using Common;
using Common.HTTPModels;
using Common.Models;
using CommunityToolkit.Mvvm.Messaging;
using Dm.filter.log;
using MegaRobo.C00225155.ControlDevices;
using MegaRobo.C00225155.ControlDevices.Scanner;
using MegaRobo.C00225155.ControlDevices.WeightDevice;
using MegaRobo.C00225155.Entities;
using MegaRobo.C00225155.Entities.Entity_DB;
using MegaRobo.C00225155.Entities.Enums;
using MegaRobo.C00225155.Entities.FromWeb;
using MegaRobo.C00225155.Entities.ToWeb;
using MegaRobo.Contract;
using MegaRobo.Contract.Servers;
using MegaRobo.ControlDevices;
using MegaRobo.ControlDevices.Models;
using MegaRobo.Entities;
using MegaRobo.Entities.ViewTT;
using MegaRobo.Logger;
using MegaRobo.PipetteTool.HamiltonConsole;
using MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.HamiltonDevices;
using NetTaste;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Nito.AsyncEx;
using SqlSugar;
using System;
using System.CodeDom;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Threading;
using static System.Net.Mime.MediaTypeNames;
using JsonSerializer = System.Text.Json.JsonSerializer;
using Pipette1ml = MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.HamiltonDevices;
using Pipette5ml = MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.Hamilton5mlDevices;

namespace MegaRobo.C00225155.AppServer.ExecuteWorks
{
    public partial class StationService_MaterialDosing : StationServiceBase
    {
        public bool TestMode = false; //测试模式

        /// <summary>
        /// 作为客户端 和BS做回复
        /// </summary>
        private IHttpClientFactory _httpClientFactory;

        protected WeightService_Ts02 preWeight;
        private LabxService labxService;

        private List<ServiceReference1.Instrument> labxPowderInstrument;
        public StationProperty StationProp = new StationProperty();

        /// <summary>
        /// 扫码枪服务
        /// </summary>
        protected ScannerService scannerService;
        protected ScannerService scannerService_Powder;

        private Pipette1ml.PipetteService pipetteService_1ml { get; set; }

        /// <summary>
        /// 从传送平台上料取载具工装 线程
        /// </summary>
        private Task TaskBoxFromTransferPlateTask { get; set; } = null;

        /// <summary>
        /// 下载具工装到传送平台 线程
        /// </summary>
        private Task DownloadBoxToTransferPlateTask { get; set; } = null;

        /// <summary>
        /// 投料线程，根据当前投料物
        /// </summary>
        private Task DoseTask_BasedOnCurrentDoseFlow { get; set; } = null;

        /// <summary>
        /// 当前正在投料的流程
        /// </summary>
        private MaterialDoseFunctionFlow _currentDoseFlow { get; set; } = null;

        /// <summary>
        /// 当前使用的原液瓶,以及原液瓶所在的FixturePosPro
        /// </summary>
        private UseLiquidBottle _currentUseSourceLiquidBottle { get; set; } = null;

        /// <summary>
        /// 当前使用粉末瓶,以及粉末瓶所在的FixturePosPro
        /// </summary>
        private SourcePowderBottleModel _currentUsePowderBottle { get; set; } = null;

        #region event
        /// <summary>
        /// 更新试剂事件
        /// </summary>
        public event EventHandler<List<DataResult_Dose>> UpdateAdditiveEvent;

        private List<DataResult_Dose> OngoingDoseDataResultList = new List<DataResult_Dose>();

        public event EventHandler<C00225155.Entities.DeviceStatus> UpdateDeviceStatusEvent;

        #endregion

        public StationService_MaterialDosing(ICoreService coreService, WorkService workService, DeviceNames plcName, string station) : base(coreService, workService, plcName, station)
        {
            StationProp = new StationProperty()
            {
                cancellationToken = new CancellationTokenSource(),
                ManualResetEvent = new ManualResetEvent(true),
                StationNum = 1,
                StationName = "投料工站",
                bStartButtonTrigger = false,
                bStopButtonTrigger = false,
                bRunFinish = false,
                bHaveReset = false,
                CTWatch = new Stopwatch(),
            };
            StationProp.ObstructFlagList = new ConcurrentDictionary<string, ObstructFlag>();
            StationProp.ObstructFlagList.TryAdd("传送平台收到准备上料信号", new ObstructFlag()
            {
                strName = "传送平台收到准备上料信号",
                flag = false
            });
            StationProp.ObstructFlagList.TryAdd("四轴机械手运行中", new ObstructFlag()
            {
                strName = "四轴机械手运行中",
                flag = false
            });
            StationProp.ObstructFlagList.TryAdd("四轴机械手正在使用传送平台", new ObstructFlag()
            {
                strName = "四轴机械手正在使用传送平台",
                flag = false
            });

            _ = Task.Run(ProcessDispatcherEx);
            _ = Task.Run(DownLoadDispatcherEx);
        }

        #region BS相关
        public async Task ChangeDeviceStatus(Entities.DeviceStatus deviceStatus)
        {
            try
            {
                StationProp.deviceStatus = deviceStatus;
                UpdateDeviceStatusEvent?.Invoke(this, deviceStatus);
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message);
            }
            finally
            {
                //todo:此处回调BS
                var status = new { status = deviceStatus.ToString() };
                var res = await SendJson(new Guid().ToString(), "status", JsonConvert.SerializeObject(status));
            }
        }

        public async Task OpenDoor(bool isChangeDeviceState = true)
        {
            //if (isChangeDeviceState) UpdateDeviceStatusEvent?.Invoke(this, Entities.DeviceStatus.CarryOn);
            if (TestMode)
            {
                await Task.Delay(5000);
            }
            else
            {
                //await this.TransferPlateformMoveTo(PlateformPos.TransferIn, new System.Threading.CancellationToken());
                await this.TransferPlateformMoveTo(PlateformPos.TransferOut, new System.Threading.CancellationToken());
            }
            await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
        }

        public async Task CloseDoor(bool isClose, bool isChangeDeviceState = true)
        {
            if (isChangeDeviceState) UpdateDeviceStatusEvent?.Invoke(this, Entities.DeviceStatus.CarryOn);
            if (isClose)
            {
                await this.TransferPlateformMoveTo(PlateformPos.TransferIn, new System.Threading.CancellationToken());
            }
            if (isChangeDeviceState)
            {
                await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
            }
        }

        public async Task StartLoad()
        {
            //await ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
            #region 开始搬运
            //await Task.Delay(10_000);
            var powderlist = new ObservableCollection<SourcePowderBottleModel>();
            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,
                });
            }

            var powderlist_125 = new ObservableCollection<SourcePowderBottleModel>();
            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,
                });
            }

            //await TransferPlateformMoveTo(PlateformPos.TransferIn, _cts.Token);
            // 1. 粉末瓶：从粉末工装 → 粉末缓存区（逐个处理）先处理粉末，放置干涉
            while (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty &&
                (f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装))
                && workService.ProjectPro.PowderHeaderCacheArea.Any(f => !f.HaveBottle))
            {
                // 检查是否存在任何有瓶子的粉末工装，如果不存在则跳出循环
                bool hasPowderHeader = workService.ProjectPro.TransferArea
                    .Where(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装))
                    .Any(f => (f is SourcePowderBottleBoxModel box16 && box16.SourcePowderBottleCollection.Any(s => s.HaveBottle)) ||
                              (f is SourcePowderBottleBoxModel_125ml box125 && box125.SourcePowderBottleCollection.Any(s => s.HaveBottle)));

                if (!hasPowderHeader) break;
                await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
                await TransferPlateformMoveTo(PlateformPos.GloveBox1, _cts.Token);  //先去2再去1
                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[i];
                        if (powderBottle == null || !powderBottle.HaveBottle) 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, _cts.Token,1);
                        await FourAxisGoToScannPos_powder(_cts.Token, powderBottle);

                        // 称重  
                        //if (!TestMode) await preWeight.Peel();
                        //var powderWeight =  await FourAxisPutPowderHeaderToPreWeight(_cts.Token);
                        //powderBottle.OriginWeight = powderBottle.RemainWeight = powderWeight;
                        // 放入缓存区
                        await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, aimPowderBottle.Pos_InDosePowderHC, powderBox.PowderBottleType, _cts.Token,1);

                        // 更新粉末缓存区（替换集合元素）
                        var newPowderBottle = File_Operator.DeepCopy(powderBottle);
                        newPowderBottle.HaveBottle = true;
                        newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC;

                        App.Current.Dispatcher.Invoke(() =>
                        {
                            powderBottle.HaveBottle = false;
                            workService.ProjectPro.PowderHeaderCacheArea[aimPowderIndex] = newPowderBottle;
                            powderBox.SourcePowderBottleCollection[i] = new SourcePowderBottleModel();
                            powderBox.SourcePowderBottleCollection[i].HaveBottle = false;
                        });
                        // 标记原粉末瓶为空
                        //var updatedBottle = powderBox.SourcePowderBottleCollection.FirstOrDefault(b => b.PosId_InBox == powderBottle.PosId_InBox);
                        //updatedBottle.HaveBottle = false;
                    }
                    App.Current.Dispatcher.Invoke(() =>
                    {
                        workService.ProjectPro.TransferArea[powderTransferIndex] = new SourcePowderBottleBoxModel()
                        {
                            BoxId_inDoseUpload = powderTransferIndex + 1,
                            IsEmpty = false,
                            IsDoseFinish = false,
                            BoxArea = BoxAreaEnum._手套箱传送平台,
                            FixtureType = BoxTypeEnum._16mL粉末瓶工装,
                            PowderBottleType = PowderBottleTypeEnum._16mL,
                            SourcePowderBottleCollection = powderlist,
                            BoxSNCode = powderBox.BoxSNCode
                        };
                    });
                }
                else if (powderBox_125 != null)
                {
                    for (int i = 0; i < powderBox_125.SourcePowderBottleCollection.Count; i++)
                    {
                        // 处理每个有瓶的粉末瓶（只处理一个，避免一次搬多个）
                        var powderBottle = powderBox_125.SourcePowderBottleCollection[i];
                        if (powderBottle == null || !powderBottle.HaveBottle) 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_125.PowderBottleType, _cts.Token,1);
                        await FourAxisGoToScannPos_powder(_cts.Token, powderBottle);

                        // 称重
                        //if (!TestMode) await preWeight.Peel();
                        //double powderWeight = await FourAxisPutPowderHeaderToPreWeight(_cts.Token);
                        //powderBottle.OriginWeight = powderBottle.RemainWeight = powderWeight;
                        // 放入缓存区
                        await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, aimPowderBottle.Pos_InDosePowderHC, powderBox_125.PowderBottleType, _cts.Token,1);

                        // 更新粉末缓存区（替换集合元素）
                        var newPowderBottle = File_Operator.DeepCopy(powderBottle);
                        newPowderBottle.HaveBottle = true;
                        newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC;
                        App.Current.Dispatcher.Invoke(() =>
                        {
                            powderBottle.HaveBottle = false;
                            workService.ProjectPro.PowderHeaderCacheArea[aimPowderIndex] = newPowderBottle;
                            powderBox.SourcePowderBottleCollection[i] = new SourcePowderBottleModel();
                            powderBox.SourcePowderBottleCollection[i].HaveBottle = false;
                        });
                        // 标记原粉末瓶为空
                        //var updatedBottle = powderBox_125.SourcePowderBottleCollection.FirstOrDefault(b => b.PosId_InBox == powderBottle.PosId_InBox);
                        //updatedBottle.HaveBottle = false;
                    }

                    App.Current.Dispatcher.Invoke(() =>
                    {
                        workService.ProjectPro.TransferArea[powderTransferIndex] = new SourcePowderBottleBoxModel_125ml()
                        {
                            BoxId_inDoseUpload = powderTransferIndex + 1,
                            IsEmpty = false,
                            IsDoseFinish = false,
                            FixtureType = BoxTypeEnum._125mL粉末瓶工装,
                            PowderBottleType = PowderBottleTypeEnum._125mL,
                            SourcePowderBottleCollection = powderlist_125,
                            BoxSNCode = powderBox_125.BoxSNCode
                        };
                    });
                }
            }

            // 2. 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, _cts.Token);
                //OrderByDescending
                var tipFixture = workService.ProjectPro.TransferArea.LastOrDefault(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.FirstOrDefault(f => !f.HaveBox && f.IsEmpty);
                int aimTipIndex = workService.ProjectPro.TipHeadArea.IndexOf(aimTipBox);

                // 执行机械手操作
                await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, tipFixture.FixtureType, (ushort)tipFixture.BoxId_inDoseUpload, _cts.Token);

                ushort aimPos = (ushort)aimTipBox.BoxId_inDosingStation;
                if (aimPos == 1)
                {
                    aimPos = 3;
                }
                else if (aimPos == 3)
                {
                    aimPos = 1;
                }
                await FourAxisPutBox((int)BoxAreaEnum._Tip托盘存放平台, tipFixture.FixtureType, aimPos, _cts.Token);

                App.Current.Dispatcher.Invoke(() =>
                {
                    // 复制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;
                        newTipBox.BoxArea = BoxAreaEnum._Tip托盘存放平台;
                        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._手套箱传送平台
                    };
                });
            }

            // 3. 原液工装：从传送平台 → 工装缓存区（任意空位置 改为 0，4号位置）
            while (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && f.FixtureType == BoxTypeEnum._40mL原液工装)
                 && workService.ProjectPro.FixtureCacheArea.Any(a => a.IsEmpty && (a.BoxId_inDosingStation == 1 || a.BoxId_inDosingStation == 5)))
            {
                await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.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, _cts.Token);
                await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, liquidFixture.FixtureType, (ushort)aimFixture.BoxId_inDosingStation, _cts.Token);

                // 复制原液工装到缓存区
                var newCacheFixture = File_Operator.DeepCopy(liquidFixture);
                newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation;
                newCacheFixture.IsDoseFinish = false;
                newCacheFixture.IsEmpty = false;
                newCacheFixture.IsUseFinsh = false;
                newCacheFixture.BoxArea = BoxAreaEnum._托盘存放平台;
                App.Current.Dispatcher.Invoke(() =>
                {
                    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._手套箱传送平台
                    };
                });
            }

            // 4. 样品工装：从传送平台 → 工装缓存区（排除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, _cts.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, _cts.Token);
                await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, sampleFixture.FixtureType, (ushort)aimFixture.BoxId_inDosingStation, _cts.Token);

                App.Current.Dispatcher.Invoke(() =>
                {
                    // 复制样品工装到缓存区（替换集合元素）
                    var newCacheFixture = File_Operator.DeepCopy(sampleFixture);
                    newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation;
                    newCacheFixture.IsDoseFinish = false;
                    newCacheFixture.IsEmpty = false;
                    newCacheFixture.IsUseFinsh = false;
                    newCacheFixture.BoxArea = BoxAreaEnum._托盘存放平台;
                    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._手套箱传送平台
                    };
                });
            }
            await TransferPlateformMoveTo(PlateformPos.GloveBox1, _cts.Token);  //最终停留在这个位置最安全
            // 无符合条件的工装可上料
            if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && f.FixtureType != BoxTypeEnum._16mL粉末瓶工装 && f.FixtureType != BoxTypeEnum._125mL粉末瓶工装))
            {
                MessageBox.Show("无可用工装或目标区域已满，无法上料！");
            }
            #endregion
            this.StationProp.deviceStatus = Entities.DeviceStatus.Idel;
            UpdateDeviceStatusEvent?.Invoke(this, Entities.DeviceStatus.Idel);
        }
        #endregion

        #region qrbian 按目标瓶配置液体

        private CancellationTokenSource _cts = new CancellationTokenSource();

        private async Task ProcessDispatcherEx()
        {
            while (!_cts.Token.IsCancellationRequested)
            {
                if (workService.stationService_Dose.StationProp.deviceStatus != Entities.DeviceStatus.Runing)
                {
                    await Task.Delay(2000);
                    continue;
                }
                var hasAnyUsableBox = workService.ProjectPro.FixtureCacheArea
                    .OfType<SampleBottleBoxModel>()
                    .Where(b => b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装)
                    .Any(box => box.SampleBottleList.Any(bottle =>
                        bottle.HaveBottle &&
                        !bottle.bDoseFinish &&
                        bottle.MaterialDoseFlowList.Count > 0));
                if (!hasAnyUsableBox)
                {
                    await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
                    continue;
                }
                var FixtureCacheAreas = workService.ProjectPro.FixtureCacheArea.Where(b => b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装).OrderBy(s => s.BoxId_inDosingStation).ToList();
                bool IsPowderInMachine = false;  //加粉头是否在梅特勒称上
                bool IsMotherLiquidInMachine = false;   //母液是否已经在母液开盖位
                for (int i = 0; i < FixtureCacheAreas.Count(); i++)
                {
                    await TransferPlateformMoveTo(PlateformPos.GloveBox1, _cts.Token);
                    if (StationProp.deviceStatus == Entities.DeviceStatus.Abort) break;
                    var FixtureCacheArea = FixtureCacheAreas.ElementAt(i);
                    SampleBottleBoxModel sampleBox = FixtureCacheArea as SampleBottleBoxModel;
                    var samplebottles = sampleBox.SampleBottleList.Where(b => b.HaveBottle && !b.bDoseFinish && b.MaterialDoseFlowList.Count() > 0).OrderBy(b => b.PosId_InBox).ToList();

                    if (samplebottles.Count() > 0)
                    {
                        if (FixtureCacheArea.BoxId_inDosingStation == 4 || FixtureCacheArea.BoxId_inDosingStation == 8)
                        {
                            //干涉，先搬到前面一位
                            await FourAxisTakeBox((int)BoxAreaEnum._托盘存放平台, FixtureCacheArea.FixtureType, (ushort)FixtureCacheArea.BoxId_inDosingStation, _cts.Token);
                            await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, FixtureCacheArea.FixtureType, (ushort)(FixtureCacheArea.BoxId_inDosingStation - 1), _cts.Token);
                            App.Current.Dispatcher.Invoke(() =>
                            {
                                FixtureCacheArea.BoxId_inDosingStation -= 1;
                                workService.ProjectPro.FixtureCacheArea[FixtureCacheArea.BoxId_inDosingStation] = new BaseBottleBox()
                                {
                                    IsEmpty = true,
                                    BoxId_inDoseDnload = FixtureCacheArea.BoxId_inDoseUpload,
                                    BoxId_inDoseUpload = FixtureCacheArea.BoxId_inDoseUpload,
                                    BoxId_inDosingStation = FixtureCacheArea.BoxId_inDosingStation + 1,
                                    IsDoseFinish = false,
                                    IsUseFinsh = false,
                                    BoxArea = BoxAreaEnum._托盘存放平台
                                };
                                workService.ProjectPro.FixtureCacheArea[FixtureCacheArea.BoxId_inDosingStation - 1] = FixtureCacheArea;
                            });
                        }
                        for (int j = 0; j < samplebottles.Count(); j++)
                        {
                            if (StationProp.deviceStatus == Entities.DeviceStatus.Abort) break;
                            var samplebottle = samplebottles.ElementAt(j);
                            //查找下一个目标瓶，用来判断母液或者粉末头是否一样，一样则不搬回去
                            SampleBottleModel samplebottleNext = null; 
                            if (j < samplebottles.Count() - 1)
                            {
                                samplebottleNext = samplebottles.ElementAt(j + 1);
                            }
                            else
                            {
                                if (i < FixtureCacheAreas.Count() - 1)
                                {
                                    var nextFixtureCacheArea = FixtureCacheAreas.ElementAt(i + 1);
                                    SampleBottleBoxModel sampleBoxNext = nextFixtureCacheArea as SampleBottleBoxModel;
                                    var samplebottlesNext = sampleBoxNext.SampleBottleList.Where(b => b.HaveBottle && !b.bDoseFinish && b.MaterialDoseFlowList.Count() > 0).OrderBy(b => b.PosId_InBox);
                                    if (samplebottlesNext != null && samplebottlesNext.Any())
                                    {
                                        samplebottleNext = samplebottlesNext.FirstOrDefault();
                                    }                                                         
                                }
                            }
                            var res = await MixForSampleBottle(samplebottle, sampleBox, IsPowderInMachine, IsMotherLiquidInMachine, samplebottleNext);
                            IsPowderInMachine = res._isPowderInMachine;
                            IsMotherLiquidInMachine = res._isMotherLiquidInMachine;
                        }
                    }

                    //搬运到转运区域，只能是1~3
                    var aimTransferFixture = GetAvaliableTransferArea(1);
                    if (aimTransferFixture != null) //&& !workService.ProjectPro.bNoUseBS
                    {
                        await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
                        await TransferFixtureFromCacheToTransfer(FixtureCacheArea, aimTransferFixture, _cts.Token); //搬运回物料区域 暂时屏蔽
                    }
                }
                WeakReferenceMessenger.Default.Send(new DesktopAlertMessage()
                {
                    Header = $"提示",
                    Content = $"工单已完成"
                });

                #region 粉末取回演示使用
                if (false && !TestMode)  
                {
                    while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                    {
                        await Task.Delay(300);
                    }
                    await SetObstructFlag("四轴机械手运行中", true);
                    await FourAxisTakePowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, PowderBottleTypeEnum._16mL, _cts.Token);
                    //Task task1 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);  //多余的
                    await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, 1, PowderBottleTypeEnum._16mL, _cts.Token);
                    //await Task.WhenAll(task1, task2);
                    await SetObstructFlag("四轴机械手运行中", false);
                    IsPowderInMachine = false;
                }
                #endregion

                await ChangeDeviceStatus(Entities.DeviceStatus.Finish);
                //if (workService.ProjectPro.bNoUseBS)
                //{   
                //    #region   //todo:测试使用，后期一定要屏蔽
                //    await ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
                //    await TransferPlateformMoveTo( PlateformPos.TransferIn,_cts.Token);
                //    await TransferPlateformMoveTo(PlateformPos.TransferOut, _cts.Token);
                //    /*
                //    try
                //    {
                //        var res = await SendJson(new Guid().ToString(), "test", "");
                //        Logger.LogInformation($"向BS发送完成接收到-{res.Item2}");
                //    }
                //    catch (Exception ex)
                //    {
                //        MessageBox.Show(ex.Message);
                //    }
                    
                //    ProjectProperty project = new ProjectProperty();
                //    bool readOk = false;
                //    project = File_Operator.Xml_Serialize("C:\\Users\\CTOS\\Desktop\\empty.pro", false, project, out readOk);
                //    if (readOk)
                //    {
                //        workService.ProjectPro = project;
                //        workService.ProjectPro.LastOpenProject = "C:\\Users\\CTOS\\Desktop\\empty.pro";
                //        workService.ProjectPro.NowOpenProjectFile = "C:\\Users\\CTOS\\Desktop\\empty.pro".Substring("C:\\Users\\CTOS\\Desktop\\empty.pro".LastIndexOf("\\") + 1).Trim();
                //        //WeakReferenceMessenger.Default.Send(new DesktopAlertMessage { Content = "打开项目文件成功！" });
                //    }
                //    */
                //    #endregion
                //    await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
                //}
                //else
                //{
                //    await ChangeDeviceStatus(Entities.DeviceStatus.Finish);
                //}
            }
        }

        //下料流程
        private async Task DownLoadDispatcherEx()
        {
            while (!_cts.Token.IsCancellationRequested)
            {
                if (workService.stationService_Dose.StationProp.deviceStatus != Entities.DeviceStatus.Finish)
                {
                    await Task.Delay(2000);
                    continue;
                }
                if (workService.ProjectPro.TransferArea.All(t => t.IsEmpty))
                {
                    await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
                    continue;
                }
                await ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
                #region 搬目标、母液、tip、 粉头
                for (int i = 1; i <= 3; i++) //1~3是样品载具
                {
                    if (workService.ProjectPro.TransferArea.Count < i) break;
                    var transferArea = workService.ProjectPro.TransferArea[i - 1];
                    if (!transferArea.IsEmpty) continue;

                    //寻找是否有样品载具待搬运
                    var sampleFixture = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._12mL样品工装 || f.FixtureType == BoxTypeEnum._5mL样品工装));
                    if (sampleFixture == null) break;
                    await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
                    await TransferFixtureFromCacheToTransfer(sampleFixture, transferArea, _cts.Token);
                }

                for (int i = 4; i <= 5; i++) //4~5是母液载具
                {
                    if (workService.ProjectPro.TransferArea.Count < i) break;
                    var transferArea = workService.ProjectPro.TransferArea[i - 1];
                    if (!transferArea.IsEmpty) continue;

                    //寻找是否有母液载具待搬运
                    var targetFixture = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._40mL原液工装));
                    if (targetFixture == null) break;
                    await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
                    await TransferFixtureFromCacheToTransfer(targetFixture, transferArea, _cts.Token);
                }

                for (int i = 6; i <= 7; i++) //6~7是tip/粉末
                {
                    if (workService.ProjectPro.TransferArea.Count < i) break;
                    var transferArea = workService.ProjectPro.TransferArea[i - 1];
                    if (!transferArea.IsEmpty && (transferArea.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || transferArea.FixtureType == BoxTypeEnum._125mL粉末瓶工装) )
                    {
                        //找粉末放进去
                        await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
                        await TransferPlateformMoveTo(PlateformPos.GloveBox1, _cts.Token);
                        if (transferArea.FixtureType == BoxTypeEnum._16mL粉末瓶工装)
                        {
                            var samplePowderBox = transferArea as SourcePowderBottleBoxModel;
                            for (int j = 0;j< samplePowderBox.SourcePowderBottleCollection.Count;j++)
                            {
                                var sourcePowderBottleHome = samplePowderBox.SourcePowderBottleCollection[j];
                                if (!sourcePowderBottleHome.HaveBottle)
                                {
                                    //搬运粉末头
                                    var powderHeader = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(p =>(p.PosId_InBox == j + 1) && p.BoxSNCode.Equals(samplePowderBox.BoxSNCode) && p.HaveBottle && p.PowderBottleType == sourcePowderBottleHome.PowderBottleType);
                                    if (powderHeader == null) break;

                                    await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderHeader.Pos_InDosePowderHC, powderHeader.PowderBottleType, _cts.Token,1);
                                    await FourAxisPutPowderHeader((int)BoxAreaEnum._手套箱传送平台, samplePowderBox.BoxId_inDoseUpload, sourcePowderBottleHome.PosId_InBox, powderHeader.PowderBottleType, _cts.Token,1);
                                    var newPowderBottle = File_Operator.DeepCopy(powderHeader);
                                    newPowderBottle.PosId_InBox = sourcePowderBottleHome.PosId_InBox;
                                    newPowderBottle.HaveBottle = true;
                                    App.Current.Dispatcher.Invoke(() =>
                                    {
                                        samplePowderBox.SourcePowderBottleCollection[j] = newPowderBottle;
                                        powderHeader.HaveBottle = false; powderHeader.SourcePowderName = ""; powderHeader.OriginWeight = powderHeader.RemainWeight = 0; 
                                    });
                                }
                            }
                        }
                        else
                        {
                            var samplePowderBox = transferArea as SourcePowderBottleBoxModel_125ml;
                            for (int j = 0; j < samplePowderBox.SourcePowderBottleCollection.Count; j++)
                            {
                                var sourcePowderBottleHome = samplePowderBox.SourcePowderBottleCollection[j];
                                if (!sourcePowderBottleHome.HaveBottle)
                                {
                                    //搬运粉末头
                                    var powderHeader = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(p => p.HaveBottle && p.PowderBottleType == sourcePowderBottleHome.PowderBottleType);
                                    if (powderHeader == null) break;

                                    await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderHeader.Pos_InDosePowderHC, powderHeader.PowderBottleType, _cts.Token, 1);
                                    await FourAxisPutPowderHeader((int)BoxAreaEnum._手套箱传送平台, samplePowderBox.BoxId_inDoseUpload, sourcePowderBottleHome.PosId_InBox, powderHeader.PowderBottleType, _cts.Token, 1);
                                    var newPowderBottle = File_Operator.DeepCopy(powderHeader);
                                    newPowderBottle.PosId_InBox = sourcePowderBottleHome.PosId_InBox;
                                    newPowderBottle.HaveBottle = true;
                                    App.Current.Dispatcher.Invoke(() =>
                                    {
                                        powderHeader.HaveBottle = false; powderHeader.SourcePowderName = ""; powderHeader.OriginWeight = powderHeader.RemainWeight = 0;
                                        samplePowderBox.SourcePowderBottleCollection[j] = newPowderBottle;
                                    });
                                }
                            }
                        }  
                    }
                    else if (transferArea.IsEmpty)
                    {
                        //找tip放进去
                        var targetFixture = workService.ProjectPro.TipHeadArea.FirstOrDefault(f => !f.IsEmpty);
                        if (targetFixture == null) continue;
                        await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
                        await TransferFixtureFromCacheToTransfer(targetFixture, transferArea, _cts.Token);
                    }
                }
                //await TransferPlateformMoveTo(PlateformPos.TransferIn, _cts.Token);
                await TransferPlateformMoveTo(PlateformPos.TransferOut, _cts.Token);
                //MessageBox.Show("通知AGV取料-需要判断是否需要空粉末治具及个数");
                //var testJson = new { test="1" };
                //var res = await SendJson((new Guid()).ToString(), "unload" , testJson.ToJson());
                #region 打包请求BS数据
                ToBsUnLoadData toBsUnLoadData = new ToBsUnLoadData()
                {
                    SampleSeqs = new List<ToBsSampleSeq>(),
                    Config = new ToBsConfig(),
                    NeedFixture = new List<ToBsFixtureInfo>()
                };
                toBsUnLoadData.Config.BoxInfo = new List<ToBsBoxInfo>();
                for (int i = 0; i < 7; i++)
                {
                    var transferArea = workService.ProjectPro.TransferArea[i];
                    if (transferArea.IsEmpty) continue;
                    ToBsBoxInfo boxInfo = new ToBsBoxInfo()
                    {
                        FixtureType = (int)transferArea.FixtureType,
                        SnCode = transferArea.BoxSNCode,
                        PosInUpload = transferArea.BoxId_inDoseUpload,
                        Detail = new List<Detail>()
                    };
                    //如果是原液或者粉末需要将数据写入boxInfo.details,如果是5、12ml瓶子则写入toBsUnLoadData.SampleSeqs
                    if (transferArea is TipBoxModel)
                    {
                        var tipBox = transferArea as TipBoxModel;
                        boxInfo.RemainCount = tipBox.TipItems.Count(t => t.IsAvailable);
                    }
                    else if (transferArea is SourceLiquidBottleBoxModel)
                    {
                        var sourceBox = transferArea as SourceLiquidBottleBoxModel;
                        var allBottles = sourceBox.SourceLiquidBottleCollection.Where(s => s.HaveBottle);
                        foreach (var bottle in allBottles)
                        {
                            var detail = new Detail()
                            {
                                Code = bottle.SourceLiquidName,
                                Pos = bottle.PosId_InBox.ToString(),
                                RemainWeight = bottle.RemainVolume
                            };
                            boxInfo.Detail.Add(detail);
                        }
                    }
                    else if (transferArea is SourcePowderBottleBoxModel)
                    {
                        var sourceBox = transferArea as SourcePowderBottleBoxModel;
                        var allBottles = sourceBox.SourcePowderBottleCollection.Where(s => s.HaveBottle);
                        foreach (var bottle in allBottles)
                        {
                            var detail = new Detail()
                            {
                                Code = bottle.SourcePowderName,
                                Pos = bottle.PosId_InBox.ToString(),
                                RemainWeight = bottle.RemainWeight
                            };
                            boxInfo.Detail.Add(detail);
                        }
                    }
                    else if (transferArea is SourcePowderBottleBoxModel_125ml)
                    {
                        var sourceBox = transferArea as SourcePowderBottleBoxModel_125ml;
                        var allBottles = sourceBox.SourcePowderBottleCollection.Where(s => s.HaveBottle);
                        foreach (var bottle in allBottles)
                        {
                            var detail = new Detail()
                            {
                                Code = bottle.SourcePowderName,
                                Pos = bottle.PosId_InBox.ToString(),
                                RemainWeight = bottle.RemainWeight
                            };
                            boxInfo.Detail.Add(detail);
                        }
                    }
                    else if (transferArea is SampleBottleBoxModel)
                    {
                        var sourceBox = transferArea as SampleBottleBoxModel;
                        var allBottles = sourceBox.SampleBottleList.Where(s => s.HaveBottle);
                        foreach (var bottle in allBottles)
                        {
                            var sampleSeq = new ToBsSampleSeq()
                            {
                                Area = "A1",
                                Carrier = transferArea.BoxId_inDoseUpload.ToString(),
                                Code = bottle.SampleContentName,
                                Pos = bottle.PosId_InBox.ToString(),
                                SampleConfig = new ToBsSampleConfig(),
                                OriginSeqIds = new List<long>() { bottle.SampleSeqId }
                            };
                            sampleSeq.SampleConfig.SnCode = transferArea.BoxSNCode;
                            sampleSeq.SampleConfig.MaterialDoseFunctionFlow = new List<ToBsMaterialDoseFunctionFlow>();
                            if (bottle.MaterialDoseFlowList != null && bottle.MaterialDoseFlowList.Count > 0)
                            {
                                foreach (var item in bottle.MaterialDoseFlowList)
                                {
                                    ToBsMaterialDoseFunctionFlow sampleFunction = new ToBsMaterialDoseFunctionFlow()
                                    {
                                        FunctionFlowType = (int)item.FunctionFlowType,
                                        TargetVolumn = item.TargetVolume,
                                        UserMaterialName = item.UseMaterialName,
                                        RealVolumn = item.ActualVolume
                                    };
                                    sampleSeq.SampleConfig.MaterialDoseFunctionFlow.Add(sampleFunction);
                                }
                                toBsUnLoadData.SampleSeqs.Add(sampleSeq);
                            }
                            sampleSeq.SampleType = bottle.SampleBottleType == SampleBottleTypeEnum._5mL ? "5mL" : "12mL";
                        }
                    }
                    toBsUnLoadData.Config.BoxInfo.Add(boxInfo);
                }

                var toBsFixtureInfo = new List<ToBsFixtureInfo>();
                var allPowderBottles = workService.ProjectPro.PowderHeaderCacheArea.Where(p => p.HaveBottle);
                List<int> remainTransferPos = new List<int>() { 6,7};
                foreach (var PowderBottle in allPowderBottles)
                {
                    if (toBsFixtureInfo.All(s => !s.SnCode.Equals(PowderBottle.BoxSNCode)))
                    {
                        var pos = remainTransferPos.FirstOrDefault();
                        if (pos != 6 && pos != 7) continue;
                        remainTransferPos.Remove(pos);
                        toBsFixtureInfo.Add(new ToBsFixtureInfo()
                        {
                            FixtureType = PowderBottle.PowderBottleType == PowderBottleTypeEnum._16mL ? (int)BoxTypeEnum._16mL粉末瓶工装 : (int)BoxTypeEnum._125mL粉末瓶工装,
                            BoxIdInDoseUpload = pos,
                            SnCode = PowderBottle.BoxSNCode
                        });
                    }
                }
                toBsUnLoadData.NeedFixture = toBsFixtureInfo;
                if (toBsUnLoadData.NeedFixture.Count > 0)
                {
                    WeakReferenceMessenger.Default.Send(new DesktopAlertMessage()
                    {
                        Header = "提示",
                        Content = $"向BS请求治具{JsonConvert.SerializeObject(toBsUnLoadData.NeedFixture)}"
                    });
                }
                #endregion
                if (!workService.ProjectPro.bNoUseBS)
                {
                    var res = await SendJson((new Guid()).ToString(), "unload", toBsUnLoadData.ToJson());
                    while (!res.Item1)
                    {
                        WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = "提示", Content = "调用BS-unload方法失败" });
                        await Task.Delay(1000);
                        res = await SendJson((new Guid()).ToString(), "unload", toBsUnLoadData.ToJson());
                    }
                }
                else
                {
                    //todo:不启用bs给出个弹窗，拿完之后清空传递仓数据,并将状态置为Finish
                }
                
                #endregion
            }
        }

        /// <summary>
        /// 返回转移区域的空位置
        /// </summary>
        /// <param name="type">1表示目标瓶在1-3找，2表示原液瓶在4-5找，3表示tip载具4表示粉末载具在6-7找</param>
        private BaseBottleBox GetAvaliableTransferArea(int type)
        {
            BaseBottleBox baseBottleBox = null;
            int startIndex = 0;
            int endIndex = 0;
            switch (type)
            {
                case 1: //目标瓶在1-3
                    startIndex = 0; endIndex = 3;
                    break;
                case 2: //原液瓶载具在4-5
                    startIndex = 3; endIndex = 5;
                    break;
                case 3: //tip
                case 4: //粉末在6-7
                    startIndex = 5; endIndex = 7;
                    break;
                default:
                    break;
            }
            for (int i = startIndex; i < endIndex; i++)
            {
                if (workService.ProjectPro.TransferArea[i].IsEmpty)
                {
                    baseBottleBox = workService.ProjectPro.TransferArea[i];
                    break;
                }
            }
            return baseBottleBox;
        }

        private async Task<bool> TransferFixtureFromPowderCacheToTransfer(SourcePowderBottleModel sourcePowderBottleModel, CancellationToken token)
        {
            var fixture = sourcePowderBottleModel.PowderBottleType == PowderBottleTypeEnum._16mL ? BoxTypeEnum._16mL粉末瓶工装 : BoxTypeEnum._125mL粉末瓶工装;
            var powderFixtures = workService.ProjectPro.TransferArea.Where(f => !f.IsEmpty && f.FixtureType == fixture);

            SourcePowderBottleBoxModel powderBox = null;
            SourcePowderBottleBoxModel_125ml powderBox_125 = null;
            BaseBottleBox powderFixture1 = null;
            foreach (var powderFixture in powderFixtures)
            {
                if (powderFixture is SourcePowderBottleBoxModel)
                {
                    powderBox = powderFixture as SourcePowderBottleBoxModel;
                    if (powderBox.SourcePowderBottleCollection.Any(s => !s.HaveBottle)) break;
                }
                else if (powderFixture is SourcePowderBottleBoxModel_125ml)
                {
                    powderBox_125 = powderFixture as SourcePowderBottleBoxModel_125ml;
                    if (powderBox_125.SourcePowderBottleCollection.Any(s => !s.HaveBottle)) break;
                }
                powderFixture1 = powderFixture;
            }
            if (powderBox.SourcePowderBottleCollection.All(s => s.HaveBottle) && powderBox_125.SourcePowderBottleCollection.All(s => s.HaveBottle)) return false;

            int powderTransferIndex = workService.ProjectPro.TransferArea.IndexOf(powderFixture1);//治具位置
            int sourceIndex = workService.ProjectPro.PowderHeaderCacheArea.IndexOf(sourcePowderBottleModel); //缓存位置位置
            if (powderBox != null)
            {
                var aimPowderBottle =  powderBox.SourcePowderBottleCollection.First(s => !s.HaveBottle);  //目标位置
                await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, sourceIndex, powderBox.PowderBottleType, token);
                await FourAxisPutPowderHeader((int)BoxAreaEnum._手套箱传送平台, powderFixture1.BoxId_inDoseUpload, aimPowderBottle.PosId_InBox, powderBox.PowderBottleType, token);
                var newPowderBottle = File_Operator.DeepCopy(sourcePowderBottleModel);
                newPowderBottle.HaveBottle = true;
                newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC;
                powderBox.SourcePowderBottleCollection[aimPowderBottle.PosId_InBox - 1] = newPowderBottle;
                workService.ProjectPro.PowderHeaderCacheArea[sourceIndex - 1] = new SourcePowderBottleModel()
                {
                    HaveBottle = false
                };
            }
            else if (powderBox_125 != null)
            {
                var aimPowderBottle = powderBox_125.SourcePowderBottleCollection.First(s => !s.HaveBottle);  //目标位置
                await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, sourceIndex, powderBox_125.PowderBottleType, token);
                await FourAxisPutPowderHeader((int)BoxAreaEnum._手套箱传送平台, powderFixture1.BoxId_inDoseUpload, aimPowderBottle.PosId_InBox, powderBox_125.PowderBottleType, token);
                // 更新粉末缓存区（替换集合元素）
                var newPowderBottle = File_Operator.DeepCopy(sourcePowderBottleModel);
                newPowderBottle.HaveBottle = true;
                newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC;
                powderBox_125.SourcePowderBottleCollection[aimPowderBottle.PosId_InBox - 1] = newPowderBottle;
                workService.ProjectPro.PowderHeaderCacheArea[sourceIndex - 1] = new SourcePowderBottleModel()
                {
                    HaveBottle = false
                };
            }
            return true;
        }

        /// <summary>
        /// 搬运治具从tip缓存位到搬运位
        /// </summary>
        /// <param name="fixture"></param>
        /// <returns></returns>
        private async Task<bool> TransferFixtureFromTipCacheToTransfer(TipBoxModel FixtureCacheArea, CancellationToken token)
        {
            var aimFixture = workService.ProjectPro.TransferArea.OrderBy(a => a.BoxId_inDosingStation).First(f => f.IsEmpty);
            if (aimFixture is null)
            {
                return false;
            }
            int aimFixtureIndex = workService.ProjectPro.TransferArea.IndexOf(aimFixture);
            await FourAxisTakeBox((int)BoxAreaEnum._Tip托盘存放平台, FixtureCacheArea.FixtureType, (ushort)FixtureCacheArea.BoxId_inDosingStation, _cts.Token);
            await FourAxisPutBox((int)BoxAreaEnum._手套箱传送平台, aimFixture.FixtureType, (ushort)aimFixture.BoxId_inDosingStation, _cts.Token);
            var newCacheFixture = File_Operator.DeepCopy(FixtureCacheArea);
            newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation;
            newCacheFixture.IsDoseFinish = true;
            newCacheFixture.IsEmpty = false;
            newCacheFixture.IsUseFinsh = true;
            try
            {
                App.Current.Dispatcher.Invoke(() =>
                {
                    workService.ProjectPro.TransferArea[aimFixtureIndex] = newCacheFixture;
                    workService.ProjectPro.TipHeadArea[FixtureCacheArea.BoxId_inDosingStation - 1] = new TipBoxModel()
                    {
                        IsEmpty = true,
                        BoxId_inDoseDnload = FixtureCacheArea.BoxId_inDoseUpload,
                        BoxId_inDoseUpload = FixtureCacheArea.BoxId_inDoseUpload,
                        IsDoseFinish = false,
                        IsUseFinsh = false,
                        BoxArea = BoxAreaEnum._手套箱传送平台
                    };
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            return true;
        }

        /// <summary>
        /// 搬运治具从缓存位到搬运位
        /// </summary>
        /// <param name="fixture"></param>
        /// <returns></returns>
        private async Task<bool> TransferFixtureFromCacheToTransfer(BaseBottleBox FixtureCacheArea, BaseBottleBox aimFixture, CancellationToken token)
        {
            //var aimFixture = workService.ProjectPro.TransferArea.OrderBy(a => a.BoxId_inDosingStation).First(f => f.IsEmpty);
            if (aimFixture is null)
            {
                return false; 
            }
            var aimFixtureIndex = workService.ProjectPro.TransferArea.IndexOf(aimFixture);
            if (FixtureCacheArea is TipBoxModel)
            {
                var fixtnew = FixtureCacheArea as TipBoxModel;
                var pos = (ushort)fixtnew.BoxId_inDosingStation;
                pos = (ushort)(3 - pos + 1);
                await FourAxisTakeBox((ushort)BoxAreaEnum._Tip托盘存放平台, fixtnew.FixtureType, (ushort)pos, _cts.Token);
                await FourAxisPutBox((int)BoxAreaEnum._手套箱传送平台, fixtnew.FixtureType, (ushort)aimFixture.BoxId_inDoseUpload, _cts.Token);
            }
            else
            {
                await FourAxisTakeBox((ushort)BoxAreaEnum._托盘存放平台, FixtureCacheArea.FixtureType, (ushort)FixtureCacheArea.BoxId_inDosingStation, _cts.Token);
                await FourAxisPutBox((int)BoxAreaEnum._手套箱传送平台, FixtureCacheArea.FixtureType, (ushort)aimFixture.BoxId_inDoseUpload, _cts.Token);
            }
            var newCacheFixture = File_Operator.DeepCopy(FixtureCacheArea);
            newCacheFixture.BoxId_inDoseUpload = aimFixture.BoxId_inDoseUpload;
            newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation;
            newCacheFixture.IsDoseFinish = true;
            newCacheFixture.IsEmpty = false;
            newCacheFixture.IsUseFinsh = true;
            try
            {
                App.Current.Dispatcher.Invoke(() =>
                {
                    workService.ProjectPro.TransferArea[aimFixtureIndex] = newCacheFixture;
                    if (FixtureCacheArea.BoxArea == BoxAreaEnum._托盘存放平台)
                    {
                        workService.ProjectPro.FixtureCacheArea[FixtureCacheArea.BoxId_inDosingStation - 1] = new BaseBottleBox()
                        {
                            IsEmpty = true,
                            BoxId_inDoseDnload = FixtureCacheArea.BoxId_inDoseUpload,
                            BoxId_inDoseUpload = FixtureCacheArea.BoxId_inDoseUpload,
                            BoxId_inDosingStation = FixtureCacheArea.BoxId_inDosingStation,
                            IsDoseFinish = false,
                            IsUseFinsh = false,
                            BoxArea = BoxAreaEnum._托盘存放平台
                        };
                    }
                    else if (FixtureCacheArea.BoxArea == BoxAreaEnum._Tip托盘存放平台)
                    {
                        var fixTipModel = FixtureCacheArea as TipBoxModel;
                        var tipBox = new TipBoxModel()
                        {
                            IsEmpty = true,
                            BoxId_inDosingStation = fixTipModel.BoxId_inDosingStation,
                            BoxArea = BoxAreaEnum._Tip托盘存放平台,
                            FixtureType = fixTipModel.FixtureType, HaveBox = false, UseIndex = 96,
                            TipItems = new ObservableCollection<TipHeadItem>()
                        };
                        for (int i = 0; i < 96; i++)
                        {
                            tipBox.TipItems.Add(new TipHeadItem() { IsAvailable = false, UseIndex = i + 1});
                        }
                        
                        workService.ProjectPro.TipHeadArea[fixTipModel.BoxId_inDosingStation - 1] = tipBox;
                    }
                    
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            return true;
        }

        public async Task TransferPlateformMoveTo(PlateformPos plateformPos, CancellationToken token)
        {
            if (token.IsCancellationRequested || TestMode) return;
            var _modbusClient_Plc1 = this.CoreService.GetServiceInstance<IModbusClientExtend>(DeviceNames.Plc1.ToString());

            var transferPlatePos = await ReadScannedValueAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_BoxPos);
            if (transferPlatePos > 0 && transferPlatePos < 5) //需要先读取当前的位置，如果当前位置是
            {
                PlateformPos currentPos = PlateformPos.TransferOut;
                //1:外面 2：里面 3：加粉头   4：载具位置
                switch (transferPlatePos)
                {
                    case 1:
                        currentPos = PlateformPos.TransferOut;
                        break;
                    case 2:
                        currentPos = PlateformPos.TransferIn;
                        break;
                    case 3:
                        currentPos = PlateformPos.GloveBox1;
                        break;
                    case 4:
                        currentPos = PlateformPos.GloveBox2;
                        break;
                    default:
                        break;
                }
                if ((plateformPos == PlateformPos.TransferOut && (currentPos == PlateformPos.GloveBox1 || currentPos == PlateformPos.GloveBox2))
                     || (currentPos == PlateformPos.TransferOut && (plateformPos == PlateformPos.GloveBox1 || plateformPos == PlateformPos.GloveBox2))
                     )
                {
                    //目标是过渡舱外面，且当前是过渡舱内部 或者当前是过渡舱外面，且目标是过渡舱内部 需要先将过渡舱到舱内
                    _modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, (ushort)PlateformPos.TransferIn);
                    await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 22, token);
                    _modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, 0);
                    await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 5, token);
                }
            }
            transferPlatePos = await ReadScannedValueAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_BoxPos);
            if (transferPlatePos > 0 && transferPlatePos < 5)
            {
                PlateformPos currentPos = PlateformPos.TransferOut;
                switch (transferPlatePos)
                {
                    case 1:
                        currentPos = PlateformPos.TransferOut;
                        break;
                    case 2:
                        currentPos = PlateformPos.TransferIn;
                        break;
                    case 3:
                        currentPos = PlateformPos.GloveBox1;
                        break;
                    case 4:
                        currentPos = PlateformPos.GloveBox2;
                        break;
                    default:
                        break;
                }
                if (currentPos != PlateformPos.GloveBox1 && currentPos != PlateformPos.GloveBox2 && plateformPos == PlateformPos.GloveBox1)
                {
                    //目标是粉末位置，当前位置如果
                    _modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, (ushort)PlateformPos.GloveBox2);
                    await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 22, token);
                    _modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, 0);
                    await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 5, token);
                }
            }
            
            _modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, (ushort)plateformPos);
            await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 22, token);
            _modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, 0);
            await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 5, token);
        }

        public async Task WriteCmdToPlc(string cmd)
        {
            ushort plcAddress = 0;
            ushort value = 1;
            bool needReset = true; //是否需要200ms复位
            bool needMaunalMode = false;  //是否需要自动
            bool needChangeMode = false;
            switch (cmd)
            {
                case "start":
                    plcAddress = PlcPoints_MaterialDose.W_PCRunStatus;
                    needChangeMode = true;
                    value = 2;
                    break;
                case "pause":
                    plcAddress = PlcPoints_MaterialDose.W_PCRunStatus;
                    value = 1; //1：停止中，2：运行中
                    break;
                case "reset":
                    plcAddress = PlcPoints_MaterialDose.W_InformationConfirm;
                    value = 1;
                    break;
                case "init":
                    plcAddress = PlcPoints_MaterialDose.W_Initial;
                    value = 1; needMaunalMode = true;
                    break;
                default:
                    break;
            }
            if (plcAddress != 0 && !TestMode)
            {
                if (needChangeMode)
                {
                    ushort plcMode = needMaunalMode ? (ushort)1 : (ushort)2; //1切成手动 2切成自动
                    await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_PCMode, plcMode);
                    await Task.Delay(200);
                    await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_PCMode, 0);
                    await Task.Delay(200);
                }

                await WriteCommandAsync_FourAxis(plcAddress, value);
                if (needReset)
                {
                    await Task.Delay(1000);
                    await WriteCommandAsync_FourAxis(plcAddress, 0);
                }
            }
        }

        private int GetBottleId(SampleBottleTypeEnum sampleType)
        {
            int res = 3;
            switch (sampleType)
            {
                case SampleBottleTypeEnum._5mL:
                    res = 3;
                    break;
                case SampleBottleTypeEnum._12mL:
                    res = 2;
                    break;
                default:
                    break;
            }
            return res;
        }

        /// <summary>
        /// 目标瓶一次加完全部的需要的液体及固体
        /// </summary>
        /// <param name="sampleBottle"></param>
        /// <param name="sampleBox"></param>
        /// <returns></returns>
        private async Task<(bool _isPowderInMachine,bool _isMotherLiquidInMachine)> MixForSampleBottle(SampleBottleModel sampleBottle, SampleBottleBoxModel sampleBox,bool IsPowderInMachine, bool IsMotherLiquidInMachine, SampleBottleModel samplebottleNext = null)
        {
            #region 搬运目标瓶到目标区域开盖
            await SetObstructFlag("四轴机械手运行中", true);
            await FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._托盘存放平台, sampleBox.BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
            if (string.IsNullOrEmpty(sampleBottle.SNCode))
            {
                await FourAxisGoToScannPos_liquid(_cts.Token, GetBottleId(sampleBottle.SampleBottleType), null, sampleBottle);
                if (TestMode) sampleBottle.SNCode = DateTime.Now.ToString();
            }
            await FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
            await SetObstructFlag("四轴机械手运行中", false);
            await OpenBottleLid(_cts.Token, null, sampleBottle);
            if (!TestMode)
            {
                while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                {
                    await Task.Delay(300);
                }
            }

            //固定加一个粉末，演示使用,0317粉末载具搬运干涉，客户想看只能固定1号位置加16ml的演示了
            if (false && !TestMode)
            {
                #region 搬运粉末加样头去梅特勒称上
                SourcePowderBottleModel powderBottle = new SourcePowderBottleModel()
                {
                    Pos_InDosePowderHC = 1,
                    PowderBottleType = PowderBottleTypeEnum._16mL
                };
                if (!IsPowderInMachine)
                {
                    if (!TestMode)
                    {
                        while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                        {
                            await Task.Delay(300);
                        }
                        await SetObstructFlag("四轴机械手运行中", true);
                        //四轴机械手取粉末加样头 放到称重模块中
                        await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderBottle.Pos_InDosePowderHC, powderBottle.PowderBottleType, _cts.Token);
                        //将粉末头放到梅特勒称重模块中
                        labxPowderInstrument = await labxService.GetInstruments("自动天平XPR105");
                        await labxService.StartWaitingForHead(labxPowderInstrument.FirstOrDefault(), "Dosing Head", "Dosing Head");
                        await FourAxisPutPowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, powderBottle.PowderBottleType, _cts.Token);
                        await SetObstructFlag("四轴机械手运行中", false);
                        await labxService.AbortWaitingForHead();
                    }
                }
                IsPowderInMachine = true;
                #endregion

                #region 目标瓶从开盖位去称重位
                while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                {
                    await Task.Delay(300);
                }
                await SetObstructFlag("四轴机械手运行中", true);
                var task1 = FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
                var task2 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);//开门
                await Task.WhenAll(task1, task2);
                await FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
                await SetObstructFlag("四轴机械手运行中", false);
                #endregion

                #region 加粉末
                //梅特勒模块关门
                await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);
                double addPowderWeight = 0;
                //大99，小125     2~200mg  +-0.297mg   200mg-5g 0.297%  
                decimal dosHeight = sampleBottle.SampleBottleType == SampleBottleTypeEnum._12mL ? 99m : 125m;
                double TargetVolume = 30;
                decimal upT = Math.Round(TargetVolume < 200 ? (decimal)(0.297 / TargetVolume * 100) : 0.297m,13);
                Logger.LogInformation($"请求加样的粉末数量-{TargetVolume},上下限为{upT}");
                addPowderWeight = await labxService.MTPowderModuleAddPowder(labxPowderInstrument.FirstOrDefault(), "Dosing2", "Dosing2", 4, dosHeight, (decimal)TargetVolume, (decimal)upT, (decimal)upT);
                //梅特勒模块开门
                //await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);
                #endregion

                #region 目标瓶放回开盖位
                while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                {
                    await Task.Delay(300);
                }
                await SetObstructFlag("四轴机械手运行中", true);
                await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);//开门
                await FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
                Task task11 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);  //关门
                Task task22 = FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
                await Task.WhenAll(task11, task22);
                await SetObstructFlag("四轴机械手运行中", false);
                #endregion
            }

            #endregion

            bool SampleHasOpened = false;
            for (int i = 0; i < sampleBottle.MaterialDoseFlowList.Count; i++)
            {
                var addSample = sampleBottle.MaterialDoseFlowList[i];
                if (addSample.FunctionFlowType!= FunctionTypeEnum.震荡摇匀 && (string.IsNullOrEmpty(addSample.UseMaterialName) || addSample.TargetVolume <= 0))
                {
                    MessageBox.Show("数据错误！");
                }
                if (addSample.FunctionFlowType == FunctionTypeEnum.加固体原料)
                {
                    #region 搬运粉末加样头去梅特勒称上
                    var powderBottle = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(ph => !string.IsNullOrEmpty(addSample.UseMaterialName) && addSample.UseMaterialName.Equals(ph.SourcePowderName));
                    if (powderBottle is null)
                    {
                        Logger.LogError($"找不到{sampleBox.BoxId_inDosingStation}-{sampleBottle.PosId_InBox}需要的{addSample.UseMaterialName}固体");
                        continue;
                    }

                    powderBottle.SourcePowderBottleState = SourceBottleStateEnum.Using;
                    if (!IsPowderInMachine)
                    {
                        if (!TestMode)
                        {
                            while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                            {
                                await Task.Delay(300);
                            }
                            await SetObstructFlag("四轴机械手运行中", true);
                            //四轴机械手取粉末加样头 放到称重模块中
                            await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderBottle.Pos_InDosePowderHC, powderBottle.PowderBottleType, _cts.Token);
                            //将粉末头放到梅特勒称重模块中
                            labxPowderInstrument = await labxService.GetInstruments("自动天平XPR105");
                            await labxService.StartWaitingForHead(labxPowderInstrument.FirstOrDefault(), "Dosing Head", "Dosing Head");
                            await FourAxisPutPowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, powderBottle.PowderBottleType, _cts.Token);
                            await SetObstructFlag("四轴机械手运行中", false);
                            await labxService.AbortWaitingForHead();
                        }
                    }
                    IsPowderInMachine = false;
                    #endregion

                    #region 目标瓶从开盖位去称重位
                    if (!TestMode && (i == 0 || sampleBottle.MaterialDoseFlowList[i - 1].FunctionFlowType != FunctionTypeEnum.加固体原料))
                    {
                        //第一个加样或者上一个加样不是固体,则取目标瓶开盖位到称重位
                        while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                        {
                            await Task.Delay(300);
                        }
                        await SetObstructFlag("四轴机械手运行中", true);
                        var task1 = FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
                        var task2 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);//开门
                        await Task.WhenAll(task1,task2);
                        await FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
                        await SetObstructFlag("四轴机械手运行中", false);
                    }
                    #endregion

                    #region 加粉末
                    if (!TestMode)
                    {
                        //梅特勒模块关门
                        await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);
                        double addPowderWeight = 0;
                        //大99，小125     2~200mg  +-0.297mg   200mg-5g 0.297%  
                        decimal dosHeight = sampleBottle.SampleBottleType == SampleBottleTypeEnum._12mL ? 96m : 122m;  //99m : 125m
                        decimal upT = Math.Round((decimal)addSample.TargetVolume < 200 ? (decimal)(0.297 / addSample.TargetVolume * 100) : 0.297m, 11);
                        Logger.LogInformation($"(decimal)addSample.TargetVolume-{addSample.TargetVolume},上下限为{upT}");
                        addPowderWeight = await labxService.MTPowderModuleAddPowder(labxPowderInstrument.FirstOrDefault(), "Dosing2", "Dosing2", 4, dosHeight, (decimal)addSample.TargetVolume, (decimal)upT, (decimal)upT);
                        powderBottle.RemainWeight -= addPowderWeight / 1000;
                        addSample.ActualVolume = addPowderWeight;
                    }
                    else
                    {
                        addSample.ActualVolume = addSample.TargetVolume;
                    }
                    Logger.LogInformation($"粉末目标：{addSample.TargetVolume}实际：{addSample.ActualVolume}");
                    addSample.IsDoseFinish = true;
                    //梅特勒模块开门
                    //await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);
                    #endregion

                    #region 粉末取回
                    if (powderBottle != null && !TestMode)
                    {
                        //判断是不是最后一个粉末，如果是的话判断下一瓶是不是用的该粉末
                        bool IsLastPowder = true;
                        for (int j = i + 1; j < sampleBottle.MaterialDoseFlowList.Count; j++)
                        {
                            if (sampleBottle.MaterialDoseFlowList[j].FunctionFlowType == FunctionTypeEnum.加固体原料)
                            {
                                IsLastPowder = false;
                                IsPowderInMachine = sampleBottle.MaterialDoseFlowList[j].UseMaterialName.Equals(powderBottle.SourcePowderName);
                                break;
                            }
                        }
                        if (IsLastPowder && samplebottleNext != null)
                        {
                            var nextMotherLiquid = samplebottleNext.MaterialDoseFlowList.FirstOrDefault(s => s.FunctionFlowType == FunctionTypeEnum.加固体原料);
                            IsPowderInMachine = nextMotherLiquid != null && nextMotherLiquid.UseMaterialName.Equals(powderBottle.SourcePowderName);
                        }

                        if (!IsPowderInMachine)
                        {
                            while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                            {
                                await Task.Delay(300);
                            }
                            await SetObstructFlag("四轴机械手运行中", true);
                            await FourAxisTakePowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, powderBottle.PowderBottleType, _cts.Token);
                            //Task task1 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);  //多余的
                            await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderBottle.Pos_InDosePowderHC, powderBottle.PowderBottleType, _cts.Token);
                            //await Task.WhenAll(task1, task2);
                            await SetObstructFlag("四轴机械手运行中", false);
                        }
                        powderBottle.SourcePowderBottleState = SourceBottleStateEnum.Idl;
                    }
                    #endregion

                    #region 目标瓶放回开盖位
                    if (!TestMode && (i == sampleBottle.MaterialDoseFlowList.Count - 1 || sampleBottle.MaterialDoseFlowList[i+1].FunctionFlowType != FunctionTypeEnum.加固体原料))
                    {
                        //最后一个加样或者下一个加样不是固体,则取回目标瓶到开盖位
                        while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                        {
                            await Task.Delay(300);
                        }
                        await SetObstructFlag("四轴机械手运行中", true);
                        await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);//开门
                        await FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
                        Task task1 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);  //关门
                        Task task2 = FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
                        await Task.WhenAll(task1, task2);
                        await SetObstructFlag("四轴机械手运行中", false);
                    }
                    #endregion 
                }
                else if (addSample.FunctionFlowType == FunctionTypeEnum.加液体原料)
                {
                    #region 搬运母液去开盖
                    // 筛选40mL原液工装并转换为SourceLiquidBottleBoxModel类型
                    var targetBoxAndBottle = workService.ProjectPro.FixtureCacheArea
                        .Where(b => b.FixtureType == BoxTypeEnum._40mL原液工装)
                        .OfType<SourceLiquidBottleBoxModel>() 
                        .SelectMany(box => box.SourceLiquidBottleCollection
                            .Select(bottle => new { Box = box, Bottle = bottle })) 
                        .FirstOrDefault(item => !string.IsNullOrEmpty(item.Bottle.SourceLiquidName) && item.Bottle.SourceLiquidName.Equals(addSample.UseMaterialName) && item.Bottle.RemainVolume > 3);
                    var sourceLiquidBox = targetBoxAndBottle?.Box;
                    var sourceBottle = targetBoxAndBottle?.Bottle;
                    if (sourceBottle is null)
                    {
                        Logger.LogError($"找不到{sampleBox.BoxId_inDosingStation}-{sampleBottle.PosId_InBox}需要的{addSample.UseMaterialName}液体");
                        continue;
                    }
                    sourceBottle.SourceLiquidBottleState = SourceBottleStateEnum.Using;
                    if (!IsMotherLiquidInMachine)
                    {
                        await SetObstructFlag("四轴机械手运行中", true);
                        await FourAxisTakeLiquidBottle(_cts.Token, (int)BoxAreaEnum._托盘存放平台, sourceLiquidBox.BoxId_inDosingStation, sourceBottle.PosId_InBox, sourceBottle);
                        if (string.IsNullOrEmpty(sourceBottle.SNCode))
                        {
                            await FourAxisGoToScannPos_liquid(_cts.Token, 1, sourceBottle, null);
                        }
                        await FourAxisPutLiquidBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sourceBottle);
                        await SetObstructFlag("四轴机械手运行中", false);
                        await OpenBottleLid(_cts.Token, sourceBottle, null);
                    }
                    else
                    {
                        //说明母液在开盖位，则开假盖子
                        await OpenCloseBottleFakeCap(_cts.Token,isOpen:true, sourceBottle,null);
                    }
                    IsMotherLiquidInMachine = false;
                    #endregion

                    #region 加液
                    await XZ_TakeTip_Absorb_Dispense_DiscardTip(_cts.Token, addSample.UseMaterialName, addSample.TargetVolume, sourceBottle, sampleBottle);
                    //更新原液瓶剩余量
                    sourceBottle.RemainVolume -= addSample.TargetVolume / 1000;
                    addSample.IsDoseFinish = true;
                    #endregion

                    #region 搬回当前原液
                    if (sourceBottle != null)
                    {
                        //判断是不是最后一个母液，如果是的话判断下一瓶是不是用的该母液
                        bool IsLastLiquid = true;
                        for (int j = i + 1; j < sampleBottle.MaterialDoseFlowList.Count; j++)
                        {
                            if (sampleBottle.MaterialDoseFlowList[j].FunctionFlowType == FunctionTypeEnum.加液体原料)
                            {
                                IsLastLiquid = false;
                                IsMotherLiquidInMachine = sampleBottle.MaterialDoseFlowList[j].UseMaterialName.Equals(sourceBottle.SourceLiquidName);
                                break;
                            }
                        }
                        if (IsLastLiquid && samplebottleNext != null) 
                        {
                            var nextMotherLiquid = samplebottleNext.MaterialDoseFlowList.FirstOrDefault(s => s.FunctionFlowType == FunctionTypeEnum.加液体原料);
                            IsMotherLiquidInMachine = nextMotherLiquid != null && nextMotherLiquid.UseMaterialName.Equals(sourceBottle.SourceLiquidName);
                            if (sourceBottle.RemainVolume < 3)
                            {
                                IsMotherLiquidInMachine = false;
                            }
                        }

                        //四轴机械手取回原液瓶 放到托盘存放平台
                        //关盖
                        if (!IsMotherLiquidInMachine)
                        {
                            await CloseBottleLid(_cts.Token, sourceBottle, null);
                            if (!TestMode)
                            {
                                while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                                {
                                    await Task.Delay(300);
                                }
                            }
                            await SetObstructFlag("四轴机械手运行中", true);
                            await FourAxisTakeLiquidBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sourceBottle);
                            await FourAxisPutLiquidBottle(_cts.Token, (int)BoxAreaEnum._托盘存放平台, sourceLiquidBox.BoxId_inDosingStation, sourceBottle.PosId_InBox, sourceBottle);
                            await SetObstructFlag("四轴机械手运行中", false);
                        }
                        else
                        {
                            //说明下一瓶还需要用，关假盖子
                            await OpenCloseBottleFakeCap(_cts.Token, isOpen: false, sourceBottle, null);
                        }
                        sourceBottle.SourceLiquidBottleState = SourceBottleStateEnum.Idl;
                    }
                    #endregion
                }
                else
                {
                    //震荡摇匀
                    await CloseBottleLid(_cts.Token, null, sampleBottle);
                    await ShakeSampleBottle(_cts.Token, sampleBottle);
                    if (i != sampleBottle.MaterialDoseFlowList.Count - 1)
                    {
                        //不是最后一次摇匀，需要开盖
                        await OpenBottleLid(_cts.Token, null, sampleBottle);
                    }
                    else
                    {
                        //最后一次摇匀，则需要标志下已经关盖了
                        SampleHasOpened = true;
                    }
                }

            }

            sampleBottle.bDoseFinish = true;
            //关盖震荡摇匀并放回
            #region 关盖震荡摇匀

            if (!SampleHasOpened)
            {
                await CloseBottleLid(_cts.Token, null, sampleBottle);
            }
            if (!TestMode)
            {
                while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                {
                    await Task.Delay(300);
                }
            }
            var isShakeMix = await dataAccessService.LoadEntityAsync<Setting>(s => s.Key.Equals("IsShakeMix") && s.Group.Equals("Setting"));
            if (isShakeMix != null && !isShakeMix.Context.Equals("0"))
            {
                await SetObstructFlag("四轴机械手运行中", true);
                await ShakeSampleBottle(_cts.Token, sampleBottle);
            }
            await FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
            await FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._托盘存放平台, sampleBox.BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
            await SetObstructFlag("四轴机械手运行中", false);
            #endregion

            return (IsPowderInMachine, IsMotherLiquidInMachine);
        }
        #endregion

        protected override void LoadServices()
        {
            base.LoadServices();//复用父类通用逻辑 + 子类扩展

            appConfigService = this.CoreService.GetServiceInstance<AppConfigService>();
            labxService = this.CoreService.GetServiceInstance<LabxService>();

            preWeight = this.CoreService.GetServiceInstance<WeightService_Ts02>(DeviceNames.PreWeight.ToString());
            scannerService = this.CoreService.GetServiceInstance<ScannerService>(DeviceNames.Scanner.ToString());
            scannerService_Powder = this.CoreService.GetServiceInstance<ScannerService>(DeviceNames.Scanner_Powder.ToString());
            pipetteService_1ml = this.CoreService.GetServiceInstance<PipetteService>(DeviceNames.Pipette_Dose_1ml.ToString());


            this._httpClientFactory = this.CoreService.GetServiceInstance<IHttpClientFactory>();
            if (this.ModbusClient != null)
            {
                //清除信号
            }
            this.workService.PrepareUploadBox += WorkService_PrepareUploadBox;
            this.workService.UpdateBoxInfo_BS += WorkService_UpdateBoxInfo_BS;
        }

        protected override void LoadDatas()
        {
            base.LoadDatas();
            InitialData();
        }

        private async Task InitialStationControlState()
        {
            if (this.StationProp.cancellationToken != null)
                this.StationProp.cancellationToken.Cancel();
            this.StationProp.cancellationToken = new CancellationTokenSource();
            this.StationProp.ManualResetEvent = new ManualResetEvent(true);
            await SetObstructFlag("传送平台收到准备上料信号", false);
            await SetObstructFlag("四轴机械手运行中", false);
            await SetObstructFlag("四轴机械手正在使用传送平台", false);
            _currentDoseFlow = null;
            _currentUseSourceLiquidBottle = null;
            _currentUsePowderBottle = null;
        }

        private async Task InitialProjectProState()
        {
            for (int i = 0; i < workService.ProjectPro.FixtureCacheArea.Count; i++)
            {
                if (workService.ProjectPro.FixtureCacheArea[i] is SampleBottleBoxModel)
                {
                    SampleBottleBoxModel samplebottleBox = workService.ProjectPro.FixtureCacheArea[i] as SampleBottleBoxModel;
                    samplebottleBox.IsDoseFinish = false;
                    samplebottleBox.IsEmpty = false;
                    samplebottleBox.IsUseFinsh = false;
                    for (int j = 0; j < samplebottleBox.SampleBottleList.Count; j++)
                    {
                        samplebottleBox.SampleBottleList[j].SNCode = string.Empty;
                        samplebottleBox.SampleBottleList[j].bDoseFinish = false;
                        samplebottleBox.SampleBottleList[j].SampleBottleLidState = SampleBottleLidStateEnum.Close;
                        samplebottleBox.SampleBottleList[j].SampleBoxState = SampleBottleStateEnum.Empty;
                        foreach (var doseflow in samplebottleBox.SampleBottleList[j].MaterialDoseFlowList)
                        {
                            doseflow.IsDoseFinish = false;
                            doseflow.ActualVolume = 0;
                        }
                    }
                }
                else if (workService.ProjectPro.FixtureCacheArea[i] is SourceLiquidBottleBoxModel)
                {
                    SourceLiquidBottleBoxModel sourceliquidbox = workService.ProjectPro.FixtureCacheArea[i] as SourceLiquidBottleBoxModel;
                    sourceliquidbox.IsDoseFinish = false;
                    for (int j = 0; j < sourceliquidbox.SourceLiquidBottleCollection.Count; j++)
                    {
                        sourceliquidbox.SourceLiquidBottleCollection[j].SNCode = string.Empty;
                        sourceliquidbox.SourceLiquidBottleCollection[j].LiquidBottleLidState = SourceBottleLidStateEnum.Close;
                        sourceliquidbox.SourceLiquidBottleCollection[j].SourceLiquidBottleState = SourceBottleStateEnum.Idl;
                        sourceliquidbox.SourceLiquidBottleCollection[j].RemainVolume = sourceliquidbox.SourceLiquidBottleCollection[j].OriginVolume;
                    }
                }
                else
                {
                    workService.ProjectPro.FixtureCacheArea[i].IsDoseFinish = false;
                    workService.ProjectPro.FixtureCacheArea[i].IsUseFinsh = false;
                    workService.ProjectPro.FixtureCacheArea[i].IsEmpty = true;
                }
            }

            for (int i = 0; i < workService.ProjectPro.PowderHeaderCacheArea.Count; i++)
            {
                workService.ProjectPro.PowderHeaderCacheArea[i].SourcePowderBottleState = SourceBottleStateEnum.Idl;
            }
        }

        public ushort GetInitStatus()
        {
            if (TestMode)
            {
                return (ushort)3;
            }
            return this.ModbusClient.Command.ReadValue<ushort>(PlcPoints_MaterialDose.R_PLCInitialStatus);
        }
        private void InitialData()
        {
            //加载传送平台  7个工装
            workService.ProjectPro.TransferArea.Clear();
            for (int i = 0; i < 7; i++)
            {
                workService.ProjectPro.TransferArea.Add(new BaseBottleBox()
                {
                    BoxId_inDoseDnload = i + 1,
                    BoxId_inDoseUpload = i + 1,
                    IsEmpty = true,
                    IsDoseFinish = false,
                    IsUseFinsh = false,
                    BoxArea = BoxAreaEnum._手套箱传送平台,
                });
            }

            workService.ProjectPro.FixtureCacheArea.Clear();
            //加载工装暂存区域 8个工装 
            for (int i = 0; i < 8; i++)
            {
                workService.ProjectPro.FixtureCacheArea.Add(new BaseBottleBox()
                {
                    //FixtureType = BoxTypeEnum._40mL原液工装,
                    BoxId_inDosingStation = i + 1,
                    BoxArea = BoxAreaEnum._托盘存放平台,
                    IsEmpty = true,
                    IsDoseFinish = false,
                    IsUseFinsh = false,
                });
            }

            workService.ProjectPro.PowderHeaderCacheArea.Clear();
            //加载粉末加样头暂存区域 10个位置
            for (int i = 0; i < 10; i++)
            {
                workService.ProjectPro.PowderHeaderCacheArea.Add(
                    new SourcePowderBottleModel()
                    {
                        HaveBottle = false,
                        Pos_InDosePowderHC = i + 1,
                        SNCode = string.Empty,
                        PowderBottleType = PowderBottleTypeEnum._125mL,
                        SourcePowderBottleState = SourceBottleStateEnum.Idl,
                        OriginWeight =0,
                    });
            }

            // 3个tip头工装
            workService.ProjectPro.TipHeadArea.Clear();
            for (int i = 0; i < 3; i++)
            {
                TipBoxModel tipBox = new TipBoxModel()
                {
                    TipType = i switch
                    {
                        0 => TipTypeEnum._1000UL,
                        1 => TipTypeEnum._300UL,
                        2 => TipTypeEnum._50UL,
                        _ => TipTypeEnum._300UL
                    },
                    HaveBox = false,
                    UseIndex = 0,
                    BoxId_inDosingStation = i + 1,
                    IsEmpty = true, // 初始无工装（可根据需求调整）
                };

                // 添加96个可用Tip头（避免序列化空引用）
                for (int j = 0; j < 8 * 12; j++)
                {
                    tipBox.TipItems.Add(new TipHeadItem { IsAvailable = false, UseIndex = j + 1 });
                }
                workService.ProjectPro.TipHeadArea.Add(tipBox);
            }

            _currentDoseFlow = null;
            _currentUseSourceLiquidBottle = null;
            _currentUsePowderBottle = null;
        }



        private bool bInitial_Z = false;
        private bool bInitial = false;
        private ushort lastInitStatus = 999;

        private async Task InitDown()
        {
            var point1 = this.ModbusClient.Command.ReadValue<ushort>(PlcPoints_MaterialDose.R_PLCInitialStatus);
            if (point1 != lastInitStatus)
            {
                lastInitStatus = point1;
                if (lastInitStatus != 999 && point1 == 3)  //不是开机第一次读取
                {
                    _ = Task.Run(async () =>
                    {
                        await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
                        WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Content = "设备已完成初始化" });
                    });
                }
            }
        }

        /// <summary>
        /// 重写，，每间隔200ms,就会进入这个函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected override async void ModbusClientBaseOnScannedEvent(object sender, EventArgs e)
        {
            base.ModbusClientBaseOnScannedEvent(sender, e);
            this.StationProp.ManualResetEvent.WaitOne(); //暂停标志
            await InitDown();

            //if (!workService.ProjectPro.bNoUseBS && (TaskBoxFromTransferPlateTask == null || TaskBoxFromTransferPlateTask.IsCanceled || TaskBoxFromTransferPlateTask.IsFaulted || TaskBoxFromTransferPlateTask.IsCompleted))
            //{
            //    TaskBoxFromTransferPlateTask = Task.Run(async () =>
            //    {
            //        await UploadBoxFromTransferPlateToHCBox(this.StationProp.cancellationToken.Token);
            //    });
            //}

            //if (!workService.ProjectPro.bNoUseBS && (DownloadBoxToTransferPlateTask == null || DownloadBoxToTransferPlateTask.IsCanceled || DownloadBoxToTransferPlateTask.IsFaulted || DownloadBoxToTransferPlateTask.IsCompleted))
            //{
            //    DownloadBoxToTransferPlateTask = Task.Run(async () =>
            //    {
            //        await DownloadFixtueBox(this.StationProp.cancellationToken.Token);
            //    });
            //}

            #region 1ml移液枪初始化
            //1ml移液枪Z轴初始化
            if (ReadScannedValueAsync_FourAxis(PlcPoints_MaterialDose.R_1mlPipetteZInit).Result == 1 && !bInitial_Z)  //1ml移液枪Z轴初始化
            {
                bInitial_Z = true;
                await GunZAxisInit_M1(DeviceNames.Pipette_Dose_1ml_1, pipetteService_1ml);
                await GunZAxisInit_M1(DeviceNames.Pipette_Dose_1ml_2, pipetteService_1ml);
                await GunZAxisInit_M1(DeviceNames.Pipette_Dose_1ml_3, pipetteService_1ml);
                await GunZAxisInit_M1(DeviceNames.Pipette_Dose_1ml_4, pipetteService_1ml);
                //Z轴初始化成功，回复给机械手
                await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_1mlPipetteZInitResult, 1);
                //等待PLC清除Z初始化信号
                await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_1mlPipetteZInit, 0, this.StationProp.cancellationToken.Token);
                await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_1mlPipetteZInitResult, 0); //清除信号
                bInitial_Z = false;
            }
            //1ml移液枪初始化
            if (ReadScannedValueAsync_FourAxis(PlcPoints_MaterialDose.R_1mlPipetteInit).Result == 1 && !bInitial)  //1ml移液枪初始化
            {
                bInitial = true;
                await GunAllInit_M1(DeviceNames.Pipette_Dose_1ml_1, pipetteService_1ml);
                await GunAllInit_M1(DeviceNames.Pipette_Dose_1ml_2, pipetteService_1ml);
                await GunAllInit_M1(DeviceNames.Pipette_Dose_1ml_3, pipetteService_1ml);
                await GunAllInit_M1(DeviceNames.Pipette_Dose_1ml_4, pipetteService_1ml);
                //Z轴初始化成功，回复给机械手
                await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_1mlPipetteInitResult, 1);
                //等待PLC清除Z初始化信号
                await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_1mlPipetteInit, 0, this.StationProp.cancellationToken.Token);
                await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_1mlPipetteInitResult, 0); //清除信号
                bInitial = false;
            }
            #endregion

            //if (!this.StationProp.bStartButtonTrigger) //没有收到启动信号或者没有按下启动按钮
            //{
            //    //若按下复位按钮，则清除所有状态
            //    if (this.StationProp.bResetButtonTrigger) //按下复位按钮
            //    {
            //        this.StationProp.bResetButtonTrigger = false;
            //        await Application.Current.Dispatcher.InvokeAsync(async () =>
            //        {
            //            await DialogManager.ShowDialogAsync(
            //                owner: Application.Current.MainWindow, // 尽量传MainWindow作为Owner，避免弹窗无归属
            //                message: "投料站复位中，正在清除状态，请稍等...\r\n这需要几秒钟时间",
            //                operation: async () =>
            //                {
            //                    await InitialStationControlState();
            //                    await InitialProjectProState();
            //                });
            //        });
            //        //await InitialStationControlState();
            //        //await InitialProjectProState();

            //    }
            //    return;
            //}
            //else //按下启动按钮
            //{
            //    if (this.StationProp.bStopButtonTrigger) //收到BS的停止信号或者按下停止按钮
            //    {
            //        this.StationProp.bStopButtonTrigger = false;
            //        this.StationProp.cancellationToken.Cancel();
            //        TimeSpan totalCt = this.StationProp.CTWatch.Elapsed;
            //        workService.ProjectPro.Dose_CT = $"{totalCt.Hours}时{totalCt.Minutes}分{totalCt.Seconds}秒";
            //        this.StationProp.CTWatch.Reset();
            //        //await magneticStirService.StirringSwitchContriol(TimeSpan.FromSeconds(3), false);
            //        //await ClearReactBottleAndRotaterState();
            //        this.StationProp.bStartButtonTrigger = false;
            //        this.StationProp.bResetButtonTrigger = false;
            //        this.StationProp.bRunFinish = false;
            //        await InitialStationControlState();
            //        return;
            //    }

            //    if (this.StationProp.bRunFinish)  //如果配置完成了，就不再执行了
            //    {
            //        this.StationProp.bRunFinish = false;
            //        //this.StationProp.cancellationToken.Cancel();
            //        TimeSpan totalCt = this.StationProp.CTWatch.Elapsed;
            //        workService.ProjectPro.Dose_CT = $"{totalCt.Hours}时{totalCt.Minutes}分{totalCt.Seconds}秒";
            //        this.StationProp.CTWatch.Reset();
            //        WeakReferenceMessenger.Default.Send(new SingleBoolMessage(true));
            //        WeakReferenceMessenger.Default.Send(new SingleBoolPeifangMessage(true));
            //        this.StationProp.bStartButtonTrigger = false;
            //        this.StationProp.bStopButtonTrigger = false;
            //        this.StationProp.bResetButtonTrigger = false;
            //        //await InitialStationControlState();
            //        return;
            //    }
            //}

            //切换投料物
            //await SwitchCurrentDoseFlow(this.StationProp.cancellationToken.Token);
        }

        /// <summary>
        /// 收到BS 告诉的准备上工装信息 ，触发事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="NotImplementedException"></exception>
        private async void WorkService_PrepareUploadBox(object sender, EventArgs e)
        {
            while (await ReadObstructFlag("四轴机械手正在使用传送平台")
                    || await ReadObstructFlag("传送平台收到准备上料信号"))
            {
                await Task.Delay(300);
            }
            await SetObstructFlag("传送平台收到准备上料信号", true);
            //传送平台到过渡舱外准备上载具
            await TransferUploadBox(this.StationProp.cancellationToken.Token);
            //回复BS准备好上料
            //_httpClientFactory.
        }

        /// <summary>
        /// BS放好载具到传送平台上,触发更新事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void WorkService_UpdateBoxInfo_BS(object sender, BaseBottleBox e)
        {
            try
            {
                //收到BS放工装完成信号
                //先让PLC将传送平台运行到设备内部
                await TransferToDeviceInner(this.StationProp.cancellationToken.Token);
                await SetObstructFlag("传送平台收到准备上料信号", false);

                //读取BS告诉CS的工装在传动平台的位置
                int pos = e.BoxId_inDoseUpload;

                BaseBottleBox fixture = workService.ProjectPro.TransferArea.FirstOrDefault(c => c.BoxId_inDoseUpload == pos);
                fixture = File_Operator.DeepCopy(e);

                //BS更新序列后
                switch (e.FixtureType)
                {
                    case BoxTypeEnum._40mL原液工装:
                        SourceLiquidBottleBoxModel sourceLiquidBottleBox = e as SourceLiquidBottleBoxModel;
                        sourceLiquidBottleBox.FixtureType = BoxTypeEnum._40mL原液工装;
                        for (int i = 0; i < sourceLiquidBottleBox.SourceLiquidBottleCollection.Count; i++)
                        {
                            sourceLiquidBottleBox.SourceLiquidBottleCollection[i].BoxSNCode = sourceLiquidBottleBox.BoxSNCode;
                            sourceLiquidBottleBox.SourceLiquidBottleCollection[i].LiquidBottleLidState = SourceBottleLidStateEnum.Close;
                            sourceLiquidBottleBox.SourceLiquidBottleCollection[i].SNCode = string.Empty;
                            sourceLiquidBottleBox.SourceLiquidBottleCollection[i].HaveBottle = true;
                        }
                        //将工装信息更新到传送平台对应位置
                        fixture = File_Operator.DeepCopy(sourceLiquidBottleBox);
                        fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
                        break;
                    case BoxTypeEnum._12mL样品工装:
                        SampleBottleBoxModel sampleBottleBox = e as SampleBottleBoxModel;
                        sampleBottleBox.SampleBottleType = SampleBottleTypeEnum._12mL;
                        for (int i = 0; i < sampleBottleBox.SampleBottleList.Count; i++)
                        {
                            sampleBottleBox.SampleBottleList[i].SampleBottleType = SampleBottleTypeEnum._12mL;
                            sampleBottleBox.SampleBottleList[i].bDoseFinish = false;
                            sampleBottleBox.SampleBottleList[i].HaveBottle = true;
                            sampleBottleBox.SampleBottleList[i].SampleBottleLidState = SampleBottleLidStateEnum.Close;
                            sampleBottleBox.SampleBottleList[i].SNCode = string.Empty;
                            sampleBottleBox.SampleBottleList[i].BoxSNCode = sampleBottleBox.BoxSNCode;
                            foreach (var doseflow in sampleBottleBox.SampleBottleList[i].MaterialDoseFlowList)
                            {
                                doseflow.IsDoseFinish = false;
                            }
                        }
                        //将工装信息更新到传送平台对应位置
                        fixture = File_Operator.DeepCopy(sampleBottleBox);
                        fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
                        break;
                    case BoxTypeEnum._5mL样品工装:
                        SampleBottleBoxModel sampleBottleBox_5 = e as SampleBottleBoxModel;
                        sampleBottleBox_5.SampleBottleType = SampleBottleTypeEnum._5mL;
                        for (int i = 0; i < sampleBottleBox_5.SampleBottleList.Count; i++)
                        {
                            sampleBottleBox_5.SampleBottleList[i].SampleBottleType = SampleBottleTypeEnum._5mL;
                            sampleBottleBox_5.SampleBottleList[i].bDoseFinish = false;
                            sampleBottleBox_5.SampleBottleList[i].HaveBottle = true;
                            sampleBottleBox_5.SampleBottleList[i].SampleBottleLidState = SampleBottleLidStateEnum.Close;
                            sampleBottleBox_5.SampleBottleList[i].SNCode = string.Empty;
                            sampleBottleBox_5.SampleBottleList[i].BoxSNCode = sampleBottleBox_5.BoxSNCode;
                            foreach (var doseflow in sampleBottleBox_5.SampleBottleList[i].MaterialDoseFlowList)
                            {
                                doseflow.IsDoseFinish = false;
                            }
                        }
                        //将工装信息更新到传送平台对应位置
                        fixture = File_Operator.DeepCopy(sampleBottleBox_5);
                        fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
                        break;
                    case BoxTypeEnum._16mL粉末瓶工装:
                        SourcePowderBottleBoxModel powderbox = e as SourcePowderBottleBoxModel;
                        powderbox.PowderBottleType = PowderBottleTypeEnum._16mL;
                        for (int i = 0; i < powderbox.SourcePowderBottleCollection.Count; i++)
                        {
                            powderbox.SourcePowderBottleCollection[i].PowderBottleType = PowderBottleTypeEnum._16mL;
                            powderbox.SourcePowderBottleCollection[i].BoxSNCode = powderbox.BoxSNCode;
                            powderbox.SourcePowderBottleCollection[i].SNCode = string.Empty;
                            powderbox.SourcePowderBottleCollection[i].HaveBottle = true;

                        }
                        //将工装信息更新到传送平台对应位置
                        fixture = File_Operator.DeepCopy(powderbox);
                        fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
                        break;
                    case BoxTypeEnum._125mL粉末瓶工装:
                        SourcePowderBottleBoxModel powderbox_125 = e as SourcePowderBottleBoxModel;
                        powderbox_125.PowderBottleType = PowderBottleTypeEnum._125mL;
                        for (int i = 0; i < powderbox_125.SourcePowderBottleCollection.Count; i++)
                        {
                            powderbox_125.SourcePowderBottleCollection[i].PowderBottleType = PowderBottleTypeEnum._125mL;
                            powderbox_125.SourcePowderBottleCollection[i].BoxSNCode = powderbox_125.BoxSNCode;
                            powderbox_125.SourcePowderBottleCollection[i].SNCode = string.Empty;
                            powderbox_125.SourcePowderBottleCollection[i].HaveBottle = true;
                        }
                        fixture = File_Operator.DeepCopy(powderbox_125);
                        fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
                        break;
                    case BoxTypeEnum._50uLTip头工装:
                        TipBoxModel tipBoxModel = e as TipBoxModel;
                        tipBoxModel.TipType = TipTypeEnum._50UL;
                        tipBoxModel.BoxId_inDosingStation = pos;
                        tipBoxModel.HaveBox = true;
                        for (var i = 0; i < tipBoxModel.TipItems.Count; i++)
                        {
                            tipBoxModel.TipItems[i].IsAvailable = true;
                        }
                        fixture = File_Operator.DeepCopy(tipBoxModel);
                        fixture.IsEmpty = false; fixture.IsUseFinsh = false;
                        break;
                    case BoxTypeEnum._300uLTip头工装:
                        TipBoxModel tipBoxModel_300 = e as TipBoxModel;
                        tipBoxModel_300.TipType = TipTypeEnum._300UL;
                        tipBoxModel_300.BoxId_inDosingStation = pos;
                        tipBoxModel_300.HaveBox = true;
                        for (var i = 0; i < tipBoxModel_300.TipItems.Count; i++)
                        {
                            tipBoxModel_300.TipItems[i].IsAvailable = true;
                        }
                        fixture = File_Operator.DeepCopy(tipBoxModel_300);
                        fixture.IsEmpty = false; fixture.IsUseFinsh = false;
                        break;
                    case BoxTypeEnum._1000uLTip头工装:
                        TipBoxModel tipBoxModel_1000 = e as TipBoxModel;
                        tipBoxModel_1000.TipType = TipTypeEnum._1000UL;
                        tipBoxModel_1000.BoxId_inDosingStation = pos;
                        tipBoxModel_1000.HaveBox = true;
                        for (var i = 0; i < tipBoxModel_1000.TipItems.Count; i++)
                        {
                            tipBoxModel_1000.TipItems[i].IsAvailable = true;
                        }
                        fixture = File_Operator.DeepCopy(tipBoxModel_1000);
                        fixture.IsEmpty = false; fixture.IsUseFinsh = false;
                        break;
                }
            }
            catch (Exception)
            {

            }
        }

        private async Task SwitchCurrentDoseFlowEx(CancellationToken token)
        {
            try
            {
                if (this.StationProp.bRunFinish) return;
                var FixtureCacheAreas = workService.ProjectPro.FixtureCacheArea.Where(b => b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装);
                if (_currentDoseFlow == null)
                {
                    //找到第一个没有配置完成的样品工装
                    BaseBottleBox fixturePosPro = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(b => !b.IsDoseFinish && !b.IsEmpty && (b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装));

                    if (fixturePosPro == null) //所有治具工装配置完成
                    {
                        this.StationProp.bRunFinish = true; //当前工单配置完成

                        await RunFinishTaskBackSourceLiquidBottleOrCurrentUsePowderBottle(_currentDoseFlow, token);
                        _currentDoseFlow = null;
                        return;
                    }
                    else
                    {
                        SampleBottleBoxModel sampleBox = fixturePosPro as SampleBottleBoxModel;
                        //找到工装中 第一个没有配置完成的样品瓶子
                        SampleBottleModel samplebottle = sampleBox.SampleBottleList.FirstOrDefault(f => f.HaveBottle && !f.bDoseFinish);
                        if (samplebottle == null)
                        {
                            sampleBox.IsDoseFinish = true;
                            _currentDoseFlow = null;
                            return;
                        }
                        else
                        {
                            if (samplebottle.MaterialDoseFlowList.Count == 0)
                            {
                                samplebottle.bDoseFinish = true;
                                _currentDoseFlow = null;
                                return;
                            }
                            MaterialDoseFunctionFlow doseflow = samplebottle.MaterialDoseFlowList.FirstOrDefault(f => !f.IsDoseFinish && f.TargetVolume > 0);
                            if (doseflow != null)
                            {
                                _currentDoseFlow = doseflow;

                                if (DoseTask_BasedOnCurrentDoseFlow == null || DoseTask_BasedOnCurrentDoseFlow.IsFaulted || DoseTask_BasedOnCurrentDoseFlow.IsCanceled || DoseTask_BasedOnCurrentDoseFlow.IsCompleted)
                                {
                                    DoseTask_BasedOnCurrentDoseFlow = Task.Run(async () =>
                                    {
                                        await OneMaterialDose(token);
                                    });
                                }
                            }
                            else
                            {
                                samplebottle.bDoseFinish = true;
                                _currentDoseFlow = null;
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                await Task.Delay(2000);
            }

        }

        /// <summary>
        /// 切换当前投料流程
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private async Task SwitchCurrentDoseFlow(CancellationToken token)
        {
            try
            {
                if (this.StationProp.bRunFinish) return;
                if (_currentDoseFlow == null)
                {
                    //找到第一个没有配置完成的样品工装
                    BaseBottleBox fixturePosPro = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(b => !b.IsDoseFinish && !b.IsEmpty && (b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装));

                    if (fixturePosPro == null) //所有治具工装配置完成
                    {
                        this.StationProp.bRunFinish = true; //当前工单配置完成

                        await RunFinishTaskBackSourceLiquidBottleOrCurrentUsePowderBottle(_currentDoseFlow, token);
                        _currentDoseFlow = null;
                        return;
                    }
                    else
                    {
                        SampleBottleBoxModel sampleBox = fixturePosPro as SampleBottleBoxModel;
                        //找到工装中 第一个没有配置完成的样品瓶子
                        SampleBottleModel samplebottle = sampleBox.SampleBottleList.FirstOrDefault(f => f.HaveBottle && !f.bDoseFinish);
                        if (samplebottle == null)
                        {
                            sampleBox.IsDoseFinish = true;
                            _currentDoseFlow = null;
                            return;
                        }
                        else
                        {
                            if (samplebottle.MaterialDoseFlowList.Count == 0)
                            {
                                samplebottle.bDoseFinish = true;
                                _currentDoseFlow = null;
                                return;
                            }
                            MaterialDoseFunctionFlow doseflow = samplebottle.MaterialDoseFlowList.FirstOrDefault(f => !f.IsDoseFinish && f.TargetVolume > 0);
                            if (doseflow != null)
                            {
                                _currentDoseFlow = doseflow;

                                if (DoseTask_BasedOnCurrentDoseFlow == null || DoseTask_BasedOnCurrentDoseFlow.IsFaulted || DoseTask_BasedOnCurrentDoseFlow.IsCanceled || DoseTask_BasedOnCurrentDoseFlow.IsCompleted)
                                {
                                    DoseTask_BasedOnCurrentDoseFlow = Task.Run(async () =>
                                    {
                                        await OneMaterialDose(token);
                                    });
                                }
                            }
                            else
                            {
                                samplebottle.bDoseFinish = true;
                                _currentDoseFlow = null;
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                await Task.Delay(2000);
            }

        }

        /// <summary>
        /// 从传动平台取工装到 治具缓存区 线程
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private async Task UploadBoxFromTransferPlateToHCBox(CancellationToken token)
        {
            while (true)
            {
                if (workService.ProjectPro.bNoUseBS) break;
                if (token.IsCancellationRequested) break;

                //从传送平台取样品工装到工装缓存区
                if (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))  //治具缓存区的 位置1和位置5 只给放原液瓶工装
                {
                    while (await ReadObstructFlag("四轴机械手运行中")
                        || await ReadObstructFlag("四轴机械手正在使用传送平台")
                        || await ReadObstructFlag("传送平台收到准备上料信号"))
                    {
                        await Task.Delay(300);
                    }
                    await SetObstructFlag("四轴机械手运行中", true);
                    await SetObstructFlag("四轴机械手正在使用传送平台", true);

                    //找到可以搬运的样品工装
                    BaseBottleBox samplefixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._5mL样品工装 || f.FixtureType == BoxTypeEnum._12mL样品工装));
                    await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, samplefixture.FixtureType, (ushort)samplefixture.BoxId_inDoseUpload, token);
                    await SetObstructFlag("四轴机械手正在使用传送平台", false);

                    //找到可以放置的工装缓存位置
                    BaseBottleBox aimfixture = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(a => a.IsEmpty && a.BoxId_inDosingStation != 1 && a.BoxId_inDosingStation != 5);
                    await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, aimfixture.FixtureType, (ushort)aimfixture.BoxId_inDosingStation, token);

                    //更新信息
                    aimfixture.IsEmpty = false;
                    aimfixture.FixtureType = samplefixture.FixtureType;
                    aimfixture = File_Operator.DeepCopy(samplefixture);
                    aimfixture.IsDoseFinish = false; aimfixture.IsUseFinsh = false;

                    samplefixture.IsEmpty = true; samplefixture = null;

                    await SetObstructFlag("四轴机械手运行中", false);
                }
                //从传送平台取原液工装到工装缓存区
                else if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && f.FixtureType == BoxTypeEnum._40mL原液工装)
                     && workService.ProjectPro.FixtureCacheArea.Any(a => a.IsEmpty))
                {
                    while (await ReadObstructFlag("四轴机械手运行中")
                        || await ReadObstructFlag("四轴机械手正在使用传送平台")
                        || await ReadObstructFlag("传送平台收到准备上料信号"))
                    {
                        await Task.Delay(300);
                    }
                    await SetObstructFlag("四轴机械手运行中", true);
                    await SetObstructFlag("四轴机械手正在使用传送平台", true);
                    //找到可以搬运的原液工装
                    BaseBottleBox liquidfixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty && f.FixtureType == BoxTypeEnum._40mL原液工装);
                    await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, liquidfixture.FixtureType, (ushort)liquidfixture.BoxId_inDoseUpload, token);
                    await SetObstructFlag("四轴机械手正在使用传送平台", false);

                    //找到可以放置的工装缓存位置
                    BaseBottleBox aimfixture = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(a => a.IsEmpty);
                    await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, aimfixture.FixtureType, (ushort)aimfixture.BoxId_inDosingStation, token);

                    //更新信息
                    aimfixture.IsEmpty = false;
                    aimfixture.FixtureType = liquidfixture.FixtureType;
                    aimfixture = File_Operator.DeepCopy(liquidfixture);
                    aimfixture.IsDoseFinish = false;
                    aimfixture.IsUseFinsh = false;

                    liquidfixture.IsEmpty = true; liquidfixture = null;

                    await SetObstructFlag("四轴机械手运行中", false);
                }
                //从传送平台的粉末工装中 一个一个取粉末瓶 ---扫码---称重---放到缓存料架上
                else if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装))
                    && workService.ProjectPro.PowderHeaderCacheArea.Any(f => !f.HaveBottle))
                {
                    BaseBottleBox powderfixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装));
                    SourcePowderBottleBoxModel powderBox = powderfixture as SourcePowderBottleBoxModel;
                    for (int i = 0; i < powderBox.SourcePowderBottleCollection.Count; i++)
                    {
                        SourcePowderBottleModel powderbottle = powderBox.SourcePowderBottleCollection[i];
                        if (powderbottle.HaveBottle)
                        {
                            while (await ReadObstructFlag("四轴机械手运行中")
                              || await ReadObstructFlag("四轴机械手正在使用传送平台")
                              || await ReadObstructFlag("传送平台收到准备上料信号"))
                            {
                                await Task.Delay(300);
                            }
                            await SetObstructFlag("四轴机械手运行中", true);
                            await SetObstructFlag("四轴机械手正在使用传送平台", true);
                            //四轴机械手从传送平台取粉末加样头
                            await FourAxisTakePowderHeader((int)BoxAreaEnum._手套箱传送平台, powderfixture.BoxId_inDoseUpload, powderbottle.PosId_InBox, powderBox.PowderBottleType, token);
                            //四轴机械手运行到扫码位置
                            await FourAxisGoToScannPos_powder(token, powderbottle);
                            await SetObstructFlag("四轴机械手正在使用传送平台", false);



                            //称重
                            await FourAxisPutPowderHeaderToPreWeight(token);
                            await preWeight.Peel();
                            double powderweight = await preWeight.ReadWeightValue();
                            powderbottle.OriginWeight = powderbottle.RemainWeight = powderweight;
                            await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_Robot_PreWeightFinish, 1);//回复预称重完成

                            //四轴机械手放粉末加样头到10个缓存区
                            SourcePowderBottleModel aimpowderbottle_inhc = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(f => !f.HaveBottle);
                            powderbottle.Pos_InDosePowderHC = aimpowderbottle_inhc.Pos_InDosePowderHC;
                            await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, aimpowderbottle_inhc.Pos_InDosePowderHC, powderBox.PowderBottleType, token);

                            //更新信息
                            aimpowderbottle_inhc = File_Operator.DeepCopy(powderbottle);
                            aimpowderbottle_inhc.HaveBottle = true;
                            powderbottle.HaveBottle = false;

                            await SetObstructFlag("四轴机械手运行中", false);
                        }
                    }
                }
                //从传送平台取Tip头工装放到投料站中
                else if (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))
                {
                    while (await ReadObstructFlag("四轴机械手运行中")
                       || await ReadObstructFlag("四轴机械手正在使用传送平台")
                       || await ReadObstructFlag("传送平台收到准备上料信号"))
                    {
                        await Task.Delay(300);
                    }
                    await SetObstructFlag("四轴机械手运行中", true);
                    await SetObstructFlag("四轴机械手正在使用传送平台", true);

                    //找到可以搬运的Tip头工装
                    BaseBottleBox tipfixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._50uLTip头工装 || f.FixtureType == BoxTypeEnum._300uLTip头工装 || f.FixtureType == BoxTypeEnum._1000uLTip头工装));
                    await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, tipfixture.FixtureType, (ushort)tipfixture.BoxId_inDoseUpload, token);
                    await SetObstructFlag("四轴机械手正在使用传送平台", false);

                    //放到Tip缓存区域 1-3
                    TipBoxModel aimtipbox = workService.ProjectPro.TipHeadArea.FirstOrDefault(f => !f.HaveBox);
                    await FourAxisPutBox((int)BoxAreaEnum._Tip托盘存放平台, tipfixture.FixtureType, (ushort)aimtipbox.BoxId_inDosingStation, token);

                    //更新信息
                    aimtipbox.HaveBox = true; aimtipbox = File_Operator.DeepCopy(tipfixture as TipBoxModel);
                    if (tipfixture.FixtureType == BoxTypeEnum._50uLTip头工装)
                    {
                        aimtipbox.TipType = TipTypeEnum._50UL;
                    }
                    else if (tipfixture.FixtureType == BoxTypeEnum._300uLTip头工装)
                    {
                        aimtipbox.TipType = TipTypeEnum._300UL;
                    }
                    else if (tipfixture.FixtureType == BoxTypeEnum._1000uLTip头工装)
                    {
                        aimtipbox.TipType = TipTypeEnum._1000UL;
                    }
                    tipfixture.IsEmpty = true; tipfixture = null;
                    await SetObstructFlag("四轴机械手运行中", false);
                }
                else
                {
                    if (!token.IsCancellationRequested)
                        await Task.Delay(2000);
                }
            }
        }

        /// <summary>
        /// 从载具工装缓存区域 下载具到传送平台
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private async Task DownloadFixtueBox(CancellationToken token)
        {
            while (true)
            {
                if (workService.ProjectPro.bNoUseBS) break;
                if (token.IsCancellationRequested) break;

            }
        }

        private async Task RunFinishTaskBackSourceLiquidBottleOrCurrentUsePowderBottle(MaterialDoseFunctionFlow flow, CancellationToken token)
        {
            #region 搬回当前原液或者粉末瓶

            if (_currentUseSourceLiquidBottle != null && _currentUseSourceLiquidBottle.liquidbottle != null)
            {
                //四轴机械手取回原液瓶 放到托盘存放平台
                //关盖
                await CloseBottleLid(token, _currentUseSourceLiquidBottle.liquidbottle, null);

                while (await ReadObstructFlag("四轴机械手运行中")
                   || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                {
                    await Task.Delay(300);
                }
                await SetObstructFlag("四轴机械手运行中", true);
                //四轴机械手取原液瓶
                await FourAxisTakeLiquidBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, _currentUseSourceLiquidBottle.liquidbottle);
                //四轴机械手放原液瓶到托盘存放平台

                await FourAxisPutLiquidBottle(token, (int)BoxAreaEnum._托盘存放平台, _currentUseSourceLiquidBottle.liquidbottleFixture.BoxId_inDosingStation, _currentUseSourceLiquidBottle.liquidbottle.PosId_InBox, _currentUseSourceLiquidBottle.liquidbottle);

                _currentUseSourceLiquidBottle = null;
                await SetObstructFlag("四轴机械手运行中", false);
            }

            if (_currentUsePowderBottle != null)
            {
                while (await ReadObstructFlag("四轴机械手运行中")
                 || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                {
                    await Task.Delay(300);
                }
                await SetObstructFlag("四轴机械手运行中", true);

                //四轴机械手取回粉末瓶 放到托盘存放平台
                await FourAxisTakePowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, _currentUsePowderBottle.PowderBottleType, token);
                await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, _currentUsePowderBottle.Pos_InDosePowderHC, _currentUsePowderBottle.PowderBottleType, token);
                _currentUsePowderBottle = null;
                await SetObstructFlag("四轴机械手运行中", false);
            }
            #endregion 
        }

        private async Task GetCurrentUseSourceLiquidBottleOrCurrentUsePowderBottle(MaterialDoseFunctionFlow flow, CancellationToken token)
        {
            #region 根据当前物料配置流程，搬运当前原液或者粉末瓶

            //根据当前物料配置流程，搬运当前原液或者粉末瓶
            if (_currentDoseFlow.FunctionFlowType == FunctionTypeEnum.加液体原料)
            {
                if (_currentUseSourceLiquidBottle != null && _currentUseSourceLiquidBottle.liquidbottle != null)
                {
                    //四轴机械手取回原液瓶 放到托盘存放平台
                    //关盖
                    await CloseBottleLid(token, _currentUseSourceLiquidBottle.liquidbottle, null);

                    while (await ReadObstructFlag("四轴机械手运行中")
                       || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                    {
                        await Task.Delay(300);
                    }
                    await SetObstructFlag("四轴机械手运行中", true);
                    //四轴机械手取原液瓶
                    await FourAxisTakeLiquidBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, _currentUseSourceLiquidBottle.liquidbottle);
                    //四轴机械手放原液瓶到托盘存放平台

                    await FourAxisPutLiquidBottle(token, (int)BoxAreaEnum._托盘存放平台, _currentUseSourceLiquidBottle.liquidbottleFixture.BoxId_inDosingStation, _currentUseSourceLiquidBottle.liquidbottle.PosId_InBox, _currentUseSourceLiquidBottle.liquidbottle);

                    _currentUseSourceLiquidBottle.liquidbottle.SourceLiquidBottleState = SourceBottleStateEnum.Idl;
                    _currentUseSourceLiquidBottle = null;
                    await SetObstructFlag("四轴机械手运行中", false);
                }

                //查找液体原料瓶
                _currentUseSourceLiquidBottle = new UseLiquidBottle()
                {
                    liquidbottleFixture = null,
                    liquidbottle = null,
                };

                _currentUseSourceLiquidBottle.liquidbottle = workService.ProjectPro.FixtureCacheArea.Where(pos => pos.FixtureType == BoxTypeEnum._40mL原液工装 && pos is SourceLiquidBottleBoxModel)
                .Select(pos => (SourceLiquidBottleBoxModel)pos)
                .SelectMany(box => box.SourceLiquidBottleCollection)
                .FirstOrDefault(bottle => bottle.HaveBottle && bottle.SourceLiquidName.Equals(_currentDoseFlow.UseMaterialName) && bottle.RemainVolume > 2 && bottle.SourceLiquidBottleState == SourceBottleStateEnum.Idl);

                if (_currentUseSourceLiquidBottle.liquidbottle == null) { } //跟BS要原液瓶

                _currentUseSourceLiquidBottle.liquidbottleFixture = workService.ProjectPro.FixtureCacheArea
                     .Where(pos => pos is SourceLiquidBottleBoxModel
                     && ((SourceLiquidBottleBoxModel)pos).SourceLiquidBottleCollection != null
                     && ((SourceLiquidBottleBoxModel)pos).SourceLiquidBottleCollection.Contains(_currentUseSourceLiquidBottle.liquidbottle)).FirstOrDefault();

                while (await ReadObstructFlag("四轴机械手运行中")
                      || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                {
                    await Task.Delay(300);
                }
                await SetObstructFlag("四轴机械手运行中", true);

                _currentUseSourceLiquidBottle.liquidbottle.SourceLiquidBottleState = SourceBottleStateEnum.Using;
                //四轴机械手取原液瓶
                await FourAxisTakeLiquidBottle(token, (int)BoxAreaEnum._托盘存放平台, _currentUseSourceLiquidBottle.liquidbottleFixture.BoxId_inDosingStation, _currentUseSourceLiquidBottle.liquidbottle.PosId_InBox, _currentUseSourceLiquidBottle.liquidbottle);

                if (_currentUseSourceLiquidBottle.liquidbottle.SNCode.Equals(string.Empty))
                {
                    await FourAxisGoToScannPos_liquid(token, 1, _currentUseSourceLiquidBottle.liquidbottle, null);
                }

                //四轴机械手放原液瓶到开关盖区域
                await FourAxisPutLiquidBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, _currentUseSourceLiquidBottle.liquidbottle);
                await SetObstructFlag("四轴机械手运行中", false);

                //开盖
                await OpenBottleLid(token, _currentUseSourceLiquidBottle.liquidbottle, null);
            }
            else if (_currentDoseFlow.FunctionFlowType == FunctionTypeEnum.加固体原料)
            {
                if (_currentUsePowderBottle != null)
                {
                    while (await ReadObstructFlag("四轴机械手运行中")
                     || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                    {
                        await Task.Delay(300);
                    }
                    await SetObstructFlag("四轴机械手运行中", true);

                    //四轴机械手取回粉末瓶 放到托盘存放平台
                    await FourAxisTakePowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, _currentUsePowderBottle.PowderBottleType, token);
                    await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, _currentUsePowderBottle.Pos_InDosePowderHC, _currentUsePowderBottle.PowderBottleType, token);
                    _currentUsePowderBottle.SourcePowderBottleState = SourceBottleStateEnum.Idl;
                    _currentUsePowderBottle = null;
                    await SetObstructFlag("四轴机械手运行中", false);
                }

                //查找可用的粉末瓶
                _currentUsePowderBottle = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(f => f.HaveBottle && f.SourcePowderName == _currentDoseFlow.UseMaterialName && f.RemainWeight > 1);

                if (_currentUsePowderBottle == null) { } //跟BS要粉末

                while (await ReadObstructFlag("四轴机械手运行中")
                    || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                {
                    await Task.Delay(300);
                }
                await SetObstructFlag("四轴机械手运行中", true);
                _currentUsePowderBottle.SourcePowderBottleState = SourceBottleStateEnum.Using;
                //四轴机械手取粉末加样头 放到称重模块中
                await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, _currentUsePowderBottle.Pos_InDosePowderHC, _currentUsePowderBottle.PowderBottleType, token);

                //将粉末头放到梅特勒称重模块中
                labxPowderInstrument = await labxService.GetInstruments("自动天平XPR105");
                await labxService.StartWaitingForHead(labxPowderInstrument.FirstOrDefault(), "Dosing Head", "Dosing Head");

                await FourAxisPutPowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, _currentUsePowderBottle.PowderBottleType, token);
                await SetObstructFlag("四轴机械手运行中", false);
                await labxService.AbortWaitingForHead();
            }
            #endregion 
        }

        /// <summary>
        /// 配置流程，由找到的_currentDoseFlow决定具体执行哪个物料的投料流程
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private async Task OneMaterialDose(CancellationToken token)
        {
            //找到所有未完成投料的样品工装
            List<BaseBottleBox> sampleBoxList = workService.ProjectPro.FixtureCacheArea.Where(f => (f.FixtureType == BoxTypeEnum._12mL样品工装 || f.FixtureType == BoxTypeEnum._5mL样品工装)
              && !f.IsDoseFinish && !f.IsEmpty).ToList();

            for (int i = 0; i < sampleBoxList.Count; i++) //对每个未配置完成的样品工装进行投料
            {
                SampleBottleBoxModel sampleBox = sampleBoxList[i] as SampleBottleBoxModel;
                for (int j = 0; j < sampleBox.SampleBottleList.Count; j++)
                {
                    if (!sampleBox.SampleBottleList[j].HaveBottle || sampleBox.SampleBottleList[j].bDoseFinish) continue;
                    SampleBottleModel sampleBottle = sampleBox.SampleBottleList[j];
                    MaterialDoseFunctionFlow doseflow = new MaterialDoseFunctionFlow();
                    doseflow = sampleBottle.MaterialDoseFlowList.FirstOrDefault(f => !f.IsDoseFinish && f.FunctionFlowType == _currentDoseFlow.FunctionFlowType && f.UseMaterialName == _currentDoseFlow.UseMaterialName && f.TargetVolume > 0);
                    if (doseflow == null) continue;
                    if (_currentDoseFlow.FunctionFlowType == FunctionTypeEnum.加液体原料)
                    {
                        if (_currentUseSourceLiquidBottle == null
                            || (_currentUseSourceLiquidBottle.liquidbottle != null &&
                            (!_currentUseSourceLiquidBottle.liquidbottle.SourceLiquidName.Equals(_currentDoseFlow.UseMaterialName) || _currentUseSourceLiquidBottle.liquidbottle.RemainVolume < 0.5))
                            )
                        {
                            await GetCurrentUseSourceLiquidBottleOrCurrentUsePowderBottle(_currentDoseFlow, token);
                        }

                        while (await ReadObstructFlag("四轴机械手运行中")
                        || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                        {
                            await Task.Delay(300);
                        }
                        await SetObstructFlag("四轴机械手运行中", true);

                        //四轴机械手取样品瓶
                        await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._托盘存放平台, sampleBoxList[i].BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);

                        //如果这个样品瓶 还没有扫过码 四轴机械手到扫码位置，暂时屏蔽
                        //if (string.IsNullOrEmpty(sampleBottle.SNCode))
                        //{
                        //    if (sampleBottle.SampleBottleType == SampleBottleTypeEnum._5mL)
                        //    {
                        //        await FourAxisGoToScannPos_liquid(token, 3, null, sampleBottle);
                        //    }
                        //    else
                        //    {
                        //        await FourAxisGoToScannPos_liquid(token, 2, null, sampleBottle);
                        //    }
                        //}

                        //四轴机械手放样品瓶到开关盖区域
                        await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
                        await SetObstructFlag("四轴机械手运行中", false);

                        //开盖
                        await OpenBottleLid(token, null, sampleBottle);


                        //执行移液枪取Tip头-吸液-分液-丢Tip头流程
                        await XZ_TakeTip_Absorb_Dispense_DiscardTip(token, doseflow.UseMaterialName, doseflow.TargetVolume, null, sampleBottle);

                        //更新原液瓶剩余量
                        _currentUseSourceLiquidBottle.liquidbottle.RemainVolume -= doseflow.TargetVolume / 1000;
                        doseflow.IsDoseFinish = true;

                        //关盖
                        await CloseBottleLid(token, null, sampleBottle);

                        while (await ReadObstructFlag("四轴机械手运行中")
                        || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                        {
                            await Task.Delay(300);
                        }
                        await SetObstructFlag("四轴机械手运行中", true);

                        //如果这个样品瓶的配置流程没有配置完成 
                        if (sampleBottle.MaterialDoseFlowList.Any(f => !f.IsDoseFinish))
                        {
                            //四轴机械手取样品瓶
                            await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
                        }
                        else  //配置完成 摇匀
                        {
                            await ShakeSampleBottle(token, sampleBottle);
                            sampleBottle.bDoseFinish = true;
                            //四轴机械手取样品瓶
                            await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
                        }

                        //四轴机械手放样品瓶到托盘存放平台
                        await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._托盘存放平台, sampleBoxList[i].BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);

                        await SetObstructFlag("四轴机械手运行中", false);
                    }
                    else if (_currentDoseFlow.FunctionFlowType == FunctionTypeEnum.加固体原料)
                    {
                        //执行加固体原料流程
                        if (_currentUsePowderBottle == null ||
                            (_currentUsePowderBottle != null && (!_currentUsePowderBottle.SourcePowderName.Equals(_currentDoseFlow.UseMaterialName) || _currentUsePowderBottle.RemainWeight < 0.1))
                            )
                        {
                            await GetCurrentUseSourceLiquidBottleOrCurrentUsePowderBottle(_currentDoseFlow, token);
                        }

                        while (await ReadObstructFlag("四轴机械手运行中")
                        || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                        {
                            await Task.Delay(300);
                        }
                        await SetObstructFlag("四轴机械手运行中", true);

                        //四轴机械手取样品瓶
                        await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._托盘存放平台, sampleBoxList[i].BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);

                        //如果这个样品瓶 还没有扫过码 四轴机械手到扫码位置  //todo:屏蔽扫码
                        //if (string.IsNullOrEmpty(sampleBottle.SNCode))
                        //{
                        //    if (sampleBottle.SampleBottleType == SampleBottleTypeEnum._5mL)
                        //    {
                        //        await FourAxisGoToScannPos_liquid(token, 3, null, sampleBottle);
                        //    }
                        //    else
                        //    {
                        //        await FourAxisGoToScannPos_liquid(token, 2, null, sampleBottle);
                        //    }
                        //}

                        //四轴机械手放样品瓶到开关盖区域
                        await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
                        await SetObstructFlag("四轴机械手运行中", false);

                        //开盖
                        await OpenBottleLid(token, null, sampleBottle);

                        while (await ReadObstructFlag("四轴机械手运行中")
                        || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                        {
                            await Task.Delay(300);
                        }
                        await SetObstructFlag("四轴机械手运行中", true);

                        await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
                        //梅特勒模块开门
                        await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);
                        await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
                        await SetObstructFlag("四轴机械手运行中", false);

                        //梅特勒模块关门
                        await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);
                        double addPowderWeight = 0;
                        //大99，小125     2~200mg  +-0.297mg   200mg-5g 0.297%  
                        addPowderWeight = await labxService.MTPowderModuleAddPowder(labxPowderInstrument.FirstOrDefault(), "Dosing2", "Dosing2", 4, 99m, (decimal)_currentDoseFlow.TargetVolume, (decimal)10, (decimal)10);
                        _currentUsePowderBottle.RemainWeight -= addPowderWeight / 1000;
                        //梅特勒模块开门
                        await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);

                        while (await ReadObstructFlag("四轴机械手运行中")
                        || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                        {
                            await Task.Delay(300);
                        }
                        await SetObstructFlag("四轴机械手运行中", true);
                        await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
                        //梅特勒模块关门
                        await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);
                        await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
                        await SetObstructFlag("四轴机械手运行中", false);
                        //关盖
                        await CloseBottleLid(token, null, sampleBottle);
                        doseflow.IsDoseFinish = true;
                        while (await ReadObstructFlag("四轴机械手运行中")
                        || await ReadObstructFlag("四轴机械手正在使用传送平台"))
                        {
                            await Task.Delay(300);
                        }
                        await SetObstructFlag("四轴机械手运行中", true);

                        //如果这个样品瓶的配置流程没有配置完成 
                        if (sampleBottle.MaterialDoseFlowList.Any(f => !f.IsDoseFinish))
                        {
                            //四轴机械手取样品瓶
                            await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
                        }
                        else  //配置完成 摇匀
                        {
                            await ShakeSampleBottle(token, sampleBottle);
                            sampleBottle.bDoseFinish = true;
                            await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
                        }

                        //四轴机械手放样品瓶到托盘存放平台
                        await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._托盘存放平台, sampleBoxList[i].BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);

                        await SetObstructFlag("四轴机械手运行中", false);
                    }
                }
            }
            //这种液体或者粉末 全部样品瓶配置完成
            _currentDoseFlow.IsDoseFinish = true; _currentDoseFlow = null;
        }

        private async Task SetObstructFlag(string name, bool value)
        {
            try
            {
                if (this.StationProp.ObstructFlagList.TryGetValue(name, out var targetFlag))
                {
                    if (targetFlag != null)
                    {
                        lock (targetFlag)
                        {
                            targetFlag.flag = value;
                        }
                    }
                }
            }
            catch (Exception)
            {
                //throw;
            }
        }

        private async Task<bool> ReadObstructFlag(string name, bool value = true, bool bAny = false)
        {
            try
            {
                if (!bAny)
                {
                    if (this.StationProp.ObstructFlagList.TryGetValue(name, out var targetFlag))
                    {
                        if (targetFlag != null)
                        {
                            lock (targetFlag)
                            {
                                return targetFlag.flag == value;
                            }
                        }
                    }
                }
                else if (bAny)
                {
                    foreach (var pair in this.StationProp.ObstructFlagList)
                    {
                        if (pair.Key.Contains(name))
                        {
                            lock (pair.Value)
                            {
                                if (pair.Value.flag == value)
                                {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                return false;
            }
            return false;
        }

        #region 和Web 通讯
        public async Task<(bool, string)> SendJson_old(string guid, string methodName, string outJson, LogLevel logLevel = LogLevel.Info)
        {
            var webApiUrl = await this.dataAccessService.LoadEntityAsync<WebApiUrl>(x => x.MethodName == methodName);
            var url = webApiUrl?.URL;
            if (string.IsNullOrEmpty(url))
            {
                return (false, "");
            }

            if (!webApiUrl.IsEnable)
            {
                return (false, "");
            }

            try
            {
                DateTime startTime = DateTime.Now;

                // *** 关键修改：将 JSON 字符串解析并重新序列化为标准格式 ***
                string finalJsonToSend;
                // 尝试将传入的 outJson (一个JSON字符串) 解析为 JsonDocument
                using (JsonDocument parsedDoc = JsonDocument.Parse(outJson))
                {
                    // 将解析后的文档重新序列化为标准、格式良好的 JSON 字符串
                    // 这一步确保了发送的是标准的 JSON 对象格式，而不是一个被当作字符串的JSON
                    finalJsonToSend = JsonSerializer.Serialize(parsedDoc.RootElement, new JsonSerializerOptions { WriteIndented = false });
                }

                HttpContent httpContent = new StringContent(finalJsonToSend, Encoding.UTF8, "application/json");
                var client = this._httpClientFactory.CreateClient(guid);
                HttpResponseMessage response = null;
                if (webApiUrl.RequestType == HttpRequestTypeEnum.Post)
                    response = await client.PostAsync(url, httpContent);
                else
                    response = await client.GetAsync(url);
                var content = await response.Content.ReadAsStringAsync();
                DateTime endTime = DateTime.Now;
                if (!methodName.Equals("error"))  //报警信息回调不写入
                {
                    Logger.LogInformation($"{url}发送{finalJsonToSend}返回{content}");
                }
                return (true, content);
            }
            catch (Exception ex)
            {
                this.Logger.LogError(logEvent: LogEvent.Error, message: $"编号:{guid} 方法:{methodName} 站: 发送失败，{ex.Message}", exception: ex);
                return (false, "");
            }
        }
        public async Task<(bool, string)> SendJson(string guid, string methodName, string outJson, LogLevel logLevel = LogLevel.Info)
        {
            var webApiUrl = await this.dataAccessService.LoadEntityAsync<WebApiUrl>(x => x.MethodName == methodName);
            var url = webApiUrl?.URL;
            if (string.IsNullOrEmpty(url))
            {
                return (false, "");
            }

            if (!webApiUrl.IsEnable)
            {
                return (false, "");
            }

            try
            {
                DateTime starTime = DateTime.Now;
                HttpContent httpContent = new StringContent(outJson,Encoding.UTF8, "application/json");
                var client = this._httpClientFactory.CreateClient(guid);
                HttpResponseMessage response = null;
                if (webApiUrl.RequestType == HttpRequestTypeEnum.Post)
                    response = await client.PostAsync(url, httpContent);
                else
                    response = await client.GetAsync(url);
                var content = await response.Content.ReadAsStringAsync();
                DateTime endTime = DateTime.Now;
                if (!methodName.Equals("error"))  //报警信息回调不写入
                {
                    Logger.LogInformation($"{url}发送{outJson}返回{content}");
                }
                return (true, content);


            }
            catch (Exception ex)
            {
                this.Logger.LogError(logEvent: LogEvent.Error, message: $"编号:{guid} 方法:{methodName} 站: 发送失败，{ex.Message}", exception: ex);
                return (false, "");
            }
        }
        #endregion

    }
}
