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; //测试模式
///
/// 作为客户端 和BS做回复
///
private IHttpClientFactory _httpClientFactory;
protected WeightService_Ts02 preWeight;
private LabxService labxService;
private List labxPowderInstrument;
public StationProperty StationProp = new StationProperty();
///
/// 扫码枪服务
///
protected ScannerService scannerService;
protected ScannerService scannerService_Powder;
private Pipette1ml.PipetteService pipetteService_1ml { get; set; }
///
/// 从传送平台上料取载具工装 线程
///
private Task TaskBoxFromTransferPlateTask { get; set; } = null;
///
/// 下载具工装到传送平台 线程
///
private Task DownloadBoxToTransferPlateTask { get; set; } = null;
///
/// 投料线程,根据当前投料物
///
private Task DoseTask_BasedOnCurrentDoseFlow { get; set; } = null;
///
/// 当前正在投料的流程
///
private MaterialDoseFunctionFlow _currentDoseFlow { get; set; } = null;
///
/// 当前使用的原液瓶,以及原液瓶所在的FixturePosPro
///
private UseLiquidBottle _currentUseSourceLiquidBottle { get; set; } = null;
///
/// 当前使用粉末瓶,以及粉末瓶所在的FixturePosPro
///
private SourcePowderBottleModel _currentUsePowderBottle { get; set; } = null;
#region event
///
/// 更新试剂事件
///
public event EventHandler> UpdateAdditiveEvent;
private List OngoingDoseDataResultList = new List();
public event EventHandler 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();
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();
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();
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()
.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(),
Config = new ToBsConfig(),
NeedFixture = new List()
};
toBsUnLoadData.Config.BoxInfo = new List();
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()
};
//如果是原液或者粉末需要将数据写入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() { bottle.SampleSeqId }
};
sampleSeq.SampleConfig.SnCode = transferArea.BoxSNCode;
sampleSeq.SampleConfig.MaterialDoseFunctionFlow = new List();
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();
var allPowderBottles = workService.ProjectPro.PowderHeaderCacheArea.Where(p => p.HaveBottle);
List remainTransferPos = new List() { 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
}
}
///
/// 返回转移区域的空位置
///
/// 1表示目标瓶在1-3找,2表示原液瓶在4-5找,3表示tip载具4表示粉末载具在6-7找
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 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;
}
///
/// 搬运治具从tip缓存位到搬运位
///
///
///
private async Task 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;
}
///
/// 搬运治具从缓存位到搬运位
///
///
///
private async Task 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()
};
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(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(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, (ushort)PlateformPos.TransferIn);
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 22, token);
_modbusClient_Plc1.Command.WriteValue(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(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, (ushort)PlateformPos.GloveBox2);
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 22, token);
_modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, 0);
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 5, token);
}
}
_modbusClient_Plc1.Command.WriteValue(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, (ushort)plateformPos);
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 22, token);
_modbusClient_Plc1.Command.WriteValue(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;
}
///
/// 目标瓶一次加完全部的需要的液体及固体
///
///
///
///
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()
.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(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();
labxService = this.CoreService.GetServiceInstance();
preWeight = this.CoreService.GetServiceInstance(DeviceNames.PreWeight.ToString());
scannerService = this.CoreService.GetServiceInstance(DeviceNames.Scanner.ToString());
scannerService_Powder = this.CoreService.GetServiceInstance(DeviceNames.Scanner_Powder.ToString());
pipetteService_1ml = this.CoreService.GetServiceInstance(DeviceNames.Pipette_Dose_1ml.ToString());
this._httpClientFactory = this.CoreService.GetServiceInstance();
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(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(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 = "设备已完成初始化" });
});
}
}
}
///
/// 重写,,每间隔200ms,就会进入这个函数
///
///
///
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);
}
///
/// 收到BS 告诉的准备上工装信息 ,触发事件
///
///
///
///
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.
}
///
/// BS放好载具到传送平台上,触发更新事件
///
///
///
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);
}
}
///
/// 切换当前投料流程
///
///
///
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);
}
}
///
/// 从传动平台取工装到 治具缓存区 线程
///
///
///
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);
}
}
}
///
/// 从载具工装缓存区域 下载具到传送平台
///
///
///
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
}
///
/// 配置流程,由找到的_currentDoseFlow决定具体执行哪个物料的投料流程
///
///
///
private async Task OneMaterialDose(CancellationToken token)
{
//找到所有未完成投料的样品工装
List 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 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(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(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
}
}