C00225155-02/C00225155/MegaRobo.C00225155/MegaRobo.C00225155.AppServer/ExecuteWorks/StationService_MaterialDosi...

3052 lines
167 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Common;
using Common.HTTPModels;
using Common.Models;
using CommunityToolkit.Mvvm.Messaging;
using Dm.filter.log;
using MegaRobo.C00225155.ControlDevices;
using MegaRobo.C00225155.ControlDevices.Scanner;
using MegaRobo.C00225155.ControlDevices.WeightDevice;
using MegaRobo.C00225155.Entities;
using MegaRobo.C00225155.Entities.Entity_DB;
using MegaRobo.C00225155.Entities.Enums;
using MegaRobo.C00225155.Entities.FromWeb;
using MegaRobo.C00225155.Entities.ToWeb;
using MegaRobo.Contract;
using MegaRobo.Contract.Servers;
using MegaRobo.ControlDevices;
using MegaRobo.ControlDevices.Models;
using MegaRobo.Entities;
using MegaRobo.Entities.ViewTT;
using MegaRobo.Logger;
using MegaRobo.PipetteTool.HamiltonConsole;
using MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.HamiltonDevices;
using NetTaste;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Nito.AsyncEx;
using SqlSugar;
using System;
using System.CodeDom;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Threading;
using static System.Net.Mime.MediaTypeNames;
using JsonSerializer = System.Text.Json.JsonSerializer;
using Pipette1ml = MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.HamiltonDevices;
using Pipette5ml = MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.Hamilton5mlDevices;
namespace MegaRobo.C00225155.AppServer.ExecuteWorks
{
public partial class StationService_MaterialDosing : StationServiceBase
{
public bool TestMode = false; //测试模式
/// <summary>
/// 作为客户端 和BS做回复
/// </summary>
private IHttpClientFactory _httpClientFactory;
protected WeightService_Ts02 preWeight;
private LabxService labxService;
private List<ServiceReference1.Instrument> labxPowderInstrument;
public StationProperty StationProp = new StationProperty();
/// <summary>
/// 扫码枪服务
/// </summary>
protected ScannerService scannerService;
protected ScannerService scannerService_Powder;
private Pipette1ml.PipetteService pipetteService_1ml { get; set; }
/// <summary>
/// 从传送平台上料取载具工装 线程
/// </summary>
private Task TaskBoxFromTransferPlateTask { get; set; } = null;
/// <summary>
/// 下载具工装到传送平台 线程
/// </summary>
private Task DownloadBoxToTransferPlateTask { get; set; } = null;
/// <summary>
/// 投料线程,根据当前投料物
/// </summary>
private Task DoseTask_BasedOnCurrentDoseFlow { get; set; } = null;
/// <summary>
/// 当前正在投料的流程
/// </summary>
private MaterialDoseFunctionFlow _currentDoseFlow { get; set; } = null;
/// <summary>
/// 当前使用的原液瓶,以及原液瓶所在的FixturePosPro
/// </summary>
private UseLiquidBottle _currentUseSourceLiquidBottle { get; set; } = null;
/// <summary>
/// 当前使用粉末瓶,以及粉末瓶所在的FixturePosPro
/// </summary>
private SourcePowderBottleModel _currentUsePowderBottle { get; set; } = null;
#region event
/// <summary>
/// 更新试剂事件
/// </summary>
public event EventHandler<List<DataResult_Dose>> UpdateAdditiveEvent;
private List<DataResult_Dose> OngoingDoseDataResultList = new List<DataResult_Dose>();
public event EventHandler<C00225155.Entities.DeviceStatus> UpdateDeviceStatusEvent;
#endregion
public StationService_MaterialDosing(ICoreService coreService, WorkService workService, DeviceNames plcName, string station) : base(coreService, workService, plcName, station)
{
StationProp = new StationProperty()
{
cancellationToken = new CancellationTokenSource(),
ManualResetEvent = new ManualResetEvent(true),
StationNum = 1,
StationName = "投料工站",
bStartButtonTrigger = false,
bStopButtonTrigger = false,
bRunFinish = false,
bHaveReset = false,
CTWatch = new Stopwatch(),
};
StationProp.ObstructFlagList = new ConcurrentDictionary<string, ObstructFlag>();
StationProp.ObstructFlagList.TryAdd("传送平台收到准备上料信号", new ObstructFlag()
{
strName = "传送平台收到准备上料信号",
flag = false
});
StationProp.ObstructFlagList.TryAdd("四轴机械手运行中", new ObstructFlag()
{
strName = "四轴机械手运行中",
flag = false
});
StationProp.ObstructFlagList.TryAdd("四轴机械手正在使用传送平台", new ObstructFlag()
{
strName = "四轴机械手正在使用传送平台",
flag = false
});
_ = Task.Run(ProcessDispatcherEx);
_ = Task.Run(DownLoadDispatcherEx);
}
#region BS相关
public async Task ChangeDeviceStatus(Entities.DeviceStatus deviceStatus)
{
try
{
StationProp.deviceStatus = deviceStatus;
UpdateDeviceStatusEvent?.Invoke(this, deviceStatus);
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
}
finally
{
//todo:此处回调BS
var status = new { status = deviceStatus.ToString() };
var res = await SendJson(new Guid().ToString(), "status", JsonConvert.SerializeObject(status));
}
}
public async Task OpenDoor(bool isChangeDeviceState = true)
{
//if (isChangeDeviceState) UpdateDeviceStatusEvent?.Invoke(this, Entities.DeviceStatus.CarryOn);
if (TestMode)
{
await Task.Delay(5000);
}
else
{
//await this.TransferPlateformMoveTo(PlateformPos.TransferIn, new System.Threading.CancellationToken());
await this.TransferPlateformMoveTo(PlateformPos.TransferOut, new System.Threading.CancellationToken());
}
await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
}
public async Task CloseDoor(bool isClose, bool isChangeDeviceState = true)
{
if (isChangeDeviceState) UpdateDeviceStatusEvent?.Invoke(this, Entities.DeviceStatus.CarryOn);
if (isClose)
{
await this.TransferPlateformMoveTo(PlateformPos.TransferIn, new System.Threading.CancellationToken());
}
if (isChangeDeviceState)
{
await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
}
}
public async Task StartLoad()
{
//await ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
#region
//await Task.Delay(10_000);
var powderlist = new ObservableCollection<SourcePowderBottleModel>();
for (int i = 0; i < 4; i++)
{
powderlist.Add(new SourcePowderBottleModel()
{
PosId_InBox = i + 1,
HaveBottle = false,
RemainWeight = 0,
SNCode = string.Empty,
PowderBottleType = PowderBottleTypeEnum._16mL,
SourcePowderBottleState = SourceBottleStateEnum.Idl,
});
}
var powderlist_125 = new ObservableCollection<SourcePowderBottleModel>();
for (int i = 0; i < 2; i++)
{
powderlist_125.Add(new SourcePowderBottleModel()
{
PosId_InBox = i + 1,
HaveBottle = false,
RemainWeight = 0,
SNCode = string.Empty,
PowderBottleType = PowderBottleTypeEnum._125mL,
SourcePowderBottleState = SourceBottleStateEnum.Idl,
});
}
//await TransferPlateformMoveTo(PlateformPos.TransferIn, _cts.Token);
// 1. 粉末瓶:从粉末工装 → 粉末缓存区(逐个处理)先处理粉末,放置干涉
while (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty &&
(f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装))
&& workService.ProjectPro.PowderHeaderCacheArea.Any(f => !f.HaveBottle))
{
// 检查是否存在任何有瓶子的粉末工装,如果不存在则跳出循环
bool hasPowderHeader = workService.ProjectPro.TransferArea
.Where(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装))
.Any(f => (f is SourcePowderBottleBoxModel box16 && box16.SourcePowderBottleCollection.Any(s => s.HaveBottle)) ||
(f is SourcePowderBottleBoxModel_125ml box125 && box125.SourcePowderBottleCollection.Any(s => s.HaveBottle)));
if (!hasPowderHeader) break;
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
await TransferPlateformMoveTo(PlateformPos.GloveBox1, _cts.Token); //先去2再去1
var powderFixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty &&
(f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装));
SourcePowderBottleBoxModel powderBox = null;
SourcePowderBottleBoxModel_125ml powderBox_125 = null;
if (powderFixture is SourcePowderBottleBoxModel)
{
powderBox = powderFixture as SourcePowderBottleBoxModel;
}
else if (powderFixture is SourcePowderBottleBoxModel_125ml)
{
powderBox_125 = powderFixture as SourcePowderBottleBoxModel_125ml;
}
if (powderBox == null && powderBox_125 == null) return;
int powderTransferIndex = workService.ProjectPro.TransferArea.IndexOf(powderFixture);
if (powderBox != null)
{
for (int i = 0; i < powderBox.SourcePowderBottleCollection.Count; i++)
{
// 处理每个有瓶的粉末瓶(只处理一个,避免一次搬多个)
var powderBottle = powderBox.SourcePowderBottleCollection[i];
if (powderBottle == null || !powderBottle.HaveBottle) continue;
// 找到粉末缓存区的空位置
var aimPowderBottle = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(f => !f.HaveBottle);
if (aimPowderBottle == null)
{
MessageBox.Show("粉末缓存区已满,无法继续上料!");
return;
}
int aimPowderIndex = workService.ProjectPro.PowderHeaderCacheArea.IndexOf(aimPowderBottle);
// 执行机械手操作
await FourAxisTakePowderHeader((int)BoxAreaEnum._手套箱传送平台, powderFixture.BoxId_inDoseUpload, powderBottle.PosId_InBox, powderBox.PowderBottleType, _cts.Token,1);
await FourAxisGoToScannPos_powder(_cts.Token, powderBottle);
// 称重
//if (!TestMode) await preWeight.Peel();
//var powderWeight = await FourAxisPutPowderHeaderToPreWeight(_cts.Token);
//powderBottle.OriginWeight = powderBottle.RemainWeight = powderWeight;
// 放入缓存区
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, aimPowderBottle.Pos_InDosePowderHC, powderBox.PowderBottleType, _cts.Token,1);
// 更新粉末缓存区(替换集合元素)
var newPowderBottle = File_Operator.DeepCopy(powderBottle);
newPowderBottle.HaveBottle = true;
newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC;
App.Current.Dispatcher.Invoke(() =>
{
powderBottle.HaveBottle = false;
workService.ProjectPro.PowderHeaderCacheArea[aimPowderIndex] = newPowderBottle;
powderBox.SourcePowderBottleCollection[i] = new SourcePowderBottleModel();
powderBox.SourcePowderBottleCollection[i].HaveBottle = false;
});
// 标记原粉末瓶为空
//var updatedBottle = powderBox.SourcePowderBottleCollection.FirstOrDefault(b => b.PosId_InBox == powderBottle.PosId_InBox);
//updatedBottle.HaveBottle = false;
}
App.Current.Dispatcher.Invoke(() =>
{
workService.ProjectPro.TransferArea[powderTransferIndex] = new SourcePowderBottleBoxModel()
{
BoxId_inDoseUpload = powderTransferIndex + 1,
IsEmpty = false,
IsDoseFinish = false,
BoxArea = BoxAreaEnum._手套箱传送平台,
FixtureType = BoxTypeEnum._16mL粉末瓶工装,
PowderBottleType = PowderBottleTypeEnum._16mL,
SourcePowderBottleCollection = powderlist,
BoxSNCode = powderBox.BoxSNCode
};
});
}
else if (powderBox_125 != null)
{
for (int i = 0; i < powderBox_125.SourcePowderBottleCollection.Count; i++)
{
// 处理每个有瓶的粉末瓶(只处理一个,避免一次搬多个)
var powderBottle = powderBox_125.SourcePowderBottleCollection[i];
if (powderBottle == null || !powderBottle.HaveBottle) continue;
// 找到粉末缓存区的空位置
var aimPowderBottle = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(f => !f.HaveBottle);
if (aimPowderBottle == null)
{
MessageBox.Show("粉末缓存区已满,无法继续上料!");
return;
}
int aimPowderIndex = workService.ProjectPro.PowderHeaderCacheArea.IndexOf(aimPowderBottle);
// 执行机械手操作
await FourAxisTakePowderHeader((int)BoxAreaEnum._手套箱传送平台, powderFixture.BoxId_inDoseUpload, powderBottle.PosId_InBox, powderBox_125.PowderBottleType, _cts.Token,1);
await FourAxisGoToScannPos_powder(_cts.Token, powderBottle);
// 称重
//if (!TestMode) await preWeight.Peel();
//double powderWeight = await FourAxisPutPowderHeaderToPreWeight(_cts.Token);
//powderBottle.OriginWeight = powderBottle.RemainWeight = powderWeight;
// 放入缓存区
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, aimPowderBottle.Pos_InDosePowderHC, powderBox_125.PowderBottleType, _cts.Token,1);
// 更新粉末缓存区(替换集合元素)
var newPowderBottle = File_Operator.DeepCopy(powderBottle);
newPowderBottle.HaveBottle = true;
newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC;
App.Current.Dispatcher.Invoke(() =>
{
powderBottle.HaveBottle = false;
workService.ProjectPro.PowderHeaderCacheArea[aimPowderIndex] = newPowderBottle;
powderBox.SourcePowderBottleCollection[i] = new SourcePowderBottleModel();
powderBox.SourcePowderBottleCollection[i].HaveBottle = false;
});
// 标记原粉末瓶为空
//var updatedBottle = powderBox_125.SourcePowderBottleCollection.FirstOrDefault(b => b.PosId_InBox == powderBottle.PosId_InBox);
//updatedBottle.HaveBottle = false;
}
App.Current.Dispatcher.Invoke(() =>
{
workService.ProjectPro.TransferArea[powderTransferIndex] = new SourcePowderBottleBoxModel_125ml()
{
BoxId_inDoseUpload = powderTransferIndex + 1,
IsEmpty = false,
IsDoseFinish = false,
FixtureType = BoxTypeEnum._125mL粉末瓶工装,
PowderBottleType = PowderBottleTypeEnum._125mL,
SourcePowderBottleCollection = powderlist_125,
BoxSNCode = powderBox_125.BoxSNCode
};
});
}
}
// 2. Tip头工装从传送平台 → Tip头区域
while (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty &&
(f.FixtureType == BoxTypeEnum._50uLTip头工装 || f.FixtureType == BoxTypeEnum._300uLTip头工装 || f.FixtureType == BoxTypeEnum._1000uLTip头工装))
&& workService.ProjectPro.TipHeadArea.Any(f => !f.HaveBox && f.IsEmpty))
{
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
//OrderByDescending
var tipFixture = workService.ProjectPro.TransferArea.LastOrDefault(f => !f.IsEmpty &&
(f.FixtureType == BoxTypeEnum._50uLTip头工装 || f.FixtureType == BoxTypeEnum._300uLTip头工装 || f.FixtureType == BoxTypeEnum._1000uLTip头工装));
int tipTransferIndex = workService.ProjectPro.TransferArea.IndexOf(tipFixture);
// 找到Tip头区域的空位置
var aimTipBox = workService.ProjectPro.TipHeadArea.FirstOrDefault(f => !f.HaveBox && f.IsEmpty);
int aimTipIndex = workService.ProjectPro.TipHeadArea.IndexOf(aimTipBox);
// 执行机械手操作
await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, tipFixture.FixtureType, (ushort)tipFixture.BoxId_inDoseUpload, _cts.Token);
ushort aimPos = (ushort)aimTipBox.BoxId_inDosingStation;
if (aimPos == 1)
{
aimPos = 3;
}
else if (aimPos == 3)
{
aimPos = 1;
}
await FourAxisPutBox((int)BoxAreaEnum._Tip托盘存放平台, tipFixture.FixtureType, aimPos, _cts.Token);
App.Current.Dispatcher.Invoke(() =>
{
// 复制Tip头工装到Tip区域替换集合元素
BaseBottleBox TipBox = File_Operator.DeepCopy(tipFixture);
if (TipBox is TipBoxModel newTipBox)
{
newTipBox.BoxId_inDosingStation = aimTipBox.BoxId_inDosingStation;
newTipBox.HaveBox = true;
newTipBox.IsEmpty = false;
newTipBox.IsUseFinsh = false;
newTipBox.BoxArea = BoxAreaEnum._Tip托盘存放平台;
workService.ProjectPro.TipHeadArea[aimTipIndex] = newTipBox; // 关键:更新集合元素
}
else
{
MessageBox.Show("error");
}
// 重置传送平台
workService.ProjectPro.TransferArea[tipTransferIndex] = new BaseBottleBox()
{
IsEmpty = true,
BoxId_inDoseUpload = tipFixture.BoxId_inDoseUpload,
IsDoseFinish = false,
IsUseFinsh = false,
BoxArea = BoxAreaEnum._手套箱传送平台
};
});
}
// 3. 原液工装:从传送平台 → 工装缓存区(任意空位置 改为 04号位置
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)); //原液只能放置在15
int aimCacheIndex = workService.ProjectPro.FixtureCacheArea.IndexOf(aimFixture);
// 执行机械手操作(传入原工装类型)
await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, liquidFixture.FixtureType, (ushort)liquidFixture.BoxId_inDoseUpload, _cts.Token);
await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, liquidFixture.FixtureType, (ushort)aimFixture.BoxId_inDosingStation, _cts.Token);
// 复制原液工装到缓存区
var newCacheFixture = File_Operator.DeepCopy(liquidFixture);
newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation;
newCacheFixture.IsDoseFinish = false;
newCacheFixture.IsEmpty = false;
newCacheFixture.IsUseFinsh = false;
newCacheFixture.BoxArea = BoxAreaEnum._托盘存放平台;
App.Current.Dispatcher.Invoke(() =>
{
workService.ProjectPro.FixtureCacheArea[aimCacheIndex] = newCacheFixture;
// 重置传送平台
workService.ProjectPro.TransferArea[liquidTransferIndex] = new BaseBottleBox()
{
IsEmpty = true,
BoxId_inDoseDnload = liquidFixture.BoxId_inDoseUpload,
BoxId_inDoseUpload = liquidFixture.BoxId_inDoseUpload,
IsDoseFinish = false,
IsUseFinsh = false,
BoxArea = BoxAreaEnum._手套箱传送平台
};
});
}
// 4. 样品工装:从传送平台 → 工装缓存区排除1、5号位置
while (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty &&
(f.FixtureType == BoxTypeEnum._5mL样品工装 || f.FixtureType == BoxTypeEnum._12mL样品工装))
&& workService.ProjectPro.FixtureCacheArea.Any(a => a.IsEmpty && a.BoxId_inDosingStation != 1 && a.BoxId_inDosingStation != 5))
{
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
// 找到传送平台中的样品工装(取第一个非空)
var sampleFixture = workService.ProjectPro.TransferArea.First(f => !f.IsEmpty &&
(f.FixtureType == BoxTypeEnum._5mL样品工装 || f.FixtureType == BoxTypeEnum._12mL样品工装));
int sampleTransferIndex = workService.ProjectPro.TransferArea.IndexOf(sampleFixture); // 获取集合索引
// 找到缓存区的空位置
var aimFixture = workService.ProjectPro.FixtureCacheArea.First(a => a.IsEmpty && a.BoxId_inDosingStation != 1 && a.BoxId_inDosingStation != 5 && a.BoxId_inDosingStation != 2 && a.BoxId_inDosingStation != 6);
int aimCacheIndex = workService.ProjectPro.FixtureCacheArea.IndexOf(aimFixture); // 获取集合索引
// 执行机械手操作(传入原工装类型,而非空工装类型)
await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, sampleFixture.FixtureType, (ushort)sampleFixture.BoxId_inDoseUpload, _cts.Token);
await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, sampleFixture.FixtureType, (ushort)aimFixture.BoxId_inDosingStation, _cts.Token);
App.Current.Dispatcher.Invoke(() =>
{
// 复制样品工装到缓存区(替换集合元素)
var newCacheFixture = File_Operator.DeepCopy(sampleFixture);
newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation;
newCacheFixture.IsDoseFinish = false;
newCacheFixture.IsEmpty = false;
newCacheFixture.IsUseFinsh = false;
newCacheFixture.BoxArea = BoxAreaEnum._托盘存放平台;
workService.ProjectPro.FixtureCacheArea[aimCacheIndex] = newCacheFixture;
// 重置传送平台位置为空工装
workService.ProjectPro.TransferArea[sampleTransferIndex] = new BaseBottleBox()
{
IsEmpty = true,
BoxId_inDoseDnload = sampleFixture.BoxId_inDoseUpload,
BoxId_inDoseUpload = sampleFixture.BoxId_inDoseUpload,
IsDoseFinish = false,
IsUseFinsh = false,
BoxArea = BoxAreaEnum._手套箱传送平台
};
});
}
await TransferPlateformMoveTo(PlateformPos.GloveBox1, _cts.Token); //最终停留在这个位置最安全
// 无符合条件的工装可上料
if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && f.FixtureType != BoxTypeEnum._16mL粉末瓶工装 && f.FixtureType != BoxTypeEnum._125mL粉末瓶工装))
{
MessageBox.Show("无可用工装或目标区域已满,无法上料!");
}
#endregion
this.StationProp.deviceStatus = Entities.DeviceStatus.Idel;
UpdateDeviceStatusEvent?.Invoke(this, Entities.DeviceStatus.Idel);
}
#endregion
#region qrbian
private CancellationTokenSource _cts = new CancellationTokenSource();
private async Task ProcessDispatcherEx()
{
while (!_cts.Token.IsCancellationRequested)
{
if (workService.stationService_Dose.StationProp.deviceStatus != Entities.DeviceStatus.Runing)
{
await Task.Delay(2000);
continue;
}
var hasAnyUsableBox = workService.ProjectPro.FixtureCacheArea
.OfType<SampleBottleBoxModel>()
.Where(b => b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装)
.Any(box => box.SampleBottleList.Any(bottle =>
bottle.HaveBottle &&
!bottle.bDoseFinish &&
bottle.MaterialDoseFlowList.Count > 0));
if (!hasAnyUsableBox)
{
await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
continue;
}
var FixtureCacheAreas = workService.ProjectPro.FixtureCacheArea.Where(b => b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装).OrderBy(s => s.BoxId_inDosingStation).ToList();
bool IsPowderInMachine = false; //加粉头是否在梅特勒称上
bool IsMotherLiquidInMachine = false; //母液是否已经在母液开盖位
for (int i = 0; i < FixtureCacheAreas.Count(); i++)
{
await TransferPlateformMoveTo(PlateformPos.GloveBox1, _cts.Token);
if (StationProp.deviceStatus == Entities.DeviceStatus.Abort) break;
var FixtureCacheArea = FixtureCacheAreas.ElementAt(i);
SampleBottleBoxModel sampleBox = FixtureCacheArea as SampleBottleBoxModel;
var samplebottles = sampleBox.SampleBottleList.Where(b => b.HaveBottle && !b.bDoseFinish && b.MaterialDoseFlowList.Count() > 0).OrderBy(b => b.PosId_InBox).ToList();
if (samplebottles.Count() > 0)
{
if (FixtureCacheArea.BoxId_inDosingStation == 4 || FixtureCacheArea.BoxId_inDosingStation == 8)
{
//干涉,先搬到前面一位
await FourAxisTakeBox((int)BoxAreaEnum._托盘存放平台, FixtureCacheArea.FixtureType, (ushort)FixtureCacheArea.BoxId_inDosingStation, _cts.Token);
await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, FixtureCacheArea.FixtureType, (ushort)(FixtureCacheArea.BoxId_inDosingStation - 1), _cts.Token);
App.Current.Dispatcher.Invoke(() =>
{
FixtureCacheArea.BoxId_inDosingStation -= 1;
workService.ProjectPro.FixtureCacheArea[FixtureCacheArea.BoxId_inDosingStation] = new BaseBottleBox()
{
IsEmpty = true,
BoxId_inDoseDnload = FixtureCacheArea.BoxId_inDoseUpload,
BoxId_inDoseUpload = FixtureCacheArea.BoxId_inDoseUpload,
BoxId_inDosingStation = FixtureCacheArea.BoxId_inDosingStation + 1,
IsDoseFinish = false,
IsUseFinsh = false,
BoxArea = BoxAreaEnum._托盘存放平台
};
workService.ProjectPro.FixtureCacheArea[FixtureCacheArea.BoxId_inDosingStation - 1] = FixtureCacheArea;
});
}
for (int j = 0; j < samplebottles.Count(); j++)
{
if (StationProp.deviceStatus == Entities.DeviceStatus.Abort) break;
var samplebottle = samplebottles.ElementAt(j);
//查找下一个目标瓶,用来判断母液或者粉末头是否一样,一样则不搬回去
SampleBottleModel samplebottleNext = null;
if (j < samplebottles.Count() - 1)
{
samplebottleNext = samplebottles.ElementAt(j + 1);
}
else
{
if (i < FixtureCacheAreas.Count() - 1)
{
var nextFixtureCacheArea = FixtureCacheAreas.ElementAt(i + 1);
SampleBottleBoxModel sampleBoxNext = nextFixtureCacheArea as SampleBottleBoxModel;
var samplebottlesNext = sampleBoxNext.SampleBottleList.Where(b => b.HaveBottle && !b.bDoseFinish && b.MaterialDoseFlowList.Count() > 0).OrderBy(b => b.PosId_InBox);
if (samplebottlesNext != null && samplebottlesNext.Any())
{
samplebottleNext = samplebottlesNext.FirstOrDefault();
}
}
}
var res = await MixForSampleBottle(samplebottle, sampleBox, IsPowderInMachine, IsMotherLiquidInMachine, samplebottleNext);
IsPowderInMachine = res._isPowderInMachine;
IsMotherLiquidInMachine = res._isMotherLiquidInMachine;
}
}
//搬运到转运区域只能是1~3
var aimTransferFixture = GetAvaliableTransferArea(1);
if (aimTransferFixture != null) //&& !workService.ProjectPro.bNoUseBS
{
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
await TransferFixtureFromCacheToTransfer(FixtureCacheArea, aimTransferFixture, _cts.Token); //搬运回物料区域 暂时屏蔽
}
}
WeakReferenceMessenger.Default.Send(new DesktopAlertMessage()
{
Header = $"提示",
Content = $"工单已完成"
});
#region 使
if (false && !TestMode)
{
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
await FourAxisTakePowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, PowderBottleTypeEnum._16mL, _cts.Token);
//Task task1 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0); //多余的
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, 1, PowderBottleTypeEnum._16mL, _cts.Token);
//await Task.WhenAll(task1, task2);
await SetObstructFlag("四轴机械手运行中", false);
IsPowderInMachine = false;
}
#endregion
await ChangeDeviceStatus(Entities.DeviceStatus.Finish);
//if (workService.ProjectPro.bNoUseBS)
//{
// #region //todo:测试使用,后期一定要屏蔽
// await ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
// await TransferPlateformMoveTo( PlateformPos.TransferIn,_cts.Token);
// await TransferPlateformMoveTo(PlateformPos.TransferOut, _cts.Token);
// /*
// try
// {
// var res = await SendJson(new Guid().ToString(), "test", "");
// Logger.LogInformation($"向BS发送完成接收到-{res.Item2}");
// }
// catch (Exception ex)
// {
// MessageBox.Show(ex.Message);
// }
// ProjectProperty project = new ProjectProperty();
// bool readOk = false;
// project = File_Operator.Xml_Serialize("C:\\Users\\CTOS\\Desktop\\empty.pro", false, project, out readOk);
// if (readOk)
// {
// workService.ProjectPro = project;
// workService.ProjectPro.LastOpenProject = "C:\\Users\\CTOS\\Desktop\\empty.pro";
// workService.ProjectPro.NowOpenProjectFile = "C:\\Users\\CTOS\\Desktop\\empty.pro".Substring("C:\\Users\\CTOS\\Desktop\\empty.pro".LastIndexOf("\\") + 1).Trim();
// //WeakReferenceMessenger.Default.Send(new DesktopAlertMessage { Content = "打开项目文件成功!" });
// }
// */
// #endregion
// await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
//}
//else
//{
// await ChangeDeviceStatus(Entities.DeviceStatus.Finish);
//}
}
}
//下料流程
private async Task DownLoadDispatcherEx()
{
while (!_cts.Token.IsCancellationRequested)
{
if (workService.stationService_Dose.StationProp.deviceStatus != Entities.DeviceStatus.Finish)
{
await Task.Delay(2000);
continue;
}
if (workService.ProjectPro.TransferArea.All(t => t.IsEmpty))
{
await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
continue;
}
await ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
#region tip
for (int i = 1; i <= 3; i++) //1~3是样品载具
{
if (workService.ProjectPro.TransferArea.Count < i) break;
var transferArea = workService.ProjectPro.TransferArea[i - 1];
if (!transferArea.IsEmpty) continue;
//寻找是否有样品载具待搬运
var sampleFixture = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._12mL样品工装 || f.FixtureType == BoxTypeEnum._5mL样品工装));
if (sampleFixture == null) break;
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
await TransferFixtureFromCacheToTransfer(sampleFixture, transferArea, _cts.Token);
}
for (int i = 4; i <= 5; i++) //4~5是母液载具
{
if (workService.ProjectPro.TransferArea.Count < i) break;
var transferArea = workService.ProjectPro.TransferArea[i - 1];
if (!transferArea.IsEmpty) continue;
//寻找是否有母液载具待搬运
var targetFixture = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._40mL原液工装));
if (targetFixture == null) break;
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
await TransferFixtureFromCacheToTransfer(targetFixture, transferArea, _cts.Token);
}
for (int i = 6; i <= 7; i++) //6~7是tip/粉末
{
if (workService.ProjectPro.TransferArea.Count < i) break;
var transferArea = workService.ProjectPro.TransferArea[i - 1];
if (!transferArea.IsEmpty && (transferArea.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || transferArea.FixtureType == BoxTypeEnum._125mL粉末瓶工装) )
{
//找粉末放进去
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
await TransferPlateformMoveTo(PlateformPos.GloveBox1, _cts.Token);
if (transferArea.FixtureType == BoxTypeEnum._16mL粉末瓶工装)
{
var samplePowderBox = transferArea as SourcePowderBottleBoxModel;
for (int j = 0;j< samplePowderBox.SourcePowderBottleCollection.Count;j++)
{
var sourcePowderBottleHome = samplePowderBox.SourcePowderBottleCollection[j];
if (!sourcePowderBottleHome.HaveBottle)
{
//搬运粉末头
var powderHeader = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(p =>(p.PosId_InBox == j + 1) && p.BoxSNCode.Equals(samplePowderBox.BoxSNCode) && p.HaveBottle && p.PowderBottleType == sourcePowderBottleHome.PowderBottleType);
if (powderHeader == null) break;
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderHeader.Pos_InDosePowderHC, powderHeader.PowderBottleType, _cts.Token,1);
await FourAxisPutPowderHeader((int)BoxAreaEnum._手套箱传送平台, samplePowderBox.BoxId_inDoseUpload, sourcePowderBottleHome.PosId_InBox, powderHeader.PowderBottleType, _cts.Token,1);
var newPowderBottle = File_Operator.DeepCopy(powderHeader);
newPowderBottle.PosId_InBox = sourcePowderBottleHome.PosId_InBox;
newPowderBottle.HaveBottle = true;
App.Current.Dispatcher.Invoke(() =>
{
samplePowderBox.SourcePowderBottleCollection[j] = newPowderBottle;
powderHeader.HaveBottle = false; powderHeader.SourcePowderName = ""; powderHeader.OriginWeight = powderHeader.RemainWeight = 0;
});
}
}
}
else
{
var samplePowderBox = transferArea as SourcePowderBottleBoxModel_125ml;
for (int j = 0; j < samplePowderBox.SourcePowderBottleCollection.Count; j++)
{
var sourcePowderBottleHome = samplePowderBox.SourcePowderBottleCollection[j];
if (!sourcePowderBottleHome.HaveBottle)
{
//搬运粉末头
var powderHeader = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(p => p.HaveBottle && p.PowderBottleType == sourcePowderBottleHome.PowderBottleType);
if (powderHeader == null) break;
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderHeader.Pos_InDosePowderHC, powderHeader.PowderBottleType, _cts.Token, 1);
await FourAxisPutPowderHeader((int)BoxAreaEnum._手套箱传送平台, samplePowderBox.BoxId_inDoseUpload, sourcePowderBottleHome.PosId_InBox, powderHeader.PowderBottleType, _cts.Token, 1);
var newPowderBottle = File_Operator.DeepCopy(powderHeader);
newPowderBottle.PosId_InBox = sourcePowderBottleHome.PosId_InBox;
newPowderBottle.HaveBottle = true;
App.Current.Dispatcher.Invoke(() =>
{
powderHeader.HaveBottle = false; powderHeader.SourcePowderName = ""; powderHeader.OriginWeight = powderHeader.RemainWeight = 0;
samplePowderBox.SourcePowderBottleCollection[j] = newPowderBottle;
});
}
}
}
}
else if (transferArea.IsEmpty)
{
//找tip放进去
var targetFixture = workService.ProjectPro.TipHeadArea.FirstOrDefault(f => !f.IsEmpty);
if (targetFixture == null) continue;
await TransferPlateformMoveTo(PlateformPos.GloveBox2, _cts.Token);
await TransferFixtureFromCacheToTransfer(targetFixture, transferArea, _cts.Token);
}
}
//await TransferPlateformMoveTo(PlateformPos.TransferIn, _cts.Token);
await TransferPlateformMoveTo(PlateformPos.TransferOut, _cts.Token);
//MessageBox.Show("通知AGV取料-需要判断是否需要空粉末治具及个数");
//var testJson = new { test="1" };
//var res = await SendJson((new Guid()).ToString(), "unload" , testJson.ToJson());
#region BS数据
ToBsUnLoadData toBsUnLoadData = new ToBsUnLoadData()
{
SampleSeqs = new List<ToBsSampleSeq>(),
Config = new ToBsConfig(),
NeedFixture = new List<ToBsFixtureInfo>()
};
toBsUnLoadData.Config.BoxInfo = new List<ToBsBoxInfo>();
for (int i = 0; i < 7; i++)
{
var transferArea = workService.ProjectPro.TransferArea[i];
if (transferArea.IsEmpty) continue;
ToBsBoxInfo boxInfo = new ToBsBoxInfo()
{
FixtureType = (int)transferArea.FixtureType,
SnCode = transferArea.BoxSNCode,
PosInUpload = transferArea.BoxId_inDoseUpload,
Detail = new List<Detail>()
};
//如果是原液或者粉末需要将数据写入boxInfo.details,如果是5、12ml瓶子则写入toBsUnLoadData.SampleSeqs
if (transferArea is TipBoxModel)
{
var tipBox = transferArea as TipBoxModel;
boxInfo.RemainCount = tipBox.TipItems.Count(t => t.IsAvailable);
}
else if (transferArea is SourceLiquidBottleBoxModel)
{
var sourceBox = transferArea as SourceLiquidBottleBoxModel;
var allBottles = sourceBox.SourceLiquidBottleCollection.Where(s => s.HaveBottle);
foreach (var bottle in allBottles)
{
var detail = new Detail()
{
Code = bottle.SourceLiquidName,
Pos = bottle.PosId_InBox.ToString(),
RemainWeight = bottle.RemainVolume
};
boxInfo.Detail.Add(detail);
}
}
else if (transferArea is SourcePowderBottleBoxModel)
{
var sourceBox = transferArea as SourcePowderBottleBoxModel;
var allBottles = sourceBox.SourcePowderBottleCollection.Where(s => s.HaveBottle);
foreach (var bottle in allBottles)
{
var detail = new Detail()
{
Code = bottle.SourcePowderName,
Pos = bottle.PosId_InBox.ToString(),
RemainWeight = bottle.RemainWeight
};
boxInfo.Detail.Add(detail);
}
}
else if (transferArea is SourcePowderBottleBoxModel_125ml)
{
var sourceBox = transferArea as SourcePowderBottleBoxModel_125ml;
var allBottles = sourceBox.SourcePowderBottleCollection.Where(s => s.HaveBottle);
foreach (var bottle in allBottles)
{
var detail = new Detail()
{
Code = bottle.SourcePowderName,
Pos = bottle.PosId_InBox.ToString(),
RemainWeight = bottle.RemainWeight
};
boxInfo.Detail.Add(detail);
}
}
else if (transferArea is SampleBottleBoxModel)
{
var sourceBox = transferArea as SampleBottleBoxModel;
var allBottles = sourceBox.SampleBottleList.Where(s => s.HaveBottle);
foreach (var bottle in allBottles)
{
var sampleSeq = new ToBsSampleSeq()
{
Area = "A1",
Carrier = transferArea.BoxId_inDoseUpload.ToString(),
Code = bottle.SampleContentName,
Pos = bottle.PosId_InBox.ToString(),
SampleConfig = new ToBsSampleConfig(),
OriginSeqIds = new List<long>() { bottle.SampleSeqId }
};
sampleSeq.SampleConfig.SnCode = transferArea.BoxSNCode;
sampleSeq.SampleConfig.MaterialDoseFunctionFlow = new List<ToBsMaterialDoseFunctionFlow>();
if (bottle.MaterialDoseFlowList != null && bottle.MaterialDoseFlowList.Count > 0)
{
foreach (var item in bottle.MaterialDoseFlowList)
{
ToBsMaterialDoseFunctionFlow sampleFunction = new ToBsMaterialDoseFunctionFlow()
{
FunctionFlowType = (int)item.FunctionFlowType,
TargetVolumn = item.TargetVolume,
UserMaterialName = item.UseMaterialName,
RealVolumn = item.ActualVolume
};
sampleSeq.SampleConfig.MaterialDoseFunctionFlow.Add(sampleFunction);
}
toBsUnLoadData.SampleSeqs.Add(sampleSeq);
}
sampleSeq.SampleType = bottle.SampleBottleType == SampleBottleTypeEnum._5mL ? "5mL" : "12mL";
}
}
toBsUnLoadData.Config.BoxInfo.Add(boxInfo);
}
var toBsFixtureInfo = new List<ToBsFixtureInfo>();
var allPowderBottles = workService.ProjectPro.PowderHeaderCacheArea.Where(p => p.HaveBottle);
List<int> remainTransferPos = new List<int>() { 6,7};
foreach (var PowderBottle in allPowderBottles)
{
if (toBsFixtureInfo.All(s => !s.SnCode.Equals(PowderBottle.BoxSNCode)))
{
var pos = remainTransferPos.FirstOrDefault();
if (pos != 6 && pos != 7) continue;
remainTransferPos.Remove(pos);
toBsFixtureInfo.Add(new ToBsFixtureInfo()
{
FixtureType = PowderBottle.PowderBottleType == PowderBottleTypeEnum._16mL ? (int)BoxTypeEnum._16mL粉末瓶工装 : (int)BoxTypeEnum._125mL粉末瓶工装,
BoxIdInDoseUpload = pos,
SnCode = PowderBottle.BoxSNCode
});
}
}
toBsUnLoadData.NeedFixture = toBsFixtureInfo;
if (toBsUnLoadData.NeedFixture.Count > 0)
{
WeakReferenceMessenger.Default.Send(new DesktopAlertMessage()
{
Header = "提示",
Content = $"向BS请求治具{JsonConvert.SerializeObject(toBsUnLoadData.NeedFixture)}"
});
}
#endregion
if (!workService.ProjectPro.bNoUseBS)
{
var res = await SendJson((new Guid()).ToString(), "unload", toBsUnLoadData.ToJson());
while (!res.Item1)
{
WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Header = "提示", Content = "调用BS-unload方法失败" });
await Task.Delay(1000);
res = await SendJson((new Guid()).ToString(), "unload", toBsUnLoadData.ToJson());
}
}
else
{
//todo:不启用bs给出个弹窗拿完之后清空传递仓数据,并将状态置为Finish
}
#endregion
}
}
/// <summary>
/// 返回转移区域的空位置
/// </summary>
/// <param name="type">1表示目标瓶在1-3找2表示原液瓶在4-5找3表示tip载具4表示粉末载具在6-7找</param>
private BaseBottleBox GetAvaliableTransferArea(int type)
{
BaseBottleBox baseBottleBox = null;
int startIndex = 0;
int endIndex = 0;
switch (type)
{
case 1: //目标瓶在1-3
startIndex = 0; endIndex = 3;
break;
case 2: //原液瓶载具在4-5
startIndex = 3; endIndex = 5;
break;
case 3: //tip
case 4: //粉末在6-7
startIndex = 5; endIndex = 7;
break;
default:
break;
}
for (int i = startIndex; i < endIndex; i++)
{
if (workService.ProjectPro.TransferArea[i].IsEmpty)
{
baseBottleBox = workService.ProjectPro.TransferArea[i];
break;
}
}
return baseBottleBox;
}
private async Task<bool> TransferFixtureFromPowderCacheToTransfer(SourcePowderBottleModel sourcePowderBottleModel, CancellationToken token)
{
var fixture = sourcePowderBottleModel.PowderBottleType == PowderBottleTypeEnum._16mL ? BoxTypeEnum._16mL粉末瓶工装 : BoxTypeEnum._125mL粉末瓶工装;
var powderFixtures = workService.ProjectPro.TransferArea.Where(f => !f.IsEmpty && f.FixtureType == fixture);
SourcePowderBottleBoxModel powderBox = null;
SourcePowderBottleBoxModel_125ml powderBox_125 = null;
BaseBottleBox powderFixture1 = null;
foreach (var powderFixture in powderFixtures)
{
if (powderFixture is SourcePowderBottleBoxModel)
{
powderBox = powderFixture as SourcePowderBottleBoxModel;
if (powderBox.SourcePowderBottleCollection.Any(s => !s.HaveBottle)) break;
}
else if (powderFixture is SourcePowderBottleBoxModel_125ml)
{
powderBox_125 = powderFixture as SourcePowderBottleBoxModel_125ml;
if (powderBox_125.SourcePowderBottleCollection.Any(s => !s.HaveBottle)) break;
}
powderFixture1 = powderFixture;
}
if (powderBox.SourcePowderBottleCollection.All(s => s.HaveBottle) && powderBox_125.SourcePowderBottleCollection.All(s => s.HaveBottle)) return false;
int powderTransferIndex = workService.ProjectPro.TransferArea.IndexOf(powderFixture1);//治具位置
int sourceIndex = workService.ProjectPro.PowderHeaderCacheArea.IndexOf(sourcePowderBottleModel); //缓存位置位置
if (powderBox != null)
{
var aimPowderBottle = powderBox.SourcePowderBottleCollection.First(s => !s.HaveBottle); //目标位置
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, sourceIndex, powderBox.PowderBottleType, token);
await FourAxisPutPowderHeader((int)BoxAreaEnum._手套箱传送平台, powderFixture1.BoxId_inDoseUpload, aimPowderBottle.PosId_InBox, powderBox.PowderBottleType, token);
var newPowderBottle = File_Operator.DeepCopy(sourcePowderBottleModel);
newPowderBottle.HaveBottle = true;
newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC;
powderBox.SourcePowderBottleCollection[aimPowderBottle.PosId_InBox - 1] = newPowderBottle;
workService.ProjectPro.PowderHeaderCacheArea[sourceIndex - 1] = new SourcePowderBottleModel()
{
HaveBottle = false
};
}
else if (powderBox_125 != null)
{
var aimPowderBottle = powderBox_125.SourcePowderBottleCollection.First(s => !s.HaveBottle); //目标位置
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, sourceIndex, powderBox_125.PowderBottleType, token);
await FourAxisPutPowderHeader((int)BoxAreaEnum._手套箱传送平台, powderFixture1.BoxId_inDoseUpload, aimPowderBottle.PosId_InBox, powderBox_125.PowderBottleType, token);
// 更新粉末缓存区(替换集合元素)
var newPowderBottle = File_Operator.DeepCopy(sourcePowderBottleModel);
newPowderBottle.HaveBottle = true;
newPowderBottle.Pos_InDosePowderHC = aimPowderBottle.Pos_InDosePowderHC;
powderBox_125.SourcePowderBottleCollection[aimPowderBottle.PosId_InBox - 1] = newPowderBottle;
workService.ProjectPro.PowderHeaderCacheArea[sourceIndex - 1] = new SourcePowderBottleModel()
{
HaveBottle = false
};
}
return true;
}
/// <summary>
/// 搬运治具从tip缓存位到搬运位
/// </summary>
/// <param name="fixture"></param>
/// <returns></returns>
private async Task<bool> TransferFixtureFromTipCacheToTransfer(TipBoxModel FixtureCacheArea, CancellationToken token)
{
var aimFixture = workService.ProjectPro.TransferArea.OrderBy(a => a.BoxId_inDosingStation).First(f => f.IsEmpty);
if (aimFixture is null)
{
return false;
}
int aimFixtureIndex = workService.ProjectPro.TransferArea.IndexOf(aimFixture);
await FourAxisTakeBox((int)BoxAreaEnum._Tip托盘存放平台, FixtureCacheArea.FixtureType, (ushort)FixtureCacheArea.BoxId_inDosingStation, _cts.Token);
await FourAxisPutBox((int)BoxAreaEnum._手套箱传送平台, aimFixture.FixtureType, (ushort)aimFixture.BoxId_inDosingStation, _cts.Token);
var newCacheFixture = File_Operator.DeepCopy(FixtureCacheArea);
newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation;
newCacheFixture.IsDoseFinish = true;
newCacheFixture.IsEmpty = false;
newCacheFixture.IsUseFinsh = true;
try
{
App.Current.Dispatcher.Invoke(() =>
{
workService.ProjectPro.TransferArea[aimFixtureIndex] = newCacheFixture;
workService.ProjectPro.TipHeadArea[FixtureCacheArea.BoxId_inDosingStation - 1] = new TipBoxModel()
{
IsEmpty = true,
BoxId_inDoseDnload = FixtureCacheArea.BoxId_inDoseUpload,
BoxId_inDoseUpload = FixtureCacheArea.BoxId_inDoseUpload,
IsDoseFinish = false,
IsUseFinsh = false,
BoxArea = BoxAreaEnum._手套箱传送平台
};
});
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return true;
}
/// <summary>
/// 搬运治具从缓存位到搬运位
/// </summary>
/// <param name="fixture"></param>
/// <returns></returns>
private async Task<bool> TransferFixtureFromCacheToTransfer(BaseBottleBox FixtureCacheArea, BaseBottleBox aimFixture, CancellationToken token)
{
//var aimFixture = workService.ProjectPro.TransferArea.OrderBy(a => a.BoxId_inDosingStation).First(f => f.IsEmpty);
if (aimFixture is null)
{
return false;
}
var aimFixtureIndex = workService.ProjectPro.TransferArea.IndexOf(aimFixture);
if (FixtureCacheArea is TipBoxModel)
{
var fixtnew = FixtureCacheArea as TipBoxModel;
var pos = (ushort)fixtnew.BoxId_inDosingStation;
pos = (ushort)(3 - pos + 1);
await FourAxisTakeBox((ushort)BoxAreaEnum._Tip托盘存放平台, fixtnew.FixtureType, (ushort)pos, _cts.Token);
await FourAxisPutBox((int)BoxAreaEnum._手套箱传送平台, fixtnew.FixtureType, (ushort)aimFixture.BoxId_inDoseUpload, _cts.Token);
}
else
{
await FourAxisTakeBox((ushort)BoxAreaEnum._托盘存放平台, FixtureCacheArea.FixtureType, (ushort)FixtureCacheArea.BoxId_inDosingStation, _cts.Token);
await FourAxisPutBox((int)BoxAreaEnum._手套箱传送平台, FixtureCacheArea.FixtureType, (ushort)aimFixture.BoxId_inDoseUpload, _cts.Token);
}
var newCacheFixture = File_Operator.DeepCopy(FixtureCacheArea);
newCacheFixture.BoxId_inDoseUpload = aimFixture.BoxId_inDoseUpload;
newCacheFixture.BoxId_inDosingStation = aimFixture.BoxId_inDosingStation;
newCacheFixture.IsDoseFinish = true;
newCacheFixture.IsEmpty = false;
newCacheFixture.IsUseFinsh = true;
try
{
App.Current.Dispatcher.Invoke(() =>
{
workService.ProjectPro.TransferArea[aimFixtureIndex] = newCacheFixture;
if (FixtureCacheArea.BoxArea == BoxAreaEnum._托盘存放平台)
{
workService.ProjectPro.FixtureCacheArea[FixtureCacheArea.BoxId_inDosingStation - 1] = new BaseBottleBox()
{
IsEmpty = true,
BoxId_inDoseDnload = FixtureCacheArea.BoxId_inDoseUpload,
BoxId_inDoseUpload = FixtureCacheArea.BoxId_inDoseUpload,
BoxId_inDosingStation = FixtureCacheArea.BoxId_inDosingStation,
IsDoseFinish = false,
IsUseFinsh = false,
BoxArea = BoxAreaEnum._托盘存放平台
};
}
else if (FixtureCacheArea.BoxArea == BoxAreaEnum._Tip托盘存放平台)
{
var fixTipModel = FixtureCacheArea as TipBoxModel;
var tipBox = new TipBoxModel()
{
IsEmpty = true,
BoxId_inDosingStation = fixTipModel.BoxId_inDosingStation,
BoxArea = BoxAreaEnum._Tip托盘存放平台,
FixtureType = fixTipModel.FixtureType, HaveBox = false, UseIndex = 96,
TipItems = new ObservableCollection<TipHeadItem>()
};
for (int i = 0; i < 96; i++)
{
tipBox.TipItems.Add(new TipHeadItem() { IsAvailable = false, UseIndex = i + 1});
}
workService.ProjectPro.TipHeadArea[fixTipModel.BoxId_inDosingStation - 1] = tipBox;
}
});
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return true;
}
public async Task TransferPlateformMoveTo(PlateformPos plateformPos, CancellationToken token)
{
if (token.IsCancellationRequested || TestMode) return;
var _modbusClient_Plc1 = this.CoreService.GetServiceInstance<IModbusClientExtend>(DeviceNames.Plc1.ToString());
var transferPlatePos = await ReadScannedValueAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_BoxPos);
if (transferPlatePos > 0 && transferPlatePos < 5) //需要先读取当前的位置,如果当前位置是
{
PlateformPos currentPos = PlateformPos.TransferOut;
//1:外面 2里面 3加粉头 4载具位置
switch (transferPlatePos)
{
case 1:
currentPos = PlateformPos.TransferOut;
break;
case 2:
currentPos = PlateformPos.TransferIn;
break;
case 3:
currentPos = PlateformPos.GloveBox1;
break;
case 4:
currentPos = PlateformPos.GloveBox2;
break;
default:
break;
}
if ((plateformPos == PlateformPos.TransferOut && (currentPos == PlateformPos.GloveBox1 || currentPos == PlateformPos.GloveBox2))
|| (currentPos == PlateformPos.TransferOut && (plateformPos == PlateformPos.GloveBox1 || plateformPos == PlateformPos.GloveBox2))
)
{
//目标是过渡舱外面,且当前是过渡舱内部 或者当前是过渡舱外面,且目标是过渡舱内部 需要先将过渡舱到舱内
_modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, (ushort)PlateformPos.TransferIn);
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 22, token);
_modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, 0);
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 5, token);
}
}
transferPlatePos = await ReadScannedValueAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_BoxPos);
if (transferPlatePos > 0 && transferPlatePos < 5)
{
PlateformPos currentPos = PlateformPos.TransferOut;
switch (transferPlatePos)
{
case 1:
currentPos = PlateformPos.TransferOut;
break;
case 2:
currentPos = PlateformPos.TransferIn;
break;
case 3:
currentPos = PlateformPos.GloveBox1;
break;
case 4:
currentPos = PlateformPos.GloveBox2;
break;
default:
break;
}
if (currentPos != PlateformPos.GloveBox1 && currentPos != PlateformPos.GloveBox2 && plateformPos == PlateformPos.GloveBox1)
{
//目标是粉末位置,当前位置如果
_modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, (ushort)PlateformPos.GloveBox2);
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 22, token);
_modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, 0);
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 5, token);
}
}
_modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, (ushort)plateformPos);
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 22, token);
_modbusClient_Plc1.Command.WriteValue<ushort>(PlcPoints_MaterialDose.W_TransferPlate_TaskNo, 0);
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_TransferPlate_RunResult, 5, token);
}
public async Task WriteCmdToPlc(string cmd)
{
ushort plcAddress = 0;
ushort value = 1;
bool needReset = true; //是否需要200ms复位
bool needMaunalMode = false; //是否需要自动
bool needChangeMode = false;
switch (cmd)
{
case "start":
plcAddress = PlcPoints_MaterialDose.W_PCRunStatus;
needChangeMode = true;
value = 2;
break;
case "pause":
plcAddress = PlcPoints_MaterialDose.W_PCRunStatus;
value = 1; //1停止中2运行中
break;
case "reset":
plcAddress = PlcPoints_MaterialDose.W_InformationConfirm;
value = 1;
break;
case "init":
plcAddress = PlcPoints_MaterialDose.W_Initial;
value = 1; needMaunalMode = true;
break;
default:
break;
}
if (plcAddress != 0 && !TestMode)
{
if (needChangeMode)
{
ushort plcMode = needMaunalMode ? (ushort)1 : (ushort)2; //1切成手动 2切成自动
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_PCMode, plcMode);
await Task.Delay(200);
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_PCMode, 0);
await Task.Delay(200);
}
await WriteCommandAsync_FourAxis(plcAddress, value);
if (needReset)
{
await Task.Delay(1000);
await WriteCommandAsync_FourAxis(plcAddress, 0);
}
}
}
private int GetBottleId(SampleBottleTypeEnum sampleType)
{
int res = 3;
switch (sampleType)
{
case SampleBottleTypeEnum._5mL:
res = 3;
break;
case SampleBottleTypeEnum._12mL:
res = 2;
break;
default:
break;
}
return res;
}
/// <summary>
/// 目标瓶一次加完全部的需要的液体及固体
/// </summary>
/// <param name="sampleBottle"></param>
/// <param name="sampleBox"></param>
/// <returns></returns>
private async Task<(bool _isPowderInMachine,bool _isMotherLiquidInMachine)> MixForSampleBottle(SampleBottleModel sampleBottle, SampleBottleBoxModel sampleBox,bool IsPowderInMachine, bool IsMotherLiquidInMachine, SampleBottleModel samplebottleNext = null)
{
#region
await SetObstructFlag("四轴机械手运行中", true);
await FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._托盘存放平台, sampleBox.BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
if (string.IsNullOrEmpty(sampleBottle.SNCode))
{
await FourAxisGoToScannPos_liquid(_cts.Token, GetBottleId(sampleBottle.SampleBottleType), null, sampleBottle);
if (TestMode) sampleBottle.SNCode = DateTime.Now.ToString();
}
await FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
await SetObstructFlag("四轴机械手运行中", false);
await OpenBottleLid(_cts.Token, null, sampleBottle);
if (!TestMode)
{
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
}
//固定加一个粉末,演示使用,0317粉末载具搬运干涉客户想看只能固定1号位置加16ml的演示了
if (false && !TestMode)
{
#region
SourcePowderBottleModel powderBottle = new SourcePowderBottleModel()
{
Pos_InDosePowderHC = 1,
PowderBottleType = PowderBottleTypeEnum._16mL
};
if (!IsPowderInMachine)
{
if (!TestMode)
{
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
//四轴机械手取粉末加样头 放到称重模块中
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderBottle.Pos_InDosePowderHC, powderBottle.PowderBottleType, _cts.Token);
//将粉末头放到梅特勒称重模块中
labxPowderInstrument = await labxService.GetInstruments("自动天平XPR105");
await labxService.StartWaitingForHead(labxPowderInstrument.FirstOrDefault(), "Dosing Head", "Dosing Head");
await FourAxisPutPowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, powderBottle.PowderBottleType, _cts.Token);
await SetObstructFlag("四轴机械手运行中", false);
await labxService.AbortWaitingForHead();
}
}
IsPowderInMachine = true;
#endregion
#region
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
var task1 = FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
var task2 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);//开门
await Task.WhenAll(task1, task2);
await FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
await SetObstructFlag("四轴机械手运行中", false);
#endregion
#region
//梅特勒模块关门
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);
double addPowderWeight = 0;
//大99小125 2~200mg +-0.297mg 200mg-5g 0.297%
decimal dosHeight = sampleBottle.SampleBottleType == SampleBottleTypeEnum._12mL ? 99m : 125m;
double TargetVolume = 30;
decimal upT = Math.Round(TargetVolume < 200 ? (decimal)(0.297 / TargetVolume * 100) : 0.297m,13);
Logger.LogInformation($"请求加样的粉末数量-{TargetVolume},上下限为{upT}");
addPowderWeight = await labxService.MTPowderModuleAddPowder(labxPowderInstrument.FirstOrDefault(), "Dosing2", "Dosing2", 4, dosHeight, (decimal)TargetVolume, (decimal)upT, (decimal)upT);
//梅特勒模块开门
//await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);
#endregion
#region
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);//开门
await FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
Task task11 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0); //关门
Task task22 = FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
await Task.WhenAll(task11, task22);
await SetObstructFlag("四轴机械手运行中", false);
#endregion
}
#endregion
bool SampleHasOpened = false;
for (int i = 0; i < sampleBottle.MaterialDoseFlowList.Count; i++)
{
var addSample = sampleBottle.MaterialDoseFlowList[i];
if (addSample.FunctionFlowType!= FunctionTypeEnum. && (string.IsNullOrEmpty(addSample.UseMaterialName) || addSample.TargetVolume <= 0))
{
MessageBox.Show("数据错误!");
}
if (addSample.FunctionFlowType == FunctionTypeEnum.)
{
#region
var powderBottle = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(ph => !string.IsNullOrEmpty(addSample.UseMaterialName) && addSample.UseMaterialName.Equals(ph.SourcePowderName));
if (powderBottle is null)
{
Logger.LogError($"找不到{sampleBox.BoxId_inDosingStation}-{sampleBottle.PosId_InBox}需要的{addSample.UseMaterialName}固体");
continue;
}
powderBottle.SourcePowderBottleState = SourceBottleStateEnum.Using;
if (!IsPowderInMachine)
{
if (!TestMode)
{
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
//四轴机械手取粉末加样头 放到称重模块中
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderBottle.Pos_InDosePowderHC, powderBottle.PowderBottleType, _cts.Token);
//将粉末头放到梅特勒称重模块中
labxPowderInstrument = await labxService.GetInstruments("自动天平XPR105");
await labxService.StartWaitingForHead(labxPowderInstrument.FirstOrDefault(), "Dosing Head", "Dosing Head");
await FourAxisPutPowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, powderBottle.PowderBottleType, _cts.Token);
await SetObstructFlag("四轴机械手运行中", false);
await labxService.AbortWaitingForHead();
}
}
IsPowderInMachine = false;
#endregion
#region
if (!TestMode && (i == 0 || sampleBottle.MaterialDoseFlowList[i - 1].FunctionFlowType != FunctionTypeEnum.))
{
//第一个加样或者上一个加样不是固体,则取目标瓶开盖位到称重位
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
var task1 = FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
var task2 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);//开门
await Task.WhenAll(task1,task2);
await FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
await SetObstructFlag("四轴机械手运行中", false);
}
#endregion
#region
if (!TestMode)
{
//梅特勒模块关门
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);
double addPowderWeight = 0;
//大99小125 2~200mg +-0.297mg 200mg-5g 0.297%
decimal dosHeight = sampleBottle.SampleBottleType == SampleBottleTypeEnum._12mL ? 96m : 122m; //99m : 125m
decimal upT = Math.Round((decimal)addSample.TargetVolume < 200 ? (decimal)(0.297 / addSample.TargetVolume * 100) : 0.297m, 11);
Logger.LogInformation($"(decimal)addSample.TargetVolume-{addSample.TargetVolume},上下限为{upT}");
addPowderWeight = await labxService.MTPowderModuleAddPowder(labxPowderInstrument.FirstOrDefault(), "Dosing2", "Dosing2", 4, dosHeight, (decimal)addSample.TargetVolume, (decimal)upT, (decimal)upT);
powderBottle.RemainWeight -= addPowderWeight / 1000;
addSample.ActualVolume = addPowderWeight;
}
else
{
addSample.ActualVolume = addSample.TargetVolume;
}
Logger.LogInformation($"粉末目标:{addSample.TargetVolume}实际:{addSample.ActualVolume}");
addSample.IsDoseFinish = true;
//梅特勒模块开门
//await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);
#endregion
#region
if (powderBottle != null && !TestMode)
{
//判断是不是最后一个粉末,如果是的话判断下一瓶是不是用的该粉末
bool IsLastPowder = true;
for (int j = i + 1; j < sampleBottle.MaterialDoseFlowList.Count; j++)
{
if (sampleBottle.MaterialDoseFlowList[j].FunctionFlowType == FunctionTypeEnum.)
{
IsLastPowder = false;
IsPowderInMachine = sampleBottle.MaterialDoseFlowList[j].UseMaterialName.Equals(powderBottle.SourcePowderName);
break;
}
}
if (IsLastPowder && samplebottleNext != null)
{
var nextMotherLiquid = samplebottleNext.MaterialDoseFlowList.FirstOrDefault(s => s.FunctionFlowType == FunctionTypeEnum.);
IsPowderInMachine = nextMotherLiquid != null && nextMotherLiquid.UseMaterialName.Equals(powderBottle.SourcePowderName);
}
if (!IsPowderInMachine)
{
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
await FourAxisTakePowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, powderBottle.PowderBottleType, _cts.Token);
//Task task1 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0); //多余的
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, powderBottle.Pos_InDosePowderHC, powderBottle.PowderBottleType, _cts.Token);
//await Task.WhenAll(task1, task2);
await SetObstructFlag("四轴机械手运行中", false);
}
powderBottle.SourcePowderBottleState = SourceBottleStateEnum.Idl;
}
#endregion
#region
if (!TestMode && (i == sampleBottle.MaterialDoseFlowList.Count - 1 || sampleBottle.MaterialDoseFlowList[i+1].FunctionFlowType != FunctionTypeEnum.))
{
//最后一个加样或者下一个加样不是固体,则取回目标瓶到开盖位
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);//开门
await FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
Task task1 = labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0); //关门
Task task2 = FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
await Task.WhenAll(task1, task2);
await SetObstructFlag("四轴机械手运行中", false);
}
#endregion
}
else if (addSample.FunctionFlowType == FunctionTypeEnum.)
{
#region
// 筛选40mL原液工装并转换为SourceLiquidBottleBoxModel类型
var targetBoxAndBottle = workService.ProjectPro.FixtureCacheArea
.Where(b => b.FixtureType == BoxTypeEnum._40mL原液工装)
.OfType<SourceLiquidBottleBoxModel>()
.SelectMany(box => box.SourceLiquidBottleCollection
.Select(bottle => new { Box = box, Bottle = bottle }))
.FirstOrDefault(item => !string.IsNullOrEmpty(item.Bottle.SourceLiquidName) && item.Bottle.SourceLiquidName.Equals(addSample.UseMaterialName) && item.Bottle.RemainVolume > 3);
var sourceLiquidBox = targetBoxAndBottle?.Box;
var sourceBottle = targetBoxAndBottle?.Bottle;
if (sourceBottle is null)
{
Logger.LogError($"找不到{sampleBox.BoxId_inDosingStation}-{sampleBottle.PosId_InBox}需要的{addSample.UseMaterialName}液体");
continue;
}
sourceBottle.SourceLiquidBottleState = SourceBottleStateEnum.Using;
if (!IsMotherLiquidInMachine)
{
await SetObstructFlag("四轴机械手运行中", true);
await FourAxisTakeLiquidBottle(_cts.Token, (int)BoxAreaEnum._托盘存放平台, sourceLiquidBox.BoxId_inDosingStation, sourceBottle.PosId_InBox, sourceBottle);
if (string.IsNullOrEmpty(sourceBottle.SNCode))
{
await FourAxisGoToScannPos_liquid(_cts.Token, 1, sourceBottle, null);
}
await FourAxisPutLiquidBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sourceBottle);
await SetObstructFlag("四轴机械手运行中", false);
await OpenBottleLid(_cts.Token, sourceBottle, null);
}
else
{
//说明母液在开盖位,则开假盖子
await OpenCloseBottleFakeCap(_cts.Token,isOpen:true, sourceBottle,null);
}
IsMotherLiquidInMachine = false;
#endregion
#region
await XZ_TakeTip_Absorb_Dispense_DiscardTip(_cts.Token, addSample.UseMaterialName, addSample.TargetVolume, sourceBottle, sampleBottle);
//更新原液瓶剩余量
sourceBottle.RemainVolume -= addSample.TargetVolume / 1000;
addSample.IsDoseFinish = true;
#endregion
#region
if (sourceBottle != null)
{
//判断是不是最后一个母液,如果是的话判断下一瓶是不是用的该母液
bool IsLastLiquid = true;
for (int j = i + 1; j < sampleBottle.MaterialDoseFlowList.Count; j++)
{
if (sampleBottle.MaterialDoseFlowList[j].FunctionFlowType == FunctionTypeEnum.)
{
IsLastLiquid = false;
IsMotherLiquidInMachine = sampleBottle.MaterialDoseFlowList[j].UseMaterialName.Equals(sourceBottle.SourceLiquidName);
break;
}
}
if (IsLastLiquid && samplebottleNext != null)
{
var nextMotherLiquid = samplebottleNext.MaterialDoseFlowList.FirstOrDefault(s => s.FunctionFlowType == FunctionTypeEnum.);
IsMotherLiquidInMachine = nextMotherLiquid != null && nextMotherLiquid.UseMaterialName.Equals(sourceBottle.SourceLiquidName);
if (sourceBottle.RemainVolume < 3)
{
IsMotherLiquidInMachine = false;
}
}
//四轴机械手取回原液瓶 放到托盘存放平台
//关盖
if (!IsMotherLiquidInMachine)
{
await CloseBottleLid(_cts.Token, sourceBottle, null);
if (!TestMode)
{
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
}
await SetObstructFlag("四轴机械手运行中", true);
await FourAxisTakeLiquidBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sourceBottle);
await FourAxisPutLiquidBottle(_cts.Token, (int)BoxAreaEnum._托盘存放平台, sourceLiquidBox.BoxId_inDosingStation, sourceBottle.PosId_InBox, sourceBottle);
await SetObstructFlag("四轴机械手运行中", false);
}
else
{
//说明下一瓶还需要用,关假盖子
await OpenCloseBottleFakeCap(_cts.Token, isOpen: false, sourceBottle, null);
}
sourceBottle.SourceLiquidBottleState = SourceBottleStateEnum.Idl;
}
#endregion
}
else
{
//震荡摇匀
await CloseBottleLid(_cts.Token, null, sampleBottle);
await ShakeSampleBottle(_cts.Token, sampleBottle);
if (i != sampleBottle.MaterialDoseFlowList.Count - 1)
{
//不是最后一次摇匀,需要开盖
await OpenBottleLid(_cts.Token, null, sampleBottle);
}
else
{
//最后一次摇匀,则需要标志下已经关盖了
SampleHasOpened = true;
}
}
}
sampleBottle.bDoseFinish = true;
//关盖震荡摇匀并放回
#region
if (!SampleHasOpened)
{
await CloseBottleLid(_cts.Token, null, sampleBottle);
}
if (!TestMode)
{
while (await ReadObstructFlag("四轴机械手运行中") || await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
}
var isShakeMix = await dataAccessService.LoadEntityAsync<Setting>(s => s.Key.Equals("IsShakeMix") && s.Group.Equals("Setting"));
if (isShakeMix != null && !isShakeMix.Context.Equals("0"))
{
await SetObstructFlag("四轴机械手运行中", true);
await ShakeSampleBottle(_cts.Token, sampleBottle);
}
await FourAxisTakeSampleBottle(_cts.Token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
await FourAxisPutSampleBottle(_cts.Token, (int)BoxAreaEnum._托盘存放平台, sampleBox.BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
await SetObstructFlag("四轴机械手运行中", false);
#endregion
return (IsPowderInMachine, IsMotherLiquidInMachine);
}
#endregion
protected override void LoadServices()
{
base.LoadServices();//复用父类通用逻辑 + 子类扩展
appConfigService = this.CoreService.GetServiceInstance<AppConfigService>();
labxService = this.CoreService.GetServiceInstance<LabxService>();
preWeight = this.CoreService.GetServiceInstance<WeightService_Ts02>(DeviceNames.PreWeight.ToString());
scannerService = this.CoreService.GetServiceInstance<ScannerService>(DeviceNames.Scanner.ToString());
scannerService_Powder = this.CoreService.GetServiceInstance<ScannerService>(DeviceNames.Scanner_Powder.ToString());
pipetteService_1ml = this.CoreService.GetServiceInstance<PipetteService>(DeviceNames.Pipette_Dose_1ml.ToString());
this._httpClientFactory = this.CoreService.GetServiceInstance<IHttpClientFactory>();
if (this.ModbusClient != null)
{
//清除信号
}
this.workService.PrepareUploadBox += WorkService_PrepareUploadBox;
this.workService.UpdateBoxInfo_BS += WorkService_UpdateBoxInfo_BS;
}
protected override void LoadDatas()
{
base.LoadDatas();
InitialData();
}
private async Task InitialStationControlState()
{
if (this.StationProp.cancellationToken != null)
this.StationProp.cancellationToken.Cancel();
this.StationProp.cancellationToken = new CancellationTokenSource();
this.StationProp.ManualResetEvent = new ManualResetEvent(true);
await SetObstructFlag("传送平台收到准备上料信号", false);
await SetObstructFlag("四轴机械手运行中", false);
await SetObstructFlag("四轴机械手正在使用传送平台", false);
_currentDoseFlow = null;
_currentUseSourceLiquidBottle = null;
_currentUsePowderBottle = null;
}
private async Task InitialProjectProState()
{
for (int i = 0; i < workService.ProjectPro.FixtureCacheArea.Count; i++)
{
if (workService.ProjectPro.FixtureCacheArea[i] is SampleBottleBoxModel)
{
SampleBottleBoxModel samplebottleBox = workService.ProjectPro.FixtureCacheArea[i] as SampleBottleBoxModel;
samplebottleBox.IsDoseFinish = false;
samplebottleBox.IsEmpty = false;
samplebottleBox.IsUseFinsh = false;
for (int j = 0; j < samplebottleBox.SampleBottleList.Count; j++)
{
samplebottleBox.SampleBottleList[j].SNCode = string.Empty;
samplebottleBox.SampleBottleList[j].bDoseFinish = false;
samplebottleBox.SampleBottleList[j].SampleBottleLidState = SampleBottleLidStateEnum.Close;
samplebottleBox.SampleBottleList[j].SampleBoxState = SampleBottleStateEnum.Empty;
foreach (var doseflow in samplebottleBox.SampleBottleList[j].MaterialDoseFlowList)
{
doseflow.IsDoseFinish = false;
doseflow.ActualVolume = 0;
}
}
}
else if (workService.ProjectPro.FixtureCacheArea[i] is SourceLiquidBottleBoxModel)
{
SourceLiquidBottleBoxModel sourceliquidbox = workService.ProjectPro.FixtureCacheArea[i] as SourceLiquidBottleBoxModel;
sourceliquidbox.IsDoseFinish = false;
for (int j = 0; j < sourceliquidbox.SourceLiquidBottleCollection.Count; j++)
{
sourceliquidbox.SourceLiquidBottleCollection[j].SNCode = string.Empty;
sourceliquidbox.SourceLiquidBottleCollection[j].LiquidBottleLidState = SourceBottleLidStateEnum.Close;
sourceliquidbox.SourceLiquidBottleCollection[j].SourceLiquidBottleState = SourceBottleStateEnum.Idl;
sourceliquidbox.SourceLiquidBottleCollection[j].RemainVolume = sourceliquidbox.SourceLiquidBottleCollection[j].OriginVolume;
}
}
else
{
workService.ProjectPro.FixtureCacheArea[i].IsDoseFinish = false;
workService.ProjectPro.FixtureCacheArea[i].IsUseFinsh = false;
workService.ProjectPro.FixtureCacheArea[i].IsEmpty = true;
}
}
for (int i = 0; i < workService.ProjectPro.PowderHeaderCacheArea.Count; i++)
{
workService.ProjectPro.PowderHeaderCacheArea[i].SourcePowderBottleState = SourceBottleStateEnum.Idl;
}
}
public ushort GetInitStatus()
{
if (TestMode)
{
return (ushort)3;
}
return this.ModbusClient.Command.ReadValue<ushort>(PlcPoints_MaterialDose.R_PLCInitialStatus);
}
private void InitialData()
{
//加载传送平台 7个工装
workService.ProjectPro.TransferArea.Clear();
for (int i = 0; i < 7; i++)
{
workService.ProjectPro.TransferArea.Add(new BaseBottleBox()
{
BoxId_inDoseDnload = i + 1,
BoxId_inDoseUpload = i + 1,
IsEmpty = true,
IsDoseFinish = false,
IsUseFinsh = false,
BoxArea = BoxAreaEnum._手套箱传送平台,
});
}
workService.ProjectPro.FixtureCacheArea.Clear();
//加载工装暂存区域 8个工装
for (int i = 0; i < 8; i++)
{
workService.ProjectPro.FixtureCacheArea.Add(new BaseBottleBox()
{
//FixtureType = BoxTypeEnum._40mL原液工装,
BoxId_inDosingStation = i + 1,
BoxArea = BoxAreaEnum._托盘存放平台,
IsEmpty = true,
IsDoseFinish = false,
IsUseFinsh = false,
});
}
workService.ProjectPro.PowderHeaderCacheArea.Clear();
//加载粉末加样头暂存区域 10个位置
for (int i = 0; i < 10; i++)
{
workService.ProjectPro.PowderHeaderCacheArea.Add(
new SourcePowderBottleModel()
{
HaveBottle = false,
Pos_InDosePowderHC = i + 1,
SNCode = string.Empty,
PowderBottleType = PowderBottleTypeEnum._125mL,
SourcePowderBottleState = SourceBottleStateEnum.Idl,
OriginWeight =0,
});
}
// 3个tip头工装
workService.ProjectPro.TipHeadArea.Clear();
for (int i = 0; i < 3; i++)
{
TipBoxModel tipBox = new TipBoxModel()
{
TipType = i switch
{
0 => TipTypeEnum._1000UL,
1 => TipTypeEnum._300UL,
2 => TipTypeEnum._50UL,
_ => TipTypeEnum._300UL
},
HaveBox = false,
UseIndex = 0,
BoxId_inDosingStation = i + 1,
IsEmpty = true, // 初始无工装(可根据需求调整)
};
// 添加96个可用Tip头避免序列化空引用
for (int j = 0; j < 8 * 12; j++)
{
tipBox.TipItems.Add(new TipHeadItem { IsAvailable = false, UseIndex = j + 1 });
}
workService.ProjectPro.TipHeadArea.Add(tipBox);
}
_currentDoseFlow = null;
_currentUseSourceLiquidBottle = null;
_currentUsePowderBottle = null;
}
private bool bInitial_Z = false;
private bool bInitial = false;
private ushort lastInitStatus = 999;
private async Task InitDown()
{
var point1 = this.ModbusClient.Command.ReadValue<ushort>(PlcPoints_MaterialDose.R_PLCInitialStatus);
if (point1 != lastInitStatus)
{
lastInitStatus = point1;
if (lastInitStatus != 999 && point1 == 3) //不是开机第一次读取
{
_ = Task.Run(async () =>
{
await ChangeDeviceStatus(Entities.DeviceStatus.Idel);
WeakReferenceMessenger.Default.Send(new DesktopAlertMessage() { Content = "设备已完成初始化" });
});
}
}
}
/// <summary>
/// 重写每间隔200ms,就会进入这个函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected override async void ModbusClientBaseOnScannedEvent(object sender, EventArgs e)
{
base.ModbusClientBaseOnScannedEvent(sender, e);
this.StationProp.ManualResetEvent.WaitOne(); //暂停标志
await InitDown();
//if (!workService.ProjectPro.bNoUseBS && (TaskBoxFromTransferPlateTask == null || TaskBoxFromTransferPlateTask.IsCanceled || TaskBoxFromTransferPlateTask.IsFaulted || TaskBoxFromTransferPlateTask.IsCompleted))
//{
// TaskBoxFromTransferPlateTask = Task.Run(async () =>
// {
// await UploadBoxFromTransferPlateToHCBox(this.StationProp.cancellationToken.Token);
// });
//}
//if (!workService.ProjectPro.bNoUseBS && (DownloadBoxToTransferPlateTask == null || DownloadBoxToTransferPlateTask.IsCanceled || DownloadBoxToTransferPlateTask.IsFaulted || DownloadBoxToTransferPlateTask.IsCompleted))
//{
// DownloadBoxToTransferPlateTask = Task.Run(async () =>
// {
// await DownloadFixtueBox(this.StationProp.cancellationToken.Token);
// });
//}
#region 1ml移液枪初始化
//1ml移液枪Z轴初始化
if (ReadScannedValueAsync_FourAxis(PlcPoints_MaterialDose.R_1mlPipetteZInit).Result == 1 && !bInitial_Z) //1ml移液枪Z轴初始化
{
bInitial_Z = true;
await GunZAxisInit_M1(DeviceNames.Pipette_Dose_1ml_1, pipetteService_1ml);
await GunZAxisInit_M1(DeviceNames.Pipette_Dose_1ml_2, pipetteService_1ml);
await GunZAxisInit_M1(DeviceNames.Pipette_Dose_1ml_3, pipetteService_1ml);
await GunZAxisInit_M1(DeviceNames.Pipette_Dose_1ml_4, pipetteService_1ml);
//Z轴初始化成功回复给机械手
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_1mlPipetteZInitResult, 1);
//等待PLC清除Z初始化信号
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_1mlPipetteZInit, 0, this.StationProp.cancellationToken.Token);
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_1mlPipetteZInitResult, 0); //清除信号
bInitial_Z = false;
}
//1ml移液枪初始化
if (ReadScannedValueAsync_FourAxis(PlcPoints_MaterialDose.R_1mlPipetteInit).Result == 1 && !bInitial) //1ml移液枪初始化
{
bInitial = true;
await GunAllInit_M1(DeviceNames.Pipette_Dose_1ml_1, pipetteService_1ml);
await GunAllInit_M1(DeviceNames.Pipette_Dose_1ml_2, pipetteService_1ml);
await GunAllInit_M1(DeviceNames.Pipette_Dose_1ml_3, pipetteService_1ml);
await GunAllInit_M1(DeviceNames.Pipette_Dose_1ml_4, pipetteService_1ml);
//Z轴初始化成功回复给机械手
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_1mlPipetteInitResult, 1);
//等待PLC清除Z初始化信号
await WaitForActionFinishAsync_FourAxis(PlcPoints_MaterialDose.R_1mlPipetteInit, 0, this.StationProp.cancellationToken.Token);
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_1mlPipetteInitResult, 0); //清除信号
bInitial = false;
}
#endregion
//if (!this.StationProp.bStartButtonTrigger) //没有收到启动信号或者没有按下启动按钮
//{
// //若按下复位按钮,则清除所有状态
// if (this.StationProp.bResetButtonTrigger) //按下复位按钮
// {
// this.StationProp.bResetButtonTrigger = false;
// await Application.Current.Dispatcher.InvokeAsync(async () =>
// {
// await DialogManager.ShowDialogAsync(
// owner: Application.Current.MainWindow, // 尽量传MainWindow作为Owner避免弹窗无归属
// message: "投料站复位中,正在清除状态,请稍等...\r\n这需要几秒钟时间",
// operation: async () =>
// {
// await InitialStationControlState();
// await InitialProjectProState();
// });
// });
// //await InitialStationControlState();
// //await InitialProjectProState();
// }
// return;
//}
//else //按下启动按钮
//{
// if (this.StationProp.bStopButtonTrigger) //收到BS的停止信号或者按下停止按钮
// {
// this.StationProp.bStopButtonTrigger = false;
// this.StationProp.cancellationToken.Cancel();
// TimeSpan totalCt = this.StationProp.CTWatch.Elapsed;
// workService.ProjectPro.Dose_CT = $"{totalCt.Hours}时{totalCt.Minutes}分{totalCt.Seconds}秒";
// this.StationProp.CTWatch.Reset();
// //await magneticStirService.StirringSwitchContriol(TimeSpan.FromSeconds(3), false);
// //await ClearReactBottleAndRotaterState();
// this.StationProp.bStartButtonTrigger = false;
// this.StationProp.bResetButtonTrigger = false;
// this.StationProp.bRunFinish = false;
// await InitialStationControlState();
// return;
// }
// if (this.StationProp.bRunFinish) //如果配置完成了,就不再执行了
// {
// this.StationProp.bRunFinish = false;
// //this.StationProp.cancellationToken.Cancel();
// TimeSpan totalCt = this.StationProp.CTWatch.Elapsed;
// workService.ProjectPro.Dose_CT = $"{totalCt.Hours}时{totalCt.Minutes}分{totalCt.Seconds}秒";
// this.StationProp.CTWatch.Reset();
// WeakReferenceMessenger.Default.Send(new SingleBoolMessage(true));
// WeakReferenceMessenger.Default.Send(new SingleBoolPeifangMessage(true));
// this.StationProp.bStartButtonTrigger = false;
// this.StationProp.bStopButtonTrigger = false;
// this.StationProp.bResetButtonTrigger = false;
// //await InitialStationControlState();
// return;
// }
//}
//切换投料物
//await SwitchCurrentDoseFlow(this.StationProp.cancellationToken.Token);
}
/// <summary>
/// 收到BS 告诉的准备上工装信息 ,触发事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="NotImplementedException"></exception>
private async void WorkService_PrepareUploadBox(object sender, EventArgs e)
{
while (await ReadObstructFlag("四轴机械手正在使用传送平台")
|| await ReadObstructFlag("传送平台收到准备上料信号"))
{
await Task.Delay(300);
}
await SetObstructFlag("传送平台收到准备上料信号", true);
//传送平台到过渡舱外准备上载具
await TransferUploadBox(this.StationProp.cancellationToken.Token);
//回复BS准备好上料
//_httpClientFactory.
}
/// <summary>
/// BS放好载具到传送平台上,触发更新事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void WorkService_UpdateBoxInfo_BS(object sender, BaseBottleBox e)
{
try
{
//收到BS放工装完成信号
//先让PLC将传送平台运行到设备内部
await TransferToDeviceInner(this.StationProp.cancellationToken.Token);
await SetObstructFlag("传送平台收到准备上料信号", false);
//读取BS告诉CS的工装在传动平台的位置
int pos = e.BoxId_inDoseUpload;
BaseBottleBox fixture = workService.ProjectPro.TransferArea.FirstOrDefault(c => c.BoxId_inDoseUpload == pos);
fixture = File_Operator.DeepCopy(e);
//BS更新序列后
switch (e.FixtureType)
{
case BoxTypeEnum._40mL原液工装:
SourceLiquidBottleBoxModel sourceLiquidBottleBox = e as SourceLiquidBottleBoxModel;
sourceLiquidBottleBox.FixtureType = BoxTypeEnum._40mL原液工装;
for (int i = 0; i < sourceLiquidBottleBox.SourceLiquidBottleCollection.Count; i++)
{
sourceLiquidBottleBox.SourceLiquidBottleCollection[i].BoxSNCode = sourceLiquidBottleBox.BoxSNCode;
sourceLiquidBottleBox.SourceLiquidBottleCollection[i].LiquidBottleLidState = SourceBottleLidStateEnum.Close;
sourceLiquidBottleBox.SourceLiquidBottleCollection[i].SNCode = string.Empty;
sourceLiquidBottleBox.SourceLiquidBottleCollection[i].HaveBottle = true;
}
//将工装信息更新到传送平台对应位置
fixture = File_Operator.DeepCopy(sourceLiquidBottleBox);
fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
break;
case BoxTypeEnum._12mL样品工装:
SampleBottleBoxModel sampleBottleBox = e as SampleBottleBoxModel;
sampleBottleBox.SampleBottleType = SampleBottleTypeEnum._12mL;
for (int i = 0; i < sampleBottleBox.SampleBottleList.Count; i++)
{
sampleBottleBox.SampleBottleList[i].SampleBottleType = SampleBottleTypeEnum._12mL;
sampleBottleBox.SampleBottleList[i].bDoseFinish = false;
sampleBottleBox.SampleBottleList[i].HaveBottle = true;
sampleBottleBox.SampleBottleList[i].SampleBottleLidState = SampleBottleLidStateEnum.Close;
sampleBottleBox.SampleBottleList[i].SNCode = string.Empty;
sampleBottleBox.SampleBottleList[i].BoxSNCode = sampleBottleBox.BoxSNCode;
foreach (var doseflow in sampleBottleBox.SampleBottleList[i].MaterialDoseFlowList)
{
doseflow.IsDoseFinish = false;
}
}
//将工装信息更新到传送平台对应位置
fixture = File_Operator.DeepCopy(sampleBottleBox);
fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
break;
case BoxTypeEnum._5mL样品工装:
SampleBottleBoxModel sampleBottleBox_5 = e as SampleBottleBoxModel;
sampleBottleBox_5.SampleBottleType = SampleBottleTypeEnum._5mL;
for (int i = 0; i < sampleBottleBox_5.SampleBottleList.Count; i++)
{
sampleBottleBox_5.SampleBottleList[i].SampleBottleType = SampleBottleTypeEnum._5mL;
sampleBottleBox_5.SampleBottleList[i].bDoseFinish = false;
sampleBottleBox_5.SampleBottleList[i].HaveBottle = true;
sampleBottleBox_5.SampleBottleList[i].SampleBottleLidState = SampleBottleLidStateEnum.Close;
sampleBottleBox_5.SampleBottleList[i].SNCode = string.Empty;
sampleBottleBox_5.SampleBottleList[i].BoxSNCode = sampleBottleBox_5.BoxSNCode;
foreach (var doseflow in sampleBottleBox_5.SampleBottleList[i].MaterialDoseFlowList)
{
doseflow.IsDoseFinish = false;
}
}
//将工装信息更新到传送平台对应位置
fixture = File_Operator.DeepCopy(sampleBottleBox_5);
fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
break;
case BoxTypeEnum._16mL粉末瓶工装:
SourcePowderBottleBoxModel powderbox = e as SourcePowderBottleBoxModel;
powderbox.PowderBottleType = PowderBottleTypeEnum._16mL;
for (int i = 0; i < powderbox.SourcePowderBottleCollection.Count; i++)
{
powderbox.SourcePowderBottleCollection[i].PowderBottleType = PowderBottleTypeEnum._16mL;
powderbox.SourcePowderBottleCollection[i].BoxSNCode = powderbox.BoxSNCode;
powderbox.SourcePowderBottleCollection[i].SNCode = string.Empty;
powderbox.SourcePowderBottleCollection[i].HaveBottle = true;
}
//将工装信息更新到传送平台对应位置
fixture = File_Operator.DeepCopy(powderbox);
fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
break;
case BoxTypeEnum._125mL粉末瓶工装:
SourcePowderBottleBoxModel powderbox_125 = e as SourcePowderBottleBoxModel;
powderbox_125.PowderBottleType = PowderBottleTypeEnum._125mL;
for (int i = 0; i < powderbox_125.SourcePowderBottleCollection.Count; i++)
{
powderbox_125.SourcePowderBottleCollection[i].PowderBottleType = PowderBottleTypeEnum._125mL;
powderbox_125.SourcePowderBottleCollection[i].BoxSNCode = powderbox_125.BoxSNCode;
powderbox_125.SourcePowderBottleCollection[i].SNCode = string.Empty;
powderbox_125.SourcePowderBottleCollection[i].HaveBottle = true;
}
fixture = File_Operator.DeepCopy(powderbox_125);
fixture.IsEmpty = false; fixture.IsUseFinsh = false; fixture.IsDoseFinish = false;
break;
case BoxTypeEnum._50uLTip头工装:
TipBoxModel tipBoxModel = e as TipBoxModel;
tipBoxModel.TipType = TipTypeEnum._50UL;
tipBoxModel.BoxId_inDosingStation = pos;
tipBoxModel.HaveBox = true;
for (var i = 0; i < tipBoxModel.TipItems.Count; i++)
{
tipBoxModel.TipItems[i].IsAvailable = true;
}
fixture = File_Operator.DeepCopy(tipBoxModel);
fixture.IsEmpty = false; fixture.IsUseFinsh = false;
break;
case BoxTypeEnum._300uLTip头工装:
TipBoxModel tipBoxModel_300 = e as TipBoxModel;
tipBoxModel_300.TipType = TipTypeEnum._300UL;
tipBoxModel_300.BoxId_inDosingStation = pos;
tipBoxModel_300.HaveBox = true;
for (var i = 0; i < tipBoxModel_300.TipItems.Count; i++)
{
tipBoxModel_300.TipItems[i].IsAvailable = true;
}
fixture = File_Operator.DeepCopy(tipBoxModel_300);
fixture.IsEmpty = false; fixture.IsUseFinsh = false;
break;
case BoxTypeEnum._1000uLTip头工装:
TipBoxModel tipBoxModel_1000 = e as TipBoxModel;
tipBoxModel_1000.TipType = TipTypeEnum._1000UL;
tipBoxModel_1000.BoxId_inDosingStation = pos;
tipBoxModel_1000.HaveBox = true;
for (var i = 0; i < tipBoxModel_1000.TipItems.Count; i++)
{
tipBoxModel_1000.TipItems[i].IsAvailable = true;
}
fixture = File_Operator.DeepCopy(tipBoxModel_1000);
fixture.IsEmpty = false; fixture.IsUseFinsh = false;
break;
}
}
catch (Exception)
{
}
}
private async Task SwitchCurrentDoseFlowEx(CancellationToken token)
{
try
{
if (this.StationProp.bRunFinish) return;
var FixtureCacheAreas = workService.ProjectPro.FixtureCacheArea.Where(b => b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装);
if (_currentDoseFlow == null)
{
//找到第一个没有配置完成的样品工装
BaseBottleBox fixturePosPro = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(b => !b.IsDoseFinish && !b.IsEmpty && (b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装));
if (fixturePosPro == null) //所有治具工装配置完成
{
this.StationProp.bRunFinish = true; //当前工单配置完成
await RunFinishTaskBackSourceLiquidBottleOrCurrentUsePowderBottle(_currentDoseFlow, token);
_currentDoseFlow = null;
return;
}
else
{
SampleBottleBoxModel sampleBox = fixturePosPro as SampleBottleBoxModel;
//找到工装中 第一个没有配置完成的样品瓶子
SampleBottleModel samplebottle = sampleBox.SampleBottleList.FirstOrDefault(f => f.HaveBottle && !f.bDoseFinish);
if (samplebottle == null)
{
sampleBox.IsDoseFinish = true;
_currentDoseFlow = null;
return;
}
else
{
if (samplebottle.MaterialDoseFlowList.Count == 0)
{
samplebottle.bDoseFinish = true;
_currentDoseFlow = null;
return;
}
MaterialDoseFunctionFlow doseflow = samplebottle.MaterialDoseFlowList.FirstOrDefault(f => !f.IsDoseFinish && f.TargetVolume > 0);
if (doseflow != null)
{
_currentDoseFlow = doseflow;
if (DoseTask_BasedOnCurrentDoseFlow == null || DoseTask_BasedOnCurrentDoseFlow.IsFaulted || DoseTask_BasedOnCurrentDoseFlow.IsCanceled || DoseTask_BasedOnCurrentDoseFlow.IsCompleted)
{
DoseTask_BasedOnCurrentDoseFlow = Task.Run(async () =>
{
await OneMaterialDose(token);
});
}
}
else
{
samplebottle.bDoseFinish = true;
_currentDoseFlow = null;
}
}
}
}
}
catch (Exception)
{
throw;
}
finally
{
await Task.Delay(2000);
}
}
/// <summary>
/// 切换当前投料流程
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
private async Task SwitchCurrentDoseFlow(CancellationToken token)
{
try
{
if (this.StationProp.bRunFinish) return;
if (_currentDoseFlow == null)
{
//找到第一个没有配置完成的样品工装
BaseBottleBox fixturePosPro = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(b => !b.IsDoseFinish && !b.IsEmpty && (b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装));
if (fixturePosPro == null) //所有治具工装配置完成
{
this.StationProp.bRunFinish = true; //当前工单配置完成
await RunFinishTaskBackSourceLiquidBottleOrCurrentUsePowderBottle(_currentDoseFlow, token);
_currentDoseFlow = null;
return;
}
else
{
SampleBottleBoxModel sampleBox = fixturePosPro as SampleBottleBoxModel;
//找到工装中 第一个没有配置完成的样品瓶子
SampleBottleModel samplebottle = sampleBox.SampleBottleList.FirstOrDefault(f => f.HaveBottle && !f.bDoseFinish);
if (samplebottle == null)
{
sampleBox.IsDoseFinish = true;
_currentDoseFlow = null;
return;
}
else
{
if (samplebottle.MaterialDoseFlowList.Count == 0)
{
samplebottle.bDoseFinish = true;
_currentDoseFlow = null;
return;
}
MaterialDoseFunctionFlow doseflow = samplebottle.MaterialDoseFlowList.FirstOrDefault(f => !f.IsDoseFinish && f.TargetVolume > 0);
if (doseflow != null)
{
_currentDoseFlow = doseflow;
if (DoseTask_BasedOnCurrentDoseFlow == null || DoseTask_BasedOnCurrentDoseFlow.IsFaulted || DoseTask_BasedOnCurrentDoseFlow.IsCanceled || DoseTask_BasedOnCurrentDoseFlow.IsCompleted)
{
DoseTask_BasedOnCurrentDoseFlow = Task.Run(async () =>
{
await OneMaterialDose(token);
});
}
}
else
{
samplebottle.bDoseFinish = true;
_currentDoseFlow = null;
}
}
}
}
}
catch (Exception)
{
throw;
}
finally
{
await Task.Delay(2000);
}
}
/// <summary>
/// 从传动平台取工装到 治具缓存区 线程
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
private async Task UploadBoxFromTransferPlateToHCBox(CancellationToken token)
{
while (true)
{
if (workService.ProjectPro.bNoUseBS) break;
if (token.IsCancellationRequested) break;
//从传送平台取样品工装到工装缓存区
if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._5mL样品工装 || f.FixtureType == BoxTypeEnum._12mL样品工装))
&& workService.ProjectPro.FixtureCacheArea.Any(a => a.IsEmpty && a.BoxId_inDosingStation != 1 && a.BoxId_inDosingStation != 5)) //治具缓存区的 位置1和位置5 只给放原液瓶工装
{
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台")
|| await ReadObstructFlag("传送平台收到准备上料信号"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
await SetObstructFlag("四轴机械手正在使用传送平台", true);
//找到可以搬运的样品工装
BaseBottleBox samplefixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._5mL样品工装 || f.FixtureType == BoxTypeEnum._12mL样品工装));
await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, samplefixture.FixtureType, (ushort)samplefixture.BoxId_inDoseUpload, token);
await SetObstructFlag("四轴机械手正在使用传送平台", false);
//找到可以放置的工装缓存位置
BaseBottleBox aimfixture = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(a => a.IsEmpty && a.BoxId_inDosingStation != 1 && a.BoxId_inDosingStation != 5);
await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, aimfixture.FixtureType, (ushort)aimfixture.BoxId_inDosingStation, token);
//更新信息
aimfixture.IsEmpty = false;
aimfixture.FixtureType = samplefixture.FixtureType;
aimfixture = File_Operator.DeepCopy(samplefixture);
aimfixture.IsDoseFinish = false; aimfixture.IsUseFinsh = false;
samplefixture.IsEmpty = true; samplefixture = null;
await SetObstructFlag("四轴机械手运行中", false);
}
//从传送平台取原液工装到工装缓存区
else if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && f.FixtureType == BoxTypeEnum._40mL原液工装)
&& workService.ProjectPro.FixtureCacheArea.Any(a => a.IsEmpty))
{
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台")
|| await ReadObstructFlag("传送平台收到准备上料信号"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
await SetObstructFlag("四轴机械手正在使用传送平台", true);
//找到可以搬运的原液工装
BaseBottleBox liquidfixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty && f.FixtureType == BoxTypeEnum._40mL原液工装);
await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, liquidfixture.FixtureType, (ushort)liquidfixture.BoxId_inDoseUpload, token);
await SetObstructFlag("四轴机械手正在使用传送平台", false);
//找到可以放置的工装缓存位置
BaseBottleBox aimfixture = workService.ProjectPro.FixtureCacheArea.FirstOrDefault(a => a.IsEmpty);
await FourAxisPutBox((int)BoxAreaEnum._托盘存放平台, aimfixture.FixtureType, (ushort)aimfixture.BoxId_inDosingStation, token);
//更新信息
aimfixture.IsEmpty = false;
aimfixture.FixtureType = liquidfixture.FixtureType;
aimfixture = File_Operator.DeepCopy(liquidfixture);
aimfixture.IsDoseFinish = false;
aimfixture.IsUseFinsh = false;
liquidfixture.IsEmpty = true; liquidfixture = null;
await SetObstructFlag("四轴机械手运行中", false);
}
//从传送平台的粉末工装中 一个一个取粉末瓶 ---扫码---称重---放到缓存料架上
else if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装))
&& workService.ProjectPro.PowderHeaderCacheArea.Any(f => !f.HaveBottle))
{
BaseBottleBox powderfixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._16mL粉末瓶工装 || f.FixtureType == BoxTypeEnum._125mL粉末瓶工装));
SourcePowderBottleBoxModel powderBox = powderfixture as SourcePowderBottleBoxModel;
for (int i = 0; i < powderBox.SourcePowderBottleCollection.Count; i++)
{
SourcePowderBottleModel powderbottle = powderBox.SourcePowderBottleCollection[i];
if (powderbottle.HaveBottle)
{
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台")
|| await ReadObstructFlag("传送平台收到准备上料信号"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
await SetObstructFlag("四轴机械手正在使用传送平台", true);
//四轴机械手从传送平台取粉末加样头
await FourAxisTakePowderHeader((int)BoxAreaEnum._手套箱传送平台, powderfixture.BoxId_inDoseUpload, powderbottle.PosId_InBox, powderBox.PowderBottleType, token);
//四轴机械手运行到扫码位置
await FourAxisGoToScannPos_powder(token, powderbottle);
await SetObstructFlag("四轴机械手正在使用传送平台", false);
//称重
await FourAxisPutPowderHeaderToPreWeight(token);
await preWeight.Peel();
double powderweight = await preWeight.ReadWeightValue();
powderbottle.OriginWeight = powderbottle.RemainWeight = powderweight;
await WriteCommandAsync_FourAxis(PlcPoints_MaterialDose.W_Robot_PreWeightFinish, 1);//回复预称重完成
//四轴机械手放粉末加样头到10个缓存区
SourcePowderBottleModel aimpowderbottle_inhc = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(f => !f.HaveBottle);
powderbottle.Pos_InDosePowderHC = aimpowderbottle_inhc.Pos_InDosePowderHC;
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, aimpowderbottle_inhc.Pos_InDosePowderHC, powderBox.PowderBottleType, token);
//更新信息
aimpowderbottle_inhc = File_Operator.DeepCopy(powderbottle);
aimpowderbottle_inhc.HaveBottle = true;
powderbottle.HaveBottle = false;
await SetObstructFlag("四轴机械手运行中", false);
}
}
}
//从传送平台取Tip头工装放到投料站中
else if (workService.ProjectPro.TransferArea.Any(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._50uLTip头工装 || f.FixtureType == BoxTypeEnum._300uLTip头工装 || f.FixtureType == BoxTypeEnum._1000uLTip头工装))
&& workService.ProjectPro.TipHeadArea.Any(f => !f.HaveBox))
{
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台")
|| await ReadObstructFlag("传送平台收到准备上料信号"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
await SetObstructFlag("四轴机械手正在使用传送平台", true);
//找到可以搬运的Tip头工装
BaseBottleBox tipfixture = workService.ProjectPro.TransferArea.FirstOrDefault(f => !f.IsEmpty && (f.FixtureType == BoxTypeEnum._50uLTip头工装 || f.FixtureType == BoxTypeEnum._300uLTip头工装 || f.FixtureType == BoxTypeEnum._1000uLTip头工装));
await FourAxisTakeBox((int)BoxAreaEnum._手套箱传送平台, tipfixture.FixtureType, (ushort)tipfixture.BoxId_inDoseUpload, token);
await SetObstructFlag("四轴机械手正在使用传送平台", false);
//放到Tip缓存区域 1-3
TipBoxModel aimtipbox = workService.ProjectPro.TipHeadArea.FirstOrDefault(f => !f.HaveBox);
await FourAxisPutBox((int)BoxAreaEnum._Tip托盘存放平台, tipfixture.FixtureType, (ushort)aimtipbox.BoxId_inDosingStation, token);
//更新信息
aimtipbox.HaveBox = true; aimtipbox = File_Operator.DeepCopy(tipfixture as TipBoxModel);
if (tipfixture.FixtureType == BoxTypeEnum._50uLTip头工装)
{
aimtipbox.TipType = TipTypeEnum._50UL;
}
else if (tipfixture.FixtureType == BoxTypeEnum._300uLTip头工装)
{
aimtipbox.TipType = TipTypeEnum._300UL;
}
else if (tipfixture.FixtureType == BoxTypeEnum._1000uLTip头工装)
{
aimtipbox.TipType = TipTypeEnum._1000UL;
}
tipfixture.IsEmpty = true; tipfixture = null;
await SetObstructFlag("四轴机械手运行中", false);
}
else
{
if (!token.IsCancellationRequested)
await Task.Delay(2000);
}
}
}
/// <summary>
/// 从载具工装缓存区域 下载具到传送平台
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
private async Task DownloadFixtueBox(CancellationToken token)
{
while (true)
{
if (workService.ProjectPro.bNoUseBS) break;
if (token.IsCancellationRequested) break;
}
}
private async Task RunFinishTaskBackSourceLiquidBottleOrCurrentUsePowderBottle(MaterialDoseFunctionFlow flow, CancellationToken token)
{
#region
if (_currentUseSourceLiquidBottle != null && _currentUseSourceLiquidBottle.liquidbottle != null)
{
//四轴机械手取回原液瓶 放到托盘存放平台
//关盖
await CloseBottleLid(token, _currentUseSourceLiquidBottle.liquidbottle, null);
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
//四轴机械手取原液瓶
await FourAxisTakeLiquidBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, _currentUseSourceLiquidBottle.liquidbottle);
//四轴机械手放原液瓶到托盘存放平台
await FourAxisPutLiquidBottle(token, (int)BoxAreaEnum._托盘存放平台, _currentUseSourceLiquidBottle.liquidbottleFixture.BoxId_inDosingStation, _currentUseSourceLiquidBottle.liquidbottle.PosId_InBox, _currentUseSourceLiquidBottle.liquidbottle);
_currentUseSourceLiquidBottle = null;
await SetObstructFlag("四轴机械手运行中", false);
}
if (_currentUsePowderBottle != null)
{
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
//四轴机械手取回粉末瓶 放到托盘存放平台
await FourAxisTakePowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, _currentUsePowderBottle.PowderBottleType, token);
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, _currentUsePowderBottle.Pos_InDosePowderHC, _currentUsePowderBottle.PowderBottleType, token);
_currentUsePowderBottle = null;
await SetObstructFlag("四轴机械手运行中", false);
}
#endregion
}
private async Task GetCurrentUseSourceLiquidBottleOrCurrentUsePowderBottle(MaterialDoseFunctionFlow flow, CancellationToken token)
{
#region
//根据当前物料配置流程,搬运当前原液或者粉末瓶
if (_currentDoseFlow.FunctionFlowType == FunctionTypeEnum.)
{
if (_currentUseSourceLiquidBottle != null && _currentUseSourceLiquidBottle.liquidbottle != null)
{
//四轴机械手取回原液瓶 放到托盘存放平台
//关盖
await CloseBottleLid(token, _currentUseSourceLiquidBottle.liquidbottle, null);
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
//四轴机械手取原液瓶
await FourAxisTakeLiquidBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, _currentUseSourceLiquidBottle.liquidbottle);
//四轴机械手放原液瓶到托盘存放平台
await FourAxisPutLiquidBottle(token, (int)BoxAreaEnum._托盘存放平台, _currentUseSourceLiquidBottle.liquidbottleFixture.BoxId_inDosingStation, _currentUseSourceLiquidBottle.liquidbottle.PosId_InBox, _currentUseSourceLiquidBottle.liquidbottle);
_currentUseSourceLiquidBottle.liquidbottle.SourceLiquidBottleState = SourceBottleStateEnum.Idl;
_currentUseSourceLiquidBottle = null;
await SetObstructFlag("四轴机械手运行中", false);
}
//查找液体原料瓶
_currentUseSourceLiquidBottle = new UseLiquidBottle()
{
liquidbottleFixture = null,
liquidbottle = null,
};
_currentUseSourceLiquidBottle.liquidbottle = workService.ProjectPro.FixtureCacheArea.Where(pos => pos.FixtureType == BoxTypeEnum._40mL原液工装 && pos is SourceLiquidBottleBoxModel)
.Select(pos => (SourceLiquidBottleBoxModel)pos)
.SelectMany(box => box.SourceLiquidBottleCollection)
.FirstOrDefault(bottle => bottle.HaveBottle && bottle.SourceLiquidName.Equals(_currentDoseFlow.UseMaterialName) && bottle.RemainVolume > 2 && bottle.SourceLiquidBottleState == SourceBottleStateEnum.Idl);
if (_currentUseSourceLiquidBottle.liquidbottle == null) { } //跟BS要原液瓶
_currentUseSourceLiquidBottle.liquidbottleFixture = workService.ProjectPro.FixtureCacheArea
.Where(pos => pos is SourceLiquidBottleBoxModel
&& ((SourceLiquidBottleBoxModel)pos).SourceLiquidBottleCollection != null
&& ((SourceLiquidBottleBoxModel)pos).SourceLiquidBottleCollection.Contains(_currentUseSourceLiquidBottle.liquidbottle)).FirstOrDefault();
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
_currentUseSourceLiquidBottle.liquidbottle.SourceLiquidBottleState = SourceBottleStateEnum.Using;
//四轴机械手取原液瓶
await FourAxisTakeLiquidBottle(token, (int)BoxAreaEnum._托盘存放平台, _currentUseSourceLiquidBottle.liquidbottleFixture.BoxId_inDosingStation, _currentUseSourceLiquidBottle.liquidbottle.PosId_InBox, _currentUseSourceLiquidBottle.liquidbottle);
if (_currentUseSourceLiquidBottle.liquidbottle.SNCode.Equals(string.Empty))
{
await FourAxisGoToScannPos_liquid(token, 1, _currentUseSourceLiquidBottle.liquidbottle, null);
}
//四轴机械手放原液瓶到开关盖区域
await FourAxisPutLiquidBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, _currentUseSourceLiquidBottle.liquidbottle);
await SetObstructFlag("四轴机械手运行中", false);
//开盖
await OpenBottleLid(token, _currentUseSourceLiquidBottle.liquidbottle, null);
}
else if (_currentDoseFlow.FunctionFlowType == FunctionTypeEnum.)
{
if (_currentUsePowderBottle != null)
{
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
//四轴机械手取回粉末瓶 放到托盘存放平台
await FourAxisTakePowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, _currentUsePowderBottle.PowderBottleType, token);
await FourAxisPutPowderHeader((int)BoxAreaEnum._加样头存放平台, 1, _currentUsePowderBottle.Pos_InDosePowderHC, _currentUsePowderBottle.PowderBottleType, token);
_currentUsePowderBottle.SourcePowderBottleState = SourceBottleStateEnum.Idl;
_currentUsePowderBottle = null;
await SetObstructFlag("四轴机械手运行中", false);
}
//查找可用的粉末瓶
_currentUsePowderBottle = workService.ProjectPro.PowderHeaderCacheArea.FirstOrDefault(f => f.HaveBottle && f.SourcePowderName == _currentDoseFlow.UseMaterialName && f.RemainWeight > 1);
if (_currentUsePowderBottle == null) { } //跟BS要粉末
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
_currentUsePowderBottle.SourcePowderBottleState = SourceBottleStateEnum.Using;
//四轴机械手取粉末加样头 放到称重模块中
await FourAxisTakePowderHeader((int)BoxAreaEnum._加样头存放平台, 1, _currentUsePowderBottle.Pos_InDosePowderHC, _currentUsePowderBottle.PowderBottleType, token);
//将粉末头放到梅特勒称重模块中
labxPowderInstrument = await labxService.GetInstruments("自动天平XPR105");
await labxService.StartWaitingForHead(labxPowderInstrument.FirstOrDefault(), "Dosing Head", "Dosing Head");
await FourAxisPutPowderHeader((int)BoxAreaEnum._自动加样模块内, 1, 1, _currentUsePowderBottle.PowderBottleType, token);
await SetObstructFlag("四轴机械手运行中", false);
await labxService.AbortWaitingForHead();
}
#endregion
}
/// <summary>
/// 配置流程由找到的_currentDoseFlow决定具体执行哪个物料的投料流程
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
private async Task OneMaterialDose(CancellationToken token)
{
//找到所有未完成投料的样品工装
List<BaseBottleBox> sampleBoxList = workService.ProjectPro.FixtureCacheArea.Where(f => (f.FixtureType == BoxTypeEnum._12mL样品工装 || f.FixtureType == BoxTypeEnum._5mL样品工装)
&& !f.IsDoseFinish && !f.IsEmpty).ToList();
for (int i = 0; i < sampleBoxList.Count; i++) //对每个未配置完成的样品工装进行投料
{
SampleBottleBoxModel sampleBox = sampleBoxList[i] as SampleBottleBoxModel;
for (int j = 0; j < sampleBox.SampleBottleList.Count; j++)
{
if (!sampleBox.SampleBottleList[j].HaveBottle || sampleBox.SampleBottleList[j].bDoseFinish) continue;
SampleBottleModel sampleBottle = sampleBox.SampleBottleList[j];
MaterialDoseFunctionFlow doseflow = new MaterialDoseFunctionFlow();
doseflow = sampleBottle.MaterialDoseFlowList.FirstOrDefault(f => !f.IsDoseFinish && f.FunctionFlowType == _currentDoseFlow.FunctionFlowType && f.UseMaterialName == _currentDoseFlow.UseMaterialName && f.TargetVolume > 0);
if (doseflow == null) continue;
if (_currentDoseFlow.FunctionFlowType == FunctionTypeEnum.)
{
if (_currentUseSourceLiquidBottle == null
|| (_currentUseSourceLiquidBottle.liquidbottle != null &&
(!_currentUseSourceLiquidBottle.liquidbottle.SourceLiquidName.Equals(_currentDoseFlow.UseMaterialName) || _currentUseSourceLiquidBottle.liquidbottle.RemainVolume < 0.5))
)
{
await GetCurrentUseSourceLiquidBottleOrCurrentUsePowderBottle(_currentDoseFlow, token);
}
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
//四轴机械手取样品瓶
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._托盘存放平台, sampleBoxList[i].BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
//如果这个样品瓶 还没有扫过码 四轴机械手到扫码位置,暂时屏蔽
//if (string.IsNullOrEmpty(sampleBottle.SNCode))
//{
// if (sampleBottle.SampleBottleType == SampleBottleTypeEnum._5mL)
// {
// await FourAxisGoToScannPos_liquid(token, 3, null, sampleBottle);
// }
// else
// {
// await FourAxisGoToScannPos_liquid(token, 2, null, sampleBottle);
// }
//}
//四轴机械手放样品瓶到开关盖区域
await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
await SetObstructFlag("四轴机械手运行中", false);
//开盖
await OpenBottleLid(token, null, sampleBottle);
//执行移液枪取Tip头-吸液-分液-丢Tip头流程
await XZ_TakeTip_Absorb_Dispense_DiscardTip(token, doseflow.UseMaterialName, doseflow.TargetVolume, null, sampleBottle);
//更新原液瓶剩余量
_currentUseSourceLiquidBottle.liquidbottle.RemainVolume -= doseflow.TargetVolume / 1000;
doseflow.IsDoseFinish = true;
//关盖
await CloseBottleLid(token, null, sampleBottle);
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
//如果这个样品瓶的配置流程没有配置完成
if (sampleBottle.MaterialDoseFlowList.Any(f => !f.IsDoseFinish))
{
//四轴机械手取样品瓶
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
}
else //配置完成 摇匀
{
await ShakeSampleBottle(token, sampleBottle);
sampleBottle.bDoseFinish = true;
//四轴机械手取样品瓶
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
}
//四轴机械手放样品瓶到托盘存放平台
await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._托盘存放平台, sampleBoxList[i].BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
await SetObstructFlag("四轴机械手运行中", false);
}
else if (_currentDoseFlow.FunctionFlowType == FunctionTypeEnum.)
{
//执行加固体原料流程
if (_currentUsePowderBottle == null ||
(_currentUsePowderBottle != null && (!_currentUsePowderBottle.SourcePowderName.Equals(_currentDoseFlow.UseMaterialName) || _currentUsePowderBottle.RemainWeight < 0.1))
)
{
await GetCurrentUseSourceLiquidBottleOrCurrentUsePowderBottle(_currentDoseFlow, token);
}
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
//四轴机械手取样品瓶
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._托盘存放平台, sampleBoxList[i].BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
//如果这个样品瓶 还没有扫过码 四轴机械手到扫码位置 //todo:屏蔽扫码
//if (string.IsNullOrEmpty(sampleBottle.SNCode))
//{
// if (sampleBottle.SampleBottleType == SampleBottleTypeEnum._5mL)
// {
// await FourAxisGoToScannPos_liquid(token, 3, null, sampleBottle);
// }
// else
// {
// await FourAxisGoToScannPos_liquid(token, 2, null, sampleBottle);
// }
//}
//四轴机械手放样品瓶到开关盖区域
await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
await SetObstructFlag("四轴机械手运行中", false);
//开盖
await OpenBottleLid(token, null, sampleBottle);
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
//梅特勒模块开门
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);
await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
await SetObstructFlag("四轴机械手运行中", false);
//梅特勒模块关门
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);
double addPowderWeight = 0;
//大99小125 2~200mg +-0.297mg 200mg-5g 0.297%
addPowderWeight = await labxService.MTPowderModuleAddPowder(labxPowderInstrument.FirstOrDefault(), "Dosing2", "Dosing2", 4, 99m, (decimal)_currentDoseFlow.TargetVolume, (decimal)10, (decimal)10);
_currentUsePowderBottle.RemainWeight -= addPowderWeight / 1000;
//梅特勒模块开门
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 1);
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._自动加样模块内, 1, 1, sampleBottle);
//梅特勒模块关门
await labxService.MTPowderModuleControlStep(labxPowderInstrument.FirstOrDefault(), "Balance Step", "Balance Step", 0);
await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
await SetObstructFlag("四轴机械手运行中", false);
//关盖
await CloseBottleLid(token, null, sampleBottle);
doseflow.IsDoseFinish = true;
while (await ReadObstructFlag("四轴机械手运行中")
|| await ReadObstructFlag("四轴机械手正在使用传送平台"))
{
await Task.Delay(300);
}
await SetObstructFlag("四轴机械手运行中", true);
//如果这个样品瓶的配置流程没有配置完成
if (sampleBottle.MaterialDoseFlowList.Any(f => !f.IsDoseFinish))
{
//四轴机械手取样品瓶
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
}
else //配置完成 摇匀
{
await ShakeSampleBottle(token, sampleBottle);
sampleBottle.bDoseFinish = true;
await FourAxisTakeSampleBottle(token, (int)BoxAreaEnum._开关盖区域, 0, 0, sampleBottle);
}
//四轴机械手放样品瓶到托盘存放平台
await FourAxisPutSampleBottle(token, (int)BoxAreaEnum._托盘存放平台, sampleBoxList[i].BoxId_inDosingStation, sampleBottle.PosId_InBox, sampleBottle);
await SetObstructFlag("四轴机械手运行中", false);
}
}
}
//这种液体或者粉末 全部样品瓶配置完成
_currentDoseFlow.IsDoseFinish = true; _currentDoseFlow = null;
}
private async Task SetObstructFlag(string name, bool value)
{
try
{
if (this.StationProp.ObstructFlagList.TryGetValue(name, out var targetFlag))
{
if (targetFlag != null)
{
lock (targetFlag)
{
targetFlag.flag = value;
}
}
}
}
catch (Exception)
{
//throw;
}
}
private async Task<bool> ReadObstructFlag(string name, bool value = true, bool bAny = false)
{
try
{
if (!bAny)
{
if (this.StationProp.ObstructFlagList.TryGetValue(name, out var targetFlag))
{
if (targetFlag != null)
{
lock (targetFlag)
{
return targetFlag.flag == value;
}
}
}
}
else if (bAny)
{
foreach (var pair in this.StationProp.ObstructFlagList)
{
if (pair.Key.Contains(name))
{
lock (pair.Value)
{
if (pair.Value.flag == value)
{
return true;
}
}
}
}
}
}
catch (Exception)
{
return false;
}
return false;
}
#region Web
public async Task<(bool, string)> SendJson_old(string guid, string methodName, string outJson, LogLevel logLevel = LogLevel.Info)
{
var webApiUrl = await this.dataAccessService.LoadEntityAsync<WebApiUrl>(x => x.MethodName == methodName);
var url = webApiUrl?.URL;
if (string.IsNullOrEmpty(url))
{
return (false, "");
}
if (!webApiUrl.IsEnable)
{
return (false, "");
}
try
{
DateTime startTime = DateTime.Now;
// *** 关键修改:将 JSON 字符串解析并重新序列化为标准格式 ***
string finalJsonToSend;
// 尝试将传入的 outJson (一个JSON字符串) 解析为 JsonDocument
using (JsonDocument parsedDoc = JsonDocument.Parse(outJson))
{
// 将解析后的文档重新序列化为标准、格式良好的 JSON 字符串
// 这一步确保了发送的是标准的 JSON 对象格式而不是一个被当作字符串的JSON
finalJsonToSend = JsonSerializer.Serialize(parsedDoc.RootElement, new JsonSerializerOptions { WriteIndented = false });
}
HttpContent httpContent = new StringContent(finalJsonToSend, Encoding.UTF8, "application/json");
var client = this._httpClientFactory.CreateClient(guid);
HttpResponseMessage response = null;
if (webApiUrl.RequestType == HttpRequestTypeEnum.Post)
response = await client.PostAsync(url, httpContent);
else
response = await client.GetAsync(url);
var content = await response.Content.ReadAsStringAsync();
DateTime endTime = DateTime.Now;
if (!methodName.Equals("error")) //报警信息回调不写入
{
Logger.LogInformation($"{url}发送{finalJsonToSend}返回{content}");
}
return (true, content);
}
catch (Exception ex)
{
this.Logger.LogError(logEvent: LogEvent.Error, message: $"编号:{guid} 方法:{methodName} 站: 发送失败,{ex.Message}", exception: ex);
return (false, "");
}
}
public async Task<(bool, string)> SendJson(string guid, string methodName, string outJson, LogLevel logLevel = LogLevel.Info)
{
var webApiUrl = await this.dataAccessService.LoadEntityAsync<WebApiUrl>(x => x.MethodName == methodName);
var url = webApiUrl?.URL;
if (string.IsNullOrEmpty(url))
{
return (false, "");
}
if (!webApiUrl.IsEnable)
{
return (false, "");
}
try
{
DateTime starTime = DateTime.Now;
HttpContent httpContent = new StringContent(outJson,Encoding.UTF8, "application/json");
var client = this._httpClientFactory.CreateClient(guid);
HttpResponseMessage response = null;
if (webApiUrl.RequestType == HttpRequestTypeEnum.Post)
response = await client.PostAsync(url, httpContent);
else
response = await client.GetAsync(url);
var content = await response.Content.ReadAsStringAsync();
DateTime endTime = DateTime.Now;
if (!methodName.Equals("error")) //报警信息回调不写入
{
Logger.LogInformation($"{url}发送{outJson}返回{content}");
}
return (true, content);
}
catch (Exception ex)
{
this.Logger.LogError(logEvent: LogEvent.Error, message: $"编号:{guid} 方法:{methodName} 站: 发送失败,{ex.Message}", exception: ex);
return (false, "");
}
}
#endregion
}
}