C00225155-02/C00225155/MegaRobo.C00225155/MegaRobo.C00225155.AppServer/WorkService.HttpServer.cs

2319 lines
125 KiB
C#
Raw Permalink Normal View History

2026-04-13 09:12:49 +00:00
using Common;
using Common.HTTPModels;
using Common.Models;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using Dm.filter.log;
using MegaRobo.C00225155.Entities.Enums;
using MegaRobo.C00225155.Entities.FromWeb;
using MegaRobo.C00225155.Entities.FromWeb.Test;
using MegaRobo.Connections.Web;
using MegaRobo.Contract.Servers;
using MegaRobo.ControlDevices.Abstractions;
using MegaRobo.Entities;
using MegaRobo.Logger;
using MegaRobo.PipetteTool.HamiltonConsole;
using NetTaste;
using Newtonsoft.Json;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Interop;
using static System.Net.Mime.MediaTypeNames;
namespace MegaRobo.C00225155.AppServer
{
public partial class WorkService
{
#region BS交互触发事件
public event EventHandler PrepareUploadBox;
public event EventHandler<BaseBottleBox> UpdateBoxInfo_BS;
#endregion
private HttpListenerService _httpListenerService;
#region
private readonly string _testName = "/api/v1/test";
private readonly string _testName1 = "/device/A1/test";
#endregion
#region swagger
private readonly List<ApiRouteInfo> _registeredApis = new();
private class ApiRouteInfo
{
public string Path { get; set; }
public string HttpMethod { get; set; } = "POST";
public string Summary { get; set; }
public Type RequestType { get; set; } // 可选,用于生成 schema
}
private void AddSwaggerSupport()
{
_httpListenerService.AddRoute("swagger", async msg =>
{
if (msg.HttpMethod == "GET")
{
const string html = @"
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'/>
<title> API - Swagger</title>
<link rel='stylesheet' type='text/css' href='https://unpkg.com/swagger-ui-dist@5.17.14/swagger-ui.css' />
<style>html { box-sizing: border-box; overflow: -moz-scrollbars-vertical; overflow-y: scroll; } *, *:before, *:after { box-sizing: inherit; }</style>
</head>
<body>
<div id='swagger-ui'></div>
<script src='https://unpkg.com/swagger-ui-dist@5.17.14/swagger-ui-bundle.js'></script>
<script>
window.onload = () => {
SwaggerUIBundle({
url: '/swagger/v1/swagger.json',
dom_id: '#swagger-ui',
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset],
layout: 'BaseLayout',
deepLinking: true,
showExtensions: false,
showCommonExtensions: false,
});
};
</script>
</body>
</html>";
msg.Response.Headers["Content-Type"] = "text/html; charset=utf-8";
await msg.ReplyAsync(html);
}
});
_httpListenerService.AddRoute("swagger/v1/swagger.json", async msg =>
{
if (msg.HttpMethod == "GET")
{
var openApi = GenerateOpenApiSpec();
await msg.ReplyAsync(openApi);
}
});
}
private string GenerateOpenApiSpec()
{
var baseUrl = "http://localhost";
var port = 10001;
var paths = new Dictionary<string, object>();
foreach (var api in _registeredApis)
{
var operation = new Dictionary<string, object>
{
["summary"] = api.Summary,
["responses"] = new Dictionary<string, object>
{
["200"] = new Dictionary<string, object>
{
["description"] = "成功"
}
}
};
if (api.HttpMethod == "POST" && api.RequestType != null)
{
var schema = BuildInlineSchema(api.RequestType); // 👈 关键:内联生成 schema
operation["requestBody"] = new Dictionary<string, object>
{
["required"] = true,
["content"] = new Dictionary<string, object>
{
["application/json"] = new Dictionary<string, object>
{
["schema"] = schema
}
}
};
}
paths[api.Path] = new Dictionary<string, object>
{
[api.HttpMethod.ToLower()] = operation
};
}
var openApi = new Dictionary<string, object>
{
["openapi"] = "3.0.3",
["info"] = new Dictionary<string, object>
{
["title"] = "MegaRobo 设备控制 API",
["version"] = "v1"
},
["servers"] = new[]
{
new Dictionary<string, object> { ["url"] = $"{baseUrl}:{port}" }}, ["paths"] = paths
};
return JsonConvert.SerializeObject(openApi, Formatting.Indented);
}
private object BuildInlineSchema(Type type)
{
// 如果是简单类型string/int/bool等直接返回类型
if (IsSimpleType(type))
{
return new Dictionary<string, object> { ["type"] = MapDotNetTypeToOpenApi(type) };
}
// 枚举:统一视为 string
if (type.IsEnum)
{
return new Dictionary<string, object> { ["type"] = "string" };
}
// 集合类型List<T>, ObservableCollection<T> 等)
if (typeof(System.Collections.IEnumerable).IsAssignableFrom(type) && type != typeof(string))
{
return new Dictionary<string, object>
{
["type"] = "array",
["items"] = new Dictionary<string, object> { ["type"] = "object" } // 不展开元素类型
};
}
// 对象类型:只取自身 + 基类(直到 ObservableObject 之前)
var properties = new Dictionary<string, object>();
var current = type;
while (current != null && current != typeof(object))
{
// 遇到 ObservableObject 就停止
if (current == typeof(ObservableObject) ||
(typeof(ObservableObject).IsAssignableFrom(current) && current != type))
{
break;
}
// 只取当前层级声明的 public 实例属性
foreach (var prop in current.GetProperties(
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.DeclaredOnly))
{
if (!prop.CanRead) continue;
var propType = prop.PropertyType;
// 处理 Nullable<T>
if (propType.IsGenericType && propType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
propType = Nullable.GetUnderlyingType(propType);
}
if (propType == null) continue;
// 枚举 → string 改为 integer
if (propType.IsEnum)
{
properties[prop.Name] = new Dictionary<string, object> { ["type"] = "integer" };
}
// 集合 → array of object
else if (typeof(System.Collections.IEnumerable).IsAssignableFrom(propType) && propType != typeof(string))
{
properties[prop.Name] = new Dictionary<string, object>
{
["type"] = "array",
["items"] = new Dictionary<string, object> { ["type"] = "object" }
};
}
// 简单类型
else if (IsSimpleType(propType))
{
properties[prop.Name] = new Dictionary<string, object>
{
["type"] = MapDotNetTypeToOpenApi(propType)
};
}
// 其他复杂对象 → 统一视为 object不展开
else
{
properties[prop.Name] = new Dictionary<string, object> { ["type"] = "object" };
}
}
current = current.BaseType;
}
return new Dictionary<string, object>
{
["type"] = "object",
["properties"] = properties
};
}
private string MapDotNetTypeToOpenApi(Type type)
{
if (type == typeof(string)) return "string";
if (type == typeof(int) || type == typeof(long)) return "integer";
if (type == typeof(float) || type == typeof(double) || type == typeof(decimal)) return "number";
if (type == typeof(bool)) return "boolean";
if (type == typeof(DateTime) || type == typeof(DateTimeOffset)) return "string"; // OpenAPI 用 string 表示时间
if (type == typeof(Guid)) return "string";
return "string";
}
private bool IsSimpleType(Type type)
{
if (type.IsPrimitive || type == typeof(string) || type == typeof(DateTime) ||
type == typeof(DateTimeOffset) || type == typeof(Guid) || type == typeof(decimal))
return true;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
return IsSimpleType(Nullable.GetUnderlyingType(type));
return false;
}
#endregion
/// <summary>
/// 将特定的 HTTP 路径(路由)与对应的处理方法关联
/// HttpListenerService 能够监听这些路径的请求并执行对应的业务逻辑
/// 当传入 deviceKey = "A5" 时,会生成路由:
/// 测试接口:/api/v1/test → 绑定 OnTest 方法,用于测试接口可用性,返回调用成功的 JSON 响应。
/// 设备同步序列接口:/device/A5/sync-seq → 绑定 SyncSeq 方法(目前方法体为空,可后续扩展同步设备序列的逻辑)。
/// </summary>
/// <param name="deviceKey"></param>
private void RegiondRoute(string deviceKey)
{
// 清空旧记录(防止重复)
_registeredApis.Clear();
string _info = $"/device/{deviceKey}/info";
string _isAllow = $"/device/{deviceKey}/is-allow";
string _get_storage = $"/device/{deviceKey}/get-storage";
string _open_door = $"/device/{deviceKey}/open-door";
string _load = $"/device/{deviceKey}/load";
string _unload = $"/device/{deviceKey}/unload";
string _sync_seq = $"/device/{deviceKey}/sync-seq";
string _add_seq = $"/device/{deviceKey}/add-seq";
string _delete_seq = $"/device/{deviceKey}/delete-seq";
string _control = $"/device/{deviceKey}/control";
//添加监听接口路由
this._httpListenerService.AddRoute(this._testName, this.OnTest);
this._httpListenerService.AddRoute(this._testName1, this.OnTest1);
this._httpListenerService.AddRoute(_info, this.MachineInfo);
this._httpListenerService.AddRoute(_isAllow, this.IsAllowOperate);
this._httpListenerService.AddRoute(_get_storage, this.GetStorage);
this._httpListenerService.AddRoute(_open_door, this.OpenDoor);
this._httpListenerService.AddRoute(_load, this.LoadConsumable);
this._httpListenerService.AddRoute(_unload, this.UnLoad);
this._httpListenerService.AddRoute(_sync_seq, this.SyncSeqEx);
this._httpListenerService.AddRoute(_add_seq, this.AddSeq);
this._httpListenerService.AddRoute(_delete_seq, this.DeleteSeq);
this._httpListenerService.AddRoute(_control, this.MachineControl);
// 记录元数据(用于 Swagger
_registeredApis.Add(new ApiRouteInfo { Path = _testName, HttpMethod = "GET", Summary = "测试接口" });
_registeredApis.Add(new ApiRouteInfo { Path = _info, HttpMethod = "GET", Summary = "查询机台状态信息" });
_registeredApis.Add(new ApiRouteInfo { Path = _isAllow, HttpMethod = "GET", Summary = "是否允许上料" });
_registeredApis.Add(new ApiRouteInfo { Path = _get_storage, HttpMethod = "GET", Summary = "获取机台可以放置的物料信息" });
_registeredApis.Add(new ApiRouteInfo { Path = _open_door, HttpMethod = "GET", Summary = "打开舱门,准备上料" });
_registeredApis.Add(new ApiRouteInfo { Path = _load, HttpMethod = "POST", Summary = "开始上料", RequestType = typeof(List<BaseBottleBox>) });
_registeredApis.Add(new ApiRouteInfo { Path = _unload, HttpMethod = "POST", Summary = "下料完成", RequestType = typeof(UnLoadModel) });
_registeredApis.Add(new ApiRouteInfo { Path = _sync_seq, HttpMethod = "POST", Summary = "同步样品序列", RequestType = typeof(List<SampleBottleModel>) });
_registeredApis.Add(new ApiRouteInfo { Path = _add_seq, HttpMethod = "POST", Summary = "添加新序列", RequestType = typeof(List<SampleBottleModel>) });
_registeredApis.Add(new ApiRouteInfo { Path = _delete_seq, HttpMethod = "POST", Summary = "取消序列执行", RequestType = typeof(List<SampleBottleModel>) });
_registeredApis.Add(new ApiRouteInfo { Path = _control, HttpMethod = "POST", Summary = "机台控制指令", RequestType = typeof(ControlCmd) });
}
/// <summary>
/// 测试接口,为了给客户看而使用的接口,后期屏蔽
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
private async Task OnTest1(HttpListenerMessage msg)
{
Response result = new Response();
string str = msg.GetMessageString(); //如果是post则接受数据并反序列化
//string str = await msg.GetRequestBodyStringAsync(); //如果是post则接受数据并反序列化
result.code = 0;
result.msg = $"{_testName} 接口调用成功";
result.data = true;
if (stationService_Dose.StationProp.deviceStatus != Entities.DeviceStatus.Idel)
{
result.code = 1; result.msg = $"{_testName} 接口调用失败,设备不在安全状态";
Logger.LogInformation($"{_testName} 接口调用失败,设备不在安全状态");
await msg.ReplyAsync(result.ToJson());
return;
}
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"向BS发送完成接收到-Test1请求返回成功");
_ = Task.Run(async() =>
{
//导入方案
ProjectPro.bNoUseBS = true;
#region
ProjectProperty project = new ProjectProperty();
bool readOk = false;
project = File_Operator.Xml_Serialize("C:\\Users\\CTOS\\Desktop\\测试流程_1.pro", false, project, out readOk);
if (readOk)
{
ProjectPro = project;
ProjectPro.LastOpenProject = "C:\\Users\\CTOS\\Desktop\\测试流程_1.pro";
ProjectPro.NowOpenProjectFile = "C:\\Users\\CTOS\\Desktop\\测试流程_1.pro".Substring("C:\\Users\\CTOS\\Desktop\\测试流程_1.pro".LastIndexOf("\\") + 1).Trim();
WeakReferenceMessenger.Default.Send(new DesktopAlertMessage { Content = "打开项目文件成功!" });
}
#endregion
await stationService_Dose.ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
await stationService_Dose.StartLoad();
await stationService_Dose.ChangeDeviceStatus(Entities.DeviceStatus.Runing);
});
}
private async Task OnTest(HttpListenerMessage msg)
{
Response result = new Response();
string str = msg.GetMessageString(); //如果是post则接受数据并反序列化
//string str = await msg.GetRequestBodyStringAsync(); //如果是post则接受数据并反序列化
result.code = 0;
result.msg = $"{_testName} 接口调用成功";
await msg.ReplyAsync(result.ToJson());
}
/// <summary>
/// 机台信息查询
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
private async Task MachineInfo(HttpListenerMessage msg)
{
Logger.LogInformation($"{DateTime.Now}收到机台查询状态指令");
Response result = new Response();
result.code = 0;
result.msg = $"{stationService_Dose.StationProp.deviceStatus.ToString()}";
var isInitOk = stationService_Dose.GetInitStatus();
if (isInitOk != 3)
{
stationService_Dose.StationProp.deviceStatus = Entities.DeviceStatus.Disable;
}
result.data = new {
status = new
{
deviceStatus = stationService_Dose.StationProp.deviceStatus.ToString(),
//isAllowLoad = true, //todo:测试先不做校验
isAllowLoad = this.stationService_Dose.StationProp.deviceStatus == Entities.DeviceStatus.Idel //这边可能需要扩展CS要完全下料完成才能认为是Idel
}
};
string json = JsonConvert.SerializeObject(result);
Logger.LogInformation($"{DateTime.Now}收到机台查询状态指令-返回{json}");
await msg.ReplyAsync(json);
//var testJson = new { test = "测试" };
//var testres = await stationService_Dose.SendJson("111", "test_1", testJson.ToString());
}
/// <summary>
/// 机台信息查询
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
private async Task IsAllowOperate(HttpListenerMessage msg)
{
Response result = new Response();
result.code = 0;
result.msg = $"操作成功";
Logger.LogInformation($"{DateTime.Now}收到机台查询允许上料指令");
bool res = this.stationService_Dose.StationProp.deviceStatus == Entities.DeviceStatus.Idel;
result.data = res;
string json = JsonConvert.SerializeObject(result);
Logger.LogInformation($"{DateTime.Now}收到机台查询允许上料指令-返回{json}");
await msg.ReplyAsync(json);
}
private async Task GetStorage(HttpListenerMessage msg)
{
Response result = new Response();
result.code = 0;
result.msg = $"操作成功";
Logger.LogInformation($"{DateTime.Now}收到机台查询库位指令");
//这边获取机台可以存放的40ml. 5/12ml tip 及 粉末头放置的个数
var _5or12_fixtures = ProjectPro.FixtureCacheArea.Count(b => (b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装) && !b.IsEmpty);
var _40_fixtures = ProjectPro.FixtureCacheArea.Count(b => b.FixtureType == BoxTypeEnum._40mL原液工装 && !b.IsEmpty);
var _powderHeaders = ProjectPro.PowderHeaderCacheArea.Count(b => b.HaveBottle);
var _tipFixtures = ProjectPro.TipHeadArea.Count(b => !b.IsEmpty);
List<int> transferPoss = new List<int>();
for (int i = 0; i < ProjectPro.TransferArea.Count; i++)
{
if (ProjectPro.TransferArea[i].IsEmpty)
{
transferPoss.Add(i + 1);
}
}
result.data = new
{
sampleFixtureRemainCount = 4 - _5or12_fixtures,
sourceFixtureRemainCount = 2 - _40_fixtures,
tipFixTureRemainCount = 3 - _tipFixtures,
powderHeaderRemainCount = 10 - _powderHeaders,
transferArea = transferPoss
};
string json = JsonConvert.SerializeObject(result);
Logger.LogInformation($"{DateTime.Now}收到机台查询库位指令-返回{json}");
await msg.ReplyAsync(json);
}
private async Task OpenDoor(HttpListenerMessage msg)
{
Response result = new Response();
result.code = 0;
result.msg = $"操作成功";
Logger.LogInformation($"{DateTime.Now}收到机台开门指令");
if (this.stationService_Dose.StationProp.deviceStatus != Entities.DeviceStatus.Idel)
{
result.data = false; result.code = 1;
result.msg = $"机台不在就绪状态,不能打开门";
var json = JsonConvert.SerializeObject(result);
await msg.ReplyAsync(json);
Logger.LogInformation($"{DateTime.Now}收到机台开门指令-返回{json}");
}
else
{
await stationService_Dose.ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
result.data = true;
var json = JsonConvert.SerializeObject(result);
Logger.LogInformation($"{DateTime.Now}收到机台开门指令-返回{json}");
await msg.ReplyAsync(json);
_ = Task.Run(async () =>
{
await stationService_Dose.OpenDoor();
});
}
}
/// <summary>
/// 判断上料数据是否合法
/// </summary>
/// <param name="uploadDatas"></param>
/// <returns></returns>
private (bool isSuccess, string msg) ValidateUploadData(List<UploadBoxModel> uploadDatas)
{
(bool isSuccess, string msg) result = (true, "");
//规则(*母液最多2-已使用个目标最多4-已使用个,tip最多3-已使用个粉末最多2-已使用个载具10-已使用个粉头
var _5or12_fixtures = ProjectPro.FixtureCacheArea.Count(b => (b.FixtureType == BoxTypeEnum._12mL样品工装 || b.FixtureType == BoxTypeEnum._5mL样品工装) && !b.IsEmpty);
var _40_fixtures = ProjectPro.FixtureCacheArea.Count(b => b.FixtureType == BoxTypeEnum._40mL原液工装 && !b.IsEmpty);
var _powderHeaders = ProjectPro.PowderHeaderCacheArea.Count(b => b.HaveBottle);
var _tipFixtures = ProjectPro.TipHeadArea.Count(b => !b.IsEmpty);
var powderHeaderRemainCount = 10 - _powderHeaders;
if (uploadDatas.Count(x => x.fixtureType == BoxTypeEnum._40mL原液工装) > (2 - _40_fixtures))
{
result.isSuccess = false; result.msg += $"原液工装剩余{(2 - _40_fixtures)}个位置,本次上料无法满足\n";
}
if (uploadDatas.Count(x => x.fixtureType == BoxTypeEnum._12mL样品工装 || x.fixtureType == BoxTypeEnum._5mL样品工装) > (4 - _5or12_fixtures))
{
result.isSuccess = false; result.msg += $"样品瓶工装剩余{(4 - _5or12_fixtures)}个位置,本次上料无法满足\n";
}
if (uploadDatas.Count(x => x.fixtureType == BoxTypeEnum._1000uLTip头工装 || x.fixtureType == BoxTypeEnum._300uLTip头工装 || x.fixtureType == BoxTypeEnum._50uLTip头工装) > (3 - _tipFixtures))
{
result.isSuccess = false; result.msg += $"Tip工装剩余{(3 - _tipFixtures)}个位置,本次上料无法满足\n";
}
var sum = uploadDatas
.Where(u => u.fixtureType == BoxTypeEnum._16mL粉末瓶工装 || u.fixtureType == BoxTypeEnum._125mL粉末瓶工装)
.Sum(u => u.sourcePowderBottles.Count());
if (sum > powderHeaderRemainCount)
{
result.isSuccess = false; result.msg += $"粉末剩余{powderHeaderRemainCount}个位置,本次上料无法满足\n";
}
//规则1上料数目有限制tipremainCount:1~96、原液瓶(8个)、目标瓶12个、粉末头2/4个不能超过剩余数目
//规则2粉末/tip只能放在67 原液只能放在45 目标瓶只能在123
foreach (var uploadData in uploadDatas)
{
switch (uploadData.fixtureType)
{
case BoxTypeEnum._40mL原液工装:
#region 14581-8
if (uploadData.boxId_inDoseUpload != 4 && uploadData.boxId_inDoseUpload != 5)
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}不能放在{uploadData.boxId_inDoseUpload}只能放在4或者5号位置\n";
}
if (uploadData.sourceLiquidBottles == null)
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}里面没有原液瓶子信息\n";
}
else
{
if (uploadData.sourceLiquidBottles.Count > 8)
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}数目为{uploadData.sourceLiquidBottles.Count}原液最多只能有8个瓶子\n";
}
if (uploadData.sourceLiquidBottles.Any(s => s.PosId_InBox > 8 || s.PosId_InBox < 1))
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}里面瓶子的PosId_InBox字段存在不是1~8的异常数\n";
}
}
#endregion
break;
case BoxTypeEnum._12mL样品工装:
case BoxTypeEnum._5mL样品工装:
#region 21~3121~12
if (uploadData.boxId_inDoseUpload != 1 && uploadData.boxId_inDoseUpload != 2 && uploadData.boxId_inDoseUpload != 3)
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}不能放在{uploadData.boxId_inDoseUpload}只能放在1~3号位置\n";
}
if (uploadData.sampleBottles == null)
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}里面没有样品瓶\n";
}
else
{
if (uploadData.sampleBottles.Count > 12)
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}数目为{uploadData.sourceLiquidBottles.Count}样品载具最多只能有12个瓶子\n";
}
if (uploadData.sampleBottles.Any(s => s.PosId_InBox > 12 || s.PosId_InBox < 1))
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}里面瓶子的PosId_InBox字段存在不是1~12的异常数\n";
}
}
#endregion
break;
case BoxTypeEnum._16mL粉末瓶工装:
case BoxTypeEnum._125mL粉末瓶工装:
#region 36-72/41~2/4
if (uploadData.boxId_inDoseUpload != 6 && uploadData.boxId_inDoseUpload != 7)
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}不能放在{uploadData.boxId_inDoseUpload}只能放在6~7号位置\n";
}
if (uploadData.sourcePowderBottles == null)
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}里面没有粉末瓶\n";
}
else
{
var maxCount = uploadData.fixtureType == BoxTypeEnum._16mL粉末瓶工装 ? 4 : 2;
if (uploadData.sourcePowderBottles.Count > maxCount)
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}数目为{uploadData.sourceLiquidBottles.Count}{uploadData.fixtureType.ToString()}载具最多只能有{maxCount}个瓶子\n";
}
if (uploadData.sourcePowderBottles.Any(s => s.PosId_InBox > maxCount || s.PosId_InBox < 1))
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}里面瓶子的PosId_InBox字段存在不是1~{maxCount}的异常数\n";
}
}
#endregion
break;
case BoxTypeEnum._50uLTip头工装:
case BoxTypeEnum._300uLTip头工装:
case BoxTypeEnum._1000uLTip头工装:
#region 4tip只能放在6-71~96
if (uploadData.boxId_inDoseUpload != 6 && uploadData.boxId_inDoseUpload != 7)
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}不能放在{uploadData.boxId_inDoseUpload}只能放在6~7号位置\n";
}
if (uploadData.RemainCount > 96 || uploadData.RemainCount < 1)
{
result.isSuccess = false; result.msg += $"{uploadData.boxSNCode}里面tip剩余个数{uploadData.RemainCount}应该是1~96\n";
}
#endregion
break;
default:
break;
}
}
return result;
}
private async Task StartLoad(HttpListenerMessage msg)
{
Response result = new Response();
result.code = 0;
result.msg = $"load接口调用成功";
string str = msg.GetMessageString();
//string str = await msg.GetRequestBodyStringAsync();
Logger.LogInformation($"{DateTime.Now}收到机台开始上料指令,内容-{str}");
if (!string.IsNullOrEmpty(str))
{
if (stationService_Dose.StationProp.deviceStatus != Entities.DeviceStatus.Idel)
{
result.data = false; result.code = 1;
result.msg = "未在就绪状态不允许上料";
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台开始上料指令,返回-{result.ToJson()}");
return;
}
var uploadDatas = JsonConvert.DeserializeObject<List<UploadBoxModel>>(str);
var res = ValidateUploadData(uploadDatas);
result.data = res.isSuccess;
result.msg = res.msg;
if (!res.isSuccess)
{
result.code = 1;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台开始上料指令,返回-{result.ToJson()}");
return;
}
foreach (var uploadData in uploadDatas)
{
switch (uploadData.fixtureType)
{
case BoxTypeEnum._40mL原液工装:
var sourceBox = new SourceLiquidBottleBoxModel()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
SourceLiquidBottleCollection = new ObservableCollection<SourceLiquidBottleModel>()
};
for (int i = 0; i < 8; i++)
{
var sourceBottle = uploadData.sourceLiquidBottles.FirstOrDefault(s => s.PosId_InBox == i + 1);
if (sourceBottle == null)
{
sourceBottle = new SourceLiquidBottleModel();
sourceBottle.HaveBottle = false;
sourceBottle.PosId_InBox = i + 1;
sourceBox.SourceLiquidBottleCollection.Add(sourceBottle);
}
else
{
sourceBottle.HaveBottle = true;
sourceBottle.BoxSNCode = sourceBox.BoxSNCode;
sourceBox.SourceLiquidBottleCollection.Add(sourceBottle);
}
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[sourceBox.BoxId_inDoseUpload - 1] = sourceBox;
});
break;
case BoxTypeEnum._12mL样品工装:
case BoxTypeEnum._5mL样品工装:
var sampleBox = new SampleBottleBoxModel()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
SampleBottleList = new ObservableCollection<SampleBottleModel>()
};
for (int i = 0; i < 12; i++)
{
var sampleBottle = uploadData.sampleBottles.FirstOrDefault(s => s.PosId_InBox == i + 1);
if (sampleBottle == null)
{
sampleBottle = new SampleBottleModel();
sampleBottle.HaveBottle = false;
sampleBottle.PosId_InBox = i + 1;
if (sampleBottle.MaterialDoseFlowList == null)
{
sampleBottle.MaterialDoseFlowList = new ObservableCollection<MaterialDoseFunctionFlow>();
}
sampleBox.SampleBottleList.Add(sampleBottle);
}
else
{
sampleBottle.SampleBottleType = uploadData.fixtureType == BoxTypeEnum._12mL样品工装 ? SampleBottleTypeEnum._12mL : SampleBottleTypeEnum._5mL;
sampleBottle.HaveBottle = true;
sampleBottle.BoxSNCode = sampleBox.BoxSNCode;
if (sampleBottle.MaterialDoseFlowList == null)
{
sampleBottle.MaterialDoseFlowList = new ObservableCollection<MaterialDoseFunctionFlow>();
}
sampleBox.SampleBottleList.Add(sampleBottle);
}
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[sampleBox.BoxId_inDoseUpload - 1] = sampleBox;
});
break;
case BoxTypeEnum._16mL粉末瓶工装:
var sourcePowderBottleBoxModel = new SourcePowderBottleBoxModel()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
SourcePowderBottleCollection = new ObservableCollection<SourcePowderBottleModel>()
};
for (int i = 0; i < 4; i++)
{
var sourcePowderBottle = uploadData.sourcePowderBottles.FirstOrDefault(s => s.PosId_InBox == i + 1);
if (sourcePowderBottle == null)
{
sourcePowderBottle = new SourcePowderBottleModel();
sourcePowderBottle.PosId_InBox = i + 1;
sourcePowderBottle.HaveBottle = false;
sourcePowderBottle.PowderBottleType = PowderBottleTypeEnum._16mL;
sourcePowderBottleBoxModel.SourcePowderBottleCollection.Add(sourcePowderBottle);
}
else
{
sourcePowderBottle.PowderBottleType = PowderBottleTypeEnum._16mL;
sourcePowderBottle.HaveBottle = true;
sourcePowderBottle.BoxSNCode = sourcePowderBottleBoxModel.BoxSNCode;
sourcePowderBottleBoxModel.SourcePowderBottleCollection.Add(sourcePowderBottle);
}
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[sourcePowderBottleBoxModel.BoxId_inDoseUpload - 1] = sourcePowderBottleBoxModel;
});
break;
case BoxTypeEnum._125mL粉末瓶工装:
var sourcePowderBottleBoxModel_125Ml = new SourcePowderBottleBoxModel_125ml()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
SourcePowderBottleCollection = new ObservableCollection<SourcePowderBottleModel>()
};
for (int i = 0; i < 2; i++)
{
var sourcePowderBottle = uploadData.sourcePowderBottles.FirstOrDefault(s => s.PosId_InBox == i + 1);
if (sourcePowderBottle == null)
{
sourcePowderBottle = new SourcePowderBottleModel();
sourcePowderBottle.PosId_InBox = i + 1;
sourcePowderBottle.HaveBottle = false;
sourcePowderBottle.PowderBottleType = PowderBottleTypeEnum._125mL;
sourcePowderBottleBoxModel_125Ml.SourcePowderBottleCollection.Add(sourcePowderBottle);
}
else
{
sourcePowderBottle.PowderBottleType = PowderBottleTypeEnum._125mL;
sourcePowderBottle.HaveBottle = true;
sourcePowderBottle.BoxSNCode = sourcePowderBottleBoxModel_125Ml.BoxSNCode;
sourcePowderBottleBoxModel_125Ml.SourcePowderBottleCollection.Add(sourcePowderBottle);
}
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[sourcePowderBottleBoxModel_125Ml.BoxId_inDoseUpload - 1] = sourcePowderBottleBoxModel_125Ml;
});
break;
case BoxTypeEnum._50uLTip头工装:
case BoxTypeEnum._300uLTip头工装:
case BoxTypeEnum._1000uLTip头工装:
TipBoxModel tipBoxModel = new TipBoxModel()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
UseIndex = 96 - uploadData.RemainCount + 1,
TipItems = new ObservableCollection<TipHeadItem>()
};
tipBoxModel.TipType = uploadData.fixtureType == BoxTypeEnum._50uLTip头工装 ? TipTypeEnum._50UL : (uploadData.fixtureType == BoxTypeEnum._300uLTip头工装 ? TipTypeEnum._300UL : TipTypeEnum._1000UL);
for (int i = 0; i < tipBoxModel.UseIndex - 1; i++)
{
tipBoxModel.TipItems.Add(new TipHeadItem() { IsAvailable = false, UseIndex = i + 1 });
}
for (int i = tipBoxModel.UseIndex - 1; i < 96; i++)
{
tipBoxModel.TipItems.Add(new TipHeadItem() { IsAvailable = true, UseIndex = i + 1 });
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[tipBoxModel.BoxId_inDoseUpload - 1] = tipBoxModel;
});
break;
default:
break;
}
}
await stationService_Dose.ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
await msg.ReplyAsync(JsonConvert.SerializeObject(result));
Logger.LogInformation($"{DateTime.Now}收到机台开始上料指令,返回-{result.ToJson()}");
_ = Task.Run(async () =>
{
await stationService_Dose.StartLoad();
});
}
else
{
result.data = false;
result.msg = "数据异常";
result.code = 1;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台开始上料指令,返回-{result.ToJson()}");
return;
}
/*
List<UploadBoxModel> list = new List<UploadBoxModel>();
UploadBoxModel uploadBoxModel = new UploadBoxModel()
{
boxId_inDoseUpload = 4,
boxSNCode = "1",
fixtureType = BoxTypeEnum._40mL原液工装,
sourceLiquidBottles = new List<SourceLiquidBottleModel>()
{
new SourceLiquidBottleModel(){ PosId_InBox = 1, SNCode = "", SourceLiquidName = "水", OriginVolume = 40, RemainVolume = 40},
new SourceLiquidBottleModel(){ PosId_InBox = 2, SNCode = "", SourceLiquidName = "EC", OriginVolume = 38, RemainVolume = 38},
new SourceLiquidBottleModel(){ PosId_InBox = 3, SNCode = "", SourceLiquidName = "DEC", OriginVolume = 35, RemainVolume = 35},
new SourceLiquidBottleModel(){ PosId_InBox = 5, SNCode = "", SourceLiquidName = "DMF", OriginVolume = 37, RemainVolume = 37},
}
};
list.Add(uploadBoxModel);
UploadBoxModel uploadBoxModel2 = new UploadBoxModel()
{
boxId_inDoseUpload = 2,
boxSNCode = "2",
fixtureType = BoxTypeEnum._5mL样品工装,
sampleBottles = new List<SampleBottleModel>()
{
new SampleBottleModel()
{
PosId_InBox = 1, SNCode = "", SampleContentName = "",
MaterialDoseFlowList = new ObservableCollection<MaterialDoseFunctionFlow>()
{
new MaterialDoseFunctionFlow(){ FunctionFlowType = FunctionTypeEnum., UseMaterialName = "水", TargetVolume = 1000},
new MaterialDoseFunctionFlow(){ FunctionFlowType = FunctionTypeEnum., UseMaterialName = "EC", TargetVolume = 1000},
new MaterialDoseFunctionFlow(){ FunctionFlowType = FunctionTypeEnum., UseMaterialName = "P1", TargetVolume = 2},
}
},
new SampleBottleModel()
{
PosId_InBox = 2, SNCode = "", SampleContentName = "",
MaterialDoseFlowList = new ObservableCollection<MaterialDoseFunctionFlow>()
{
new MaterialDoseFunctionFlow(){ FunctionFlowType = FunctionTypeEnum., UseMaterialName = "P2", TargetVolume = 10},
new MaterialDoseFunctionFlow(){ FunctionFlowType = FunctionTypeEnum., UseMaterialName = "DMF", TargetVolume = 1000},
new MaterialDoseFunctionFlow(){ FunctionFlowType = FunctionTypeEnum., UseMaterialName = "EC", TargetVolume = 1000}
}
}
}
};
list.Add(uploadBoxModel2);
UploadBoxModel uploadBoxModel3 = new UploadBoxModel()
{
boxId_inDoseUpload = 6,
boxSNCode = "6",
fixtureType = BoxTypeEnum._1000uLTip头工装,
RemainCount = 90
};
list.Add(uploadBoxModel3);
UploadBoxModel uploadBoxModel4 = new UploadBoxModel()
{
boxId_inDoseUpload = 7,
boxSNCode = "7",
fixtureType = BoxTypeEnum._16mL粉末瓶工装,
sourcePowderBottles = new List<SourcePowderBottleModel>()
{
new SourcePowderBottleModel(){ PosId_InBox = 1, SNCode = "", SourcePowderName = "P1", OriginWeight = 16, RemainWeight = 16 },
new SourcePowderBottleModel(){ PosId_InBox = 2, SNCode = "", SourcePowderName = "P2", OriginWeight = 16, RemainWeight = 16 },
}
};
list.Add(uploadBoxModel4);
var testjson = JsonConvert.SerializeObject(list.ToList());
*/
}
/// <summary>
/// 上耗材
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
private async Task LoadConsumable(HttpListenerMessage msg)
{
Response result = new Response() { code = 0, data = true, msg = "" };
string str = msg.GetMessageString();
//string str = await msg.GetRequestBodyStringAsync();
Logger.LogInformation($"{DateTime.Now}收到机台上料耗材指令,内容-{str}");
if (string.IsNullOrEmpty(str))
{
result.data = false; result.msg = "参数不正确"; result.code = 1;
await msg.ReplyAsync(result.ToJson());
return;
}
try
{
var consumBoxs = JsonConvert.DeserializeObject<ConsumableBox>(str);
List<UploadBoxModel> uploadDatas = new List<UploadBoxModel>();
foreach (var consumBox in consumBoxs.Consumable)
{
if ((BoxTypeEnum)consumBox.FixtureType != BoxTypeEnum._300uLTip头工装 &&
(BoxTypeEnum)consumBox.FixtureType != BoxTypeEnum._50uLTip头工装 &&
(BoxTypeEnum)consumBox.FixtureType != BoxTypeEnum._1000uLTip头工装 &&
(BoxTypeEnum)consumBox.FixtureType != BoxTypeEnum._40mL原液工装 &&
(BoxTypeEnum)consumBox.FixtureType != BoxTypeEnum._16mL粉末瓶工装 &&
(BoxTypeEnum)consumBox.FixtureType != BoxTypeEnum._125mL粉末瓶工装)
{
result.data = false; result.msg = $"耗材类型{consumBox.FixtureType}不正确!"; result.code = 1;
await msg.ReplyAsync(result.ToJson());
return;
}
UploadBoxModel uploadBox = new UploadBoxModel()
{
fixtureType = (BoxTypeEnum)consumBox.FixtureType,
boxSNCode = consumBox.SnCode,
boxId_inDoseUpload = consumBox.PosInUpload,
RemainCount = consumBox.RemainCount
};
if (uploadBox.fixtureType == BoxTypeEnum._40mL原液工装)
{
uploadBox.sourceLiquidBottles = new List<SourceLiquidBottleModel>();
foreach (var tubeInfo in consumBox.Detail)
{
SourceLiquidBottleModel sourceLiquidBottleModel = new SourceLiquidBottleModel()
{
BoxSNCode = consumBox.SnCode,
HaveBottle = true, OriginVolume = tubeInfo.RemainWeight, RemainVolume = tubeInfo.RemainWeight,
PosId_InBox = int.Parse(tubeInfo.Pos),SourceLiquidName = tubeInfo.Code
};
uploadBox.sourceLiquidBottles.Add(sourceLiquidBottleModel);
}
}
else if (uploadBox.fixtureType == BoxTypeEnum._16mL粉末瓶工装 || uploadBox.fixtureType == BoxTypeEnum._125mL粉末瓶工装)
{
uploadBox.sourcePowderBottles = new List<SourcePowderBottleModel>();
foreach (var tubeInfo in consumBox.Detail)
{
SourcePowderBottleModel sourceBottle = new SourcePowderBottleModel()
{
BoxSNCode = consumBox.SnCode,
HaveBottle = true,
OriginWeight = tubeInfo.RemainWeight,
RemainWeight = tubeInfo.RemainWeight,
PosId_InBox = int.Parse(tubeInfo.Pos),
SourcePowderName = tubeInfo.Code
};
uploadBox.sourcePowderBottles.Add(sourceBottle);
}
}
uploadDatas.Add(uploadBox);
}
var res = ValidateUploadData(uploadDatas);
result.data = res.isSuccess;
result.msg = res.msg;
if (!res.isSuccess)
{
result.code = 1;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台开始上料指令,返回-{result.ToJson()}");
return;
}
foreach (var uploadData in uploadDatas)
{
switch (uploadData.fixtureType)
{
case BoxTypeEnum._40mL原液工装:
var sourceBox = new SourceLiquidBottleBoxModel()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
SourceLiquidBottleCollection = new ObservableCollection<SourceLiquidBottleModel>()
};
for (int i = 0; i < 8; i++)
{
var sourceBottle = uploadData.sourceLiquidBottles.FirstOrDefault(s => s.PosId_InBox == i + 1);
if (sourceBottle == null)
{
sourceBottle = new SourceLiquidBottleModel();
sourceBottle.HaveBottle = false;
sourceBottle.PosId_InBox = i + 1;
sourceBox.SourceLiquidBottleCollection.Add(sourceBottle);
}
else
{
sourceBottle.HaveBottle = true;
sourceBottle.BoxSNCode = sourceBox.BoxSNCode;
sourceBox.SourceLiquidBottleCollection.Add(sourceBottle);
}
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[sourceBox.BoxId_inDoseUpload - 1] = sourceBox;
});
break;
case BoxTypeEnum._12mL样品工装:
case BoxTypeEnum._5mL样品工装:
var sampleBox = new SampleBottleBoxModel()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
SampleBottleList = new ObservableCollection<SampleBottleModel>()
};
for (int i = 0; i < 12; i++)
{
var sampleBottle = uploadData.sampleBottles.FirstOrDefault(s => s.PosId_InBox == i + 1);
if (sampleBottle == null)
{
sampleBottle = new SampleBottleModel();
sampleBottle.HaveBottle = false;
sampleBottle.PosId_InBox = i + 1;
if (sampleBottle.MaterialDoseFlowList == null)
{
sampleBottle.MaterialDoseFlowList = new ObservableCollection<MaterialDoseFunctionFlow>();
}
sampleBox.SampleBottleList.Add(sampleBottle);
}
else
{
sampleBottle.SampleBottleType = uploadData.fixtureType == BoxTypeEnum._12mL样品工装 ? SampleBottleTypeEnum._12mL : SampleBottleTypeEnum._5mL;
sampleBottle.HaveBottle = true;
sampleBottle.BoxSNCode = sampleBox.BoxSNCode;
if (sampleBottle.MaterialDoseFlowList == null)
{
sampleBottle.MaterialDoseFlowList = new ObservableCollection<MaterialDoseFunctionFlow>();
}
sampleBox.SampleBottleList.Add(sampleBottle);
}
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[sampleBox.BoxId_inDoseUpload - 1] = sampleBox;
});
break;
case BoxTypeEnum._16mL粉末瓶工装:
var sourcePowderBottleBoxModel = new SourcePowderBottleBoxModel()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
SourcePowderBottleCollection = new ObservableCollection<SourcePowderBottleModel>()
};
for (int i = 0; i < 4; i++)
{
var sourcePowderBottle = uploadData.sourcePowderBottles.FirstOrDefault(s => s.PosId_InBox == i + 1);
if (sourcePowderBottle == null)
{
sourcePowderBottle = new SourcePowderBottleModel();
sourcePowderBottle.PosId_InBox = i + 1;
sourcePowderBottle.HaveBottle = false;
sourcePowderBottle.PowderBottleType = PowderBottleTypeEnum._16mL;
sourcePowderBottleBoxModel.SourcePowderBottleCollection.Add(sourcePowderBottle);
}
else
{
sourcePowderBottle.PowderBottleType = PowderBottleTypeEnum._16mL;
sourcePowderBottle.HaveBottle = true;
sourcePowderBottle.BoxSNCode = sourcePowderBottleBoxModel.BoxSNCode;
sourcePowderBottleBoxModel.SourcePowderBottleCollection.Add(sourcePowderBottle);
}
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[sourcePowderBottleBoxModel.BoxId_inDoseUpload - 1] = sourcePowderBottleBoxModel;
});
break;
case BoxTypeEnum._125mL粉末瓶工装:
var sourcePowderBottleBoxModel_125Ml = new SourcePowderBottleBoxModel_125ml()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
SourcePowderBottleCollection = new ObservableCollection<SourcePowderBottleModel>()
};
for (int i = 0; i < 2; i++)
{
var sourcePowderBottle = uploadData.sourcePowderBottles.FirstOrDefault(s => s.PosId_InBox == i + 1);
if (sourcePowderBottle == null)
{
sourcePowderBottle = new SourcePowderBottleModel();
sourcePowderBottle.PosId_InBox = i + 1;
sourcePowderBottle.HaveBottle = false;
sourcePowderBottle.PowderBottleType = PowderBottleTypeEnum._125mL;
sourcePowderBottleBoxModel_125Ml.SourcePowderBottleCollection.Add(sourcePowderBottle);
}
else
{
sourcePowderBottle.PowderBottleType = PowderBottleTypeEnum._125mL;
sourcePowderBottle.HaveBottle = true;
sourcePowderBottle.BoxSNCode = sourcePowderBottleBoxModel_125Ml.BoxSNCode;
sourcePowderBottleBoxModel_125Ml.SourcePowderBottleCollection.Add(sourcePowderBottle);
}
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[sourcePowderBottleBoxModel_125Ml.BoxId_inDoseUpload - 1] = sourcePowderBottleBoxModel_125Ml;
});
break;
case BoxTypeEnum._50uLTip头工装:
case BoxTypeEnum._300uLTip头工装:
case BoxTypeEnum._1000uLTip头工装:
TipBoxModel tipBoxModel = new TipBoxModel()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
UseIndex = 96 - uploadData.RemainCount + 1,
TipItems = new ObservableCollection<TipHeadItem>()
};
tipBoxModel.TipType = uploadData.fixtureType == BoxTypeEnum._50uLTip头工装 ? TipTypeEnum._50UL : (uploadData.fixtureType == BoxTypeEnum._300uLTip头工装 ? TipTypeEnum._300UL : TipTypeEnum._1000UL);
for (int i = 0; i < tipBoxModel.UseIndex - 1; i++)
{
tipBoxModel.TipItems.Add(new TipHeadItem() { IsAvailable = false, UseIndex = i + 1 });
}
for (int i = tipBoxModel.UseIndex - 1; i < 96; i++)
{
tipBoxModel.TipItems.Add(new TipHeadItem() { IsAvailable = true, UseIndex = i + 1 });
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[tipBoxModel.BoxId_inDoseUpload - 1] = tipBoxModel;
});
break;
default:
break;
}
}
}
catch (Exception ex)
{
result.data = false; result.msg = ex.Message; result.code = 1;
await msg.ReplyAsync(result.ToJson());
return;
}
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台开始上料指令,返回-{result.ToJson()}");
}
private async Task UnLoad(HttpListenerMessage msg)
{
Response result = new Response() { code = 0, data = true, msg = "" };
string str = msg.GetMessageString();
//string str = await msg.GetRequestBodyStringAsync();
Logger.LogInformation($"{DateTime.Now}收到机台下料完成指令,内容-{str}");
bool isCloseDoor = true;
bool isBSRequest = true;
List<SourcePowderBottleBoxModel> sourcePowderBottleBoxModels = null;
if (!string.IsNullOrEmpty(str))
{
try
{
var unLoadData = JsonConvert.DeserializeObject<UnLoadModel>(str);
sourcePowderBottleBoxModels = unLoadData.sourcePowderBottleBoxModel;
isCloseDoor = !unLoadData.isContinueLoad;
isBSRequest = unLoadData.isBSRequest;
}
catch (Exception ex)
{
result.data = false; result.msg = ex.Message; result.code = 1;
await msg.ReplyAsync(result.ToJson());
return;
}
}
else
{
result.data = false; result.msg = "参数不正确"; result.code = 1;
await msg.ReplyAsync(result.ToJson());
return;
}
for (int i = 0; i < 7; i++)
{
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[i] = new BaseBottleBox()
{
IsEmpty = true,
BoxId_inDoseDnload = i + 1,
BoxId_inDoseUpload = i + 1,
IsDoseFinish = false,
IsUseFinsh = false,
BoxArea = BoxAreaEnum._手套箱传送平台
};
});
}
if (sourcePowderBottleBoxModels != null)
{
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,
});
}
foreach (var sourcePowderBottleBoxModel in sourcePowderBottleBoxModels)
{
switch (sourcePowderBottleBoxModel.FixtureType)
{
case BoxTypeEnum._16mL粉末瓶工装:
var powderList16mL = File_Operator.DeepCopy(powderlist); // 复制集合
foreach (var bottle in powderList16mL)
{
bottle.PowderBottleType = PowderBottleTypeEnum._16mL;
}
var powderBox16mL = new SourcePowderBottleBoxModel
{
FixtureType = sourcePowderBottleBoxModel.FixtureType,
BoxSNCode = sourcePowderBottleBoxModel.BoxSNCode,
SourcePowderBottleCollection = powderList16mL,
IsDoseFinish = false,
IsEmpty = false,
IsUseFinsh = false,
BoxId_inDoseUpload = sourcePowderBottleBoxModel.BoxId_inDoseUpload,
BoxArea = BoxAreaEnum._手套箱传送平台
};
App.Current.Dispatcher.Invoke(() => { ProjectPro.TransferArea[sourcePowderBottleBoxModel.BoxId_inDoseUpload - 1] = powderBox16mL; });
break;
case BoxTypeEnum._125mL粉末瓶工装:
var powderList125mL = File_Operator.DeepCopy(powderlist_125);
foreach (var bottle in powderList125mL)
{
bottle.PowderBottleType = PowderBottleTypeEnum._125mL;
}
var powderBox125mL = new SourcePowderBottleBoxModel_125ml
{
FixtureType = sourcePowderBottleBoxModel.FixtureType,
BoxSNCode = sourcePowderBottleBoxModel.BoxSNCode,
SourcePowderBottleCollection = powderList125mL,
IsDoseFinish = false,
IsEmpty = false,
IsUseFinsh = false,
BoxId_inDoseUpload = sourcePowderBottleBoxModel.BoxId_inDoseUpload,
BoxArea = BoxAreaEnum._手套箱传送平台
};
App.Current.Dispatcher.Invoke(() => { ProjectPro.TransferArea[sourcePowderBottleBoxModel.BoxId_inDoseUpload - 1] = powderBox125mL; });
break;
}
}
}
if (isCloseDoor) await stationService_Dose.ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台下料完成指令,返回-{result.ToJson()}");
//await stationService_Dose.CloseDoor(isCloseDoor, isChangeDeviceState:true);
_ = Task.Run(async() =>
{
if (isCloseDoor)
{
await stationService_Dose.TransferPlateformMoveTo(PlateformPos.TransferIn, new System.Threading.CancellationToken());
}
if (isBSRequest)
{
await stationService_Dose.ChangeDeviceStatus(Entities.DeviceStatus.Idel);
}
else
{
await stationService_Dose.TransferPlateformMoveTo(PlateformPos.TransferIn, new System.Threading.CancellationToken());
await stationService_Dose.ChangeDeviceStatus(Entities.DeviceStatus.Finish);
}
});
}
/// <summary>
/// 验证同步序列数据是否合法
/// </summary>
/// <param name="sampleSeqRequests"></param>
/// <returns></returns>
private (bool isSuccess, string msg) ValidateSampleSeqs(SampleSeqRequest sampleSeq)
{
(bool isSuccess, string msg) result = (true, "");
StringBuilder sb = new StringBuilder();
if(sampleSeq.Config == null || sampleSeq.Config.BoxInfo.Count < 1)
{
sb.AppendLine($"Config不能为空");
return (false, sb.ToString());
}
foreach (var sampleSeqConfig in sampleSeq.Config.BoxInfo)
{
if (sampleSeqConfig.PosInUpload > 7 || sampleSeqConfig.PosInUpload < 1) sb.AppendLine($"PosInUpload只能在1~7");
if (string.IsNullOrEmpty(sampleSeqConfig.SnCode)) sb.AppendLine($"盒子SN码不能为空");
if (sampleSeqConfig.FixtureType == (int)BoxTypeEnum._300uLTip头工装 || sampleSeqConfig.FixtureType == (int)BoxTypeEnum._50uLTip头工装 || sampleSeqConfig.FixtureType == (int)BoxTypeEnum._1000uLTip头工装)
{
if (sampleSeqConfig.RemainCount < 0 || sampleSeqConfig.RemainCount > 96) sb.AppendLine($"tip类型的载具RemainCount需要为1~96");
}
else
{
if (sampleSeq.SampleSeqs == null || sampleSeq.SampleSeqs.Count() < 1)
{
sb.AppendLine("非Tip工装的SampleSeqs不能为空");
return (false, sb.ToString());
}
}
if (sampleSeqConfig.FixtureType < 1) sb.AppendLine($"请传入治具类型FixtureType字段");
}
foreach (var tubeInfo in sampleSeq.SampleSeqs)
{
var sampleSeqConfig = sampleSeq.Config.BoxInfo.FirstOrDefault(s => s.PosInUpload == int.Parse(tubeInfo.Carrier));
if (sampleSeqConfig == null)
{
sb.AppendLine($"{tubeInfo.Carrier}在Config中找不到对应的载具");
continue;
}
if (sampleSeqConfig.FixtureType == (int)BoxTypeEnum._12mL样品工装 || sampleSeqConfig.FixtureType == (int)BoxTypeEnum._5mL样品工装)
{
var carridParseOk = int.TryParse(tubeInfo.Carrier, out int CarrierId);
var posParseOk = int.TryParse(tubeInfo.Pos, out int PosId);
if (!carridParseOk || !posParseOk)
{
sb.AppendLine($"Carrier或者Pos不是数字");
continue;
}
//样品瓶子需要满足样品序列不为空 code作为瓶子信息能为空area需要是A1,carrier需要1~7pos需要1~12
if (CarrierId < 1 || CarrierId > 7 || PosId < 1 || PosId > 12)
{
sb.AppendLine($"对于样品载具Carrier只能是1~7Pos只能是1~12");
}
}
else if (sampleSeqConfig.FixtureType == (int)BoxTypeEnum._40mL原液工装 || sampleSeqConfig.FixtureType == (int)BoxTypeEnum._16mL粉末瓶工装 || sampleSeqConfig.FixtureType == (int)BoxTypeEnum._125mL粉末瓶工装)
{
var carridParseOk = int.TryParse(tubeInfo.Carrier, out int CarrierId);
var posParseOk = int.TryParse(tubeInfo.Pos, out int PosId);
if (!carridParseOk || !posParseOk)
{
sb.AppendLine($"Carrier或者Pos不是数字");
continue;
}
int maxPosVal = sampleSeqConfig.FixtureType == (int)BoxTypeEnum._40mL原液工装 ? 8 : (sampleSeqConfig.FixtureType == (int)BoxTypeEnum._16mL粉末瓶工装 ? 4 : 2);
if (string.IsNullOrEmpty(tubeInfo.Code)) sb.AppendLine($"此工装Code不能为空");
if (CarrierId < 1 || CarrierId > 7 || PosId < 1 || PosId > maxPosVal)
{
sb.AppendLine($"对于载具Carrier只能是1~7Pos只能是1~{maxPosVal}");
}
//if (tubeInfo.SampleConfig.RemainWeight <= 0) sb.AppendLine($"RemainWeight字段不能小于等于0");
}
}
result.msg = sb.ToString();
result.isSuccess = string.IsNullOrEmpty(result.msg);
return result;
}
private (bool isSuccess, string msg) ValidateSampleSeqsEx(SampleSeqRequestEx sampleSeq)
{
(bool isSuccess, string msg) result = (true, "");
StringBuilder sb = new StringBuilder();
if (sampleSeq.Config.BoxInfo == null)
{
sb.AppendLine($"Config不能为空");
return (false, sb.ToString());
}
//var sampleSeqConfig = sampleSeq.Config;
foreach (var sampleSeqConfig in sampleSeq.Config.BoxInfo)
{
if (sampleSeqConfig.PosInUpload > 3 || sampleSeqConfig.PosInUpload < 1) sb.AppendLine($"样品载具只能在1~3");
if (string.IsNullOrEmpty(sampleSeqConfig.SnCode)) sb.AppendLine($"盒子SN码不能为空");
if (sampleSeq.SampleSeqs == null || sampleSeq.SampleSeqs.Count() < 1)
{
sb.AppendLine("SampleSeqs不能为空");
return (false, sb.ToString());
}
if (sampleSeqConfig.FixtureType != (int)BoxTypeEnum._12mL样品工装 && sampleSeqConfig.FixtureType != (int)BoxTypeEnum._5mL样品工装)
{
sb.AppendLine($"样品治具类型FixtureType字段只能位2或3");
return (false, sb.ToString());
}
}
foreach (var tubeInfo in sampleSeq.SampleSeqs)
{
var carridParseOk = int.TryParse(tubeInfo.Carrier, out int CarrierId);
var posParseOk = int.TryParse(tubeInfo.Pos, out int PosId);
if (!carridParseOk || !posParseOk)
{
sb.AppendLine($"Carrier或者Pos不是数字");
continue;
}
//样品瓶子需要满足样品序列不为空 code作为瓶子信息能为空area需要是A1,carrier需要1~7pos需要1~12
if (CarrierId < 1 || CarrierId > 7 || PosId < 1 || PosId > 12)
{
sb.AppendLine($"对于样品载具Carrier只能是1~7Pos只能是1~12");
}
}
result.msg = sb.ToString();
result.isSuccess = string.IsNullOrEmpty(result.msg);
return result;
}
private async Task SyncSeqEx(HttpListenerMessage msg)
{
Response result = new Response() { code = 0, data = true, msg = "" };
string str = msg.GetMessageString();
//string str = await msg.GetRequestBodyStringAsync();
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,内容-{str}");
if (string.IsNullOrEmpty(str))
{
result.code = 1; result.data = false; result.msg = "序列内容不能为空";
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,返回-{result.ToJson()}");
return;
}
try
{
var sampleSeqRequest = JsonConvert.DeserializeObject<SampleSeqRequestEx>(str);
var res = ValidateSampleSeqsEx(sampleSeqRequest);
if (!res.isSuccess)
{
result = new Response() { code = 1, data = false, msg = res.msg };
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,返回-{result.ToJson()}");
return;
}
List<UploadBoxModel> uploadDatas = new List<UploadBoxModel>();
foreach (var sampleSeqConfig in sampleSeqRequest.Config.BoxInfo)
{
UploadBoxModel uploadDataTmp = new UploadBoxModel()
{
boxId_inDoseUpload = sampleSeqConfig.PosInUpload,
boxSNCode = sampleSeqConfig.SnCode,
fixtureType = (BoxTypeEnum)sampleSeqConfig.FixtureType,
sampleBottles = new List<SampleBottleModel>(),
sourceLiquidBottles = new List<SourceLiquidBottleModel>(),
sourcePowderBottles = new List<SourcePowderBottleModel>(),
};
uploadDatas.Add(uploadDataTmp);
foreach (var uploadData in uploadDatas)
{
//var allTubes = sampleSeqRequest.SampleSeqs.Where(s => !string.IsNullOrEmpty(s.Carrier) && s.Carrier.Equals(uploadData.boxId_inDoseUpload.ToString()));
var allTubes = sampleSeqRequest.SampleSeqs.Where(s => s.Carrier.Equals(sampleSeqConfig.PosInUpload.ToString()));
foreach (var tubeInfo in allTubes)
{
SampleBottleModel sampleBottleModel = new SampleBottleModel()
{
SampleSeqId = tubeInfo.SampleSeqId,
SampleBottleType = uploadData.fixtureType == BoxTypeEnum._5mL样品工装 ? SampleBottleTypeEnum._5mL : SampleBottleTypeEnum._12mL,
BoxSNCode = uploadData.boxSNCode,
HaveBottle = true,
PosId_InBox = int.Parse(tubeInfo.Pos),
SampleContentName = tubeInfo.Code,
MaterialDoseFlowList = new ObservableCollection<MaterialDoseFunctionFlow>()
};
if (tubeInfo.SampleConfig != null && tubeInfo.SampleConfig.MaterialDoseFunctionFlow != null)
{
foreach (var item in tubeInfo.SampleConfig.MaterialDoseFunctionFlow)
{
sampleBottleModel.MaterialDoseFlowList.Add(
new MaterialDoseFunctionFlow()
{
FunctionFlowType = (FunctionTypeEnum)item.FunctionFlowType,
UseMaterialName = item.UserMaterialName,
TargetVolume = item.TargetVolumn
}
);
}
}
uploadData.sampleBottles.Add(sampleBottleModel);
}
var sampleBox = new SampleBottleBoxModel()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
SampleBottleList = new ObservableCollection<SampleBottleModel>()
};
for (int i = 0; i < 12; i++)
{
var sampleBottle = uploadData.sampleBottles.FirstOrDefault(s => s.PosId_InBox == i + 1);
if (sampleBottle == null)
{
sampleBottle = new SampleBottleModel();
sampleBottle.HaveBottle = false;
sampleBottle.PosId_InBox = i + 1;
if (sampleBottle.MaterialDoseFlowList == null)
{
sampleBottle.MaterialDoseFlowList = new ObservableCollection<MaterialDoseFunctionFlow>();
}
sampleBox.SampleBottleList.Add(sampleBottle);
}
else
{
sampleBottle.SampleBottleType = uploadData.fixtureType == BoxTypeEnum._12mL样品工装 ? SampleBottleTypeEnum._12mL : SampleBottleTypeEnum._5mL;
sampleBottle.HaveBottle = true;
sampleBottle.BoxSNCode = sampleBox.BoxSNCode;
if (sampleBottle.MaterialDoseFlowList == null)
{
sampleBottle.MaterialDoseFlowList = new ObservableCollection<MaterialDoseFunctionFlow>();
}
sampleBox.SampleBottleList.Add(sampleBottle);
}
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[sampleBox.BoxId_inDoseUpload - 1] = sampleBox;
});
}
}
//var sampleSeqConfig = sampleSeqRequest.Config;
await msg.ReplyAsync(JsonConvert.SerializeObject(result));
Logger.LogInformation($"{DateTime.Now}收到机台开始上料指令,返回-{result.ToJson()}");
}
catch (Exception ex)
{
result.data = false; result.msg = ex.Message; result.code = 1;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,返回-{result.ToJson()}");
}
}
/// <summary>
/// 上料 同步序列
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
private async Task SyncSeq(HttpListenerMessage msg)
{
Response result = new Response() { code = 0, data = true, msg = "" };
string str = msg.GetMessageString();
//string str = await msg.GetRequestBodyStringAsync();
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,内容-{str}");
if (string.IsNullOrEmpty(str))
{
result.code = 1; result.data = false; result.msg = "序列内容不能为空";
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,返回-{result.ToJson()}");
return;
}
try
{
var sampleSeqRequest = JsonConvert.DeserializeObject<SampleSeqRequest>(str);
var res = ValidateSampleSeqs(sampleSeqRequest);
if (!res.isSuccess)
{
result = new Response() { code = 1, data = false, msg = res.msg };
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,返回-{result.ToJson()}");
return;
}
List<UploadBoxModel> uploadDatas = new List<UploadBoxModel>();
foreach (var sampleSeqConfig in sampleSeqRequest.Config.BoxInfo)
{
UploadBoxModel uploadData = new UploadBoxModel()
{
boxId_inDoseUpload = sampleSeqConfig.PosInUpload,
boxSNCode = sampleSeqConfig.SnCode,
fixtureType = (BoxTypeEnum)sampleSeqConfig.FixtureType,
RemainCount = sampleSeqConfig.RemainCount,
sampleBottles = new List<SampleBottleModel>(),
sourceLiquidBottles = new List<SourceLiquidBottleModel>(),
sourcePowderBottles = new List<SourcePowderBottleModel>(),
};
uploadDatas.Add(uploadData);
}
foreach (var uploadData in uploadDatas)
{
var allTubes = sampleSeqRequest.SampleSeqs.Where(s => !string.IsNullOrEmpty(s.Carrier) && s.Carrier.Equals(uploadData.boxId_inDoseUpload.ToString()));
if (uploadData.fixtureType == BoxTypeEnum._40mL原液工装)
{
foreach (var tubeInfo in allTubes)
{
var sourceBottle = new SourceLiquidBottleModel()
{
BoxSNCode = uploadData.boxSNCode,
PosId_InBox = int.Parse(tubeInfo.Pos),
SourceLiquidName = tubeInfo.Code,
//RemainVolume = tubeInfo.SampleConfig.RemainWeight,
//OriginVolume = tubeInfo.SampleConfig.RemainWeight
};
uploadData.sourceLiquidBottles.Add(sourceBottle);
}
}
else if (uploadData.fixtureType == BoxTypeEnum._5mL样品工装 || uploadData.fixtureType == BoxTypeEnum._12mL样品工装)
{
foreach (var tubeInfo in allTubes)
{
SampleBottleModel sampleBottleModel = new SampleBottleModel()
{
SampleSeqId = tubeInfo.SampleSeqId,
SampleBottleType = uploadData.fixtureType == BoxTypeEnum._5mL样品工装 ? SampleBottleTypeEnum._5mL : SampleBottleTypeEnum._12mL,
BoxSNCode = uploadData.boxSNCode,
HaveBottle = true,
PosId_InBox = int.Parse(tubeInfo.Pos),
SampleContentName = tubeInfo.Code,
MaterialDoseFlowList = new ObservableCollection<MaterialDoseFunctionFlow>()
};
if (tubeInfo.SampleConfig != null && tubeInfo.SampleConfig.MaterialDoseFunctionFlow != null)
{
foreach (var item in tubeInfo.SampleConfig.MaterialDoseFunctionFlow)
{
sampleBottleModel.MaterialDoseFlowList.Add(
new MaterialDoseFunctionFlow()
{
FunctionFlowType = (FunctionTypeEnum)item.FunctionFlowType,
UseMaterialName = item.UserMaterialName,
TargetVolume = item.TargetVolumn
}
);
}
}
uploadData.sampleBottles.Add(sampleBottleModel);
}
}
else if (uploadData.fixtureType == BoxTypeEnum._16mL粉末瓶工装 || uploadData.fixtureType == BoxTypeEnum._125mL粉末瓶工装)
{
foreach (var tubeInfo in allTubes)
{
var sourceBottle = new SourcePowderBottleModel()
{
BoxSNCode = uploadData.boxSNCode,
PosId_InBox = int.Parse(tubeInfo.Pos),
SourcePowderName = tubeInfo.Code,
//RemainWeight = tubeInfo.SampleConfig.RemainWeight,
//OriginWeight = tubeInfo.SampleConfig.RemainWeight,
PowderBottleType = uploadData.fixtureType == BoxTypeEnum._16mL粉末瓶工装 ? PowderBottleTypeEnum._16mL : PowderBottleTypeEnum._125mL
};
uploadData.sourcePowderBottles.Add(sourceBottle);
}
}
switch (uploadData.fixtureType)
{
case BoxTypeEnum._40mL原液工装:
var sourceBox = new SourceLiquidBottleBoxModel()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
SourceLiquidBottleCollection = new ObservableCollection<SourceLiquidBottleModel>()
};
for (int i = 0; i < 8; i++)
{
var sourceBottle = uploadData.sourceLiquidBottles.FirstOrDefault(s => s.PosId_InBox == i + 1);
if (sourceBottle == null)
{
sourceBottle = new SourceLiquidBottleModel();
sourceBottle.HaveBottle = false;
sourceBottle.PosId_InBox = i + 1;
sourceBox.SourceLiquidBottleCollection.Add(sourceBottle);
}
else
{
sourceBottle.HaveBottle = true;
sourceBottle.BoxSNCode = sourceBox.BoxSNCode;
sourceBox.SourceLiquidBottleCollection.Add(sourceBottle);
}
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[sourceBox.BoxId_inDoseUpload - 1] = sourceBox;
});
break;
case BoxTypeEnum._12mL样品工装:
case BoxTypeEnum._5mL样品工装:
var sampleBox = new SampleBottleBoxModel()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
SampleBottleList = new ObservableCollection<SampleBottleModel>()
};
for (int i = 0; i < 12; i++)
{
var sampleBottle = uploadData.sampleBottles.FirstOrDefault(s => s.PosId_InBox == i + 1);
if (sampleBottle == null)
{
sampleBottle = new SampleBottleModel();
sampleBottle.HaveBottle = false;
sampleBottle.PosId_InBox = i + 1;
if (sampleBottle.MaterialDoseFlowList == null)
{
sampleBottle.MaterialDoseFlowList = new ObservableCollection<MaterialDoseFunctionFlow>();
}
sampleBox.SampleBottleList.Add(sampleBottle);
}
else
{
sampleBottle.SampleBottleType = uploadData.fixtureType == BoxTypeEnum._12mL样品工装 ? SampleBottleTypeEnum._12mL : SampleBottleTypeEnum._5mL;
sampleBottle.HaveBottle = true;
sampleBottle.BoxSNCode = sampleBox.BoxSNCode;
if (sampleBottle.MaterialDoseFlowList == null)
{
sampleBottle.MaterialDoseFlowList = new ObservableCollection<MaterialDoseFunctionFlow>();
}
sampleBox.SampleBottleList.Add(sampleBottle);
}
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[sampleBox.BoxId_inDoseUpload - 1] = sampleBox;
});
break;
case BoxTypeEnum._16mL粉末瓶工装:
var sourcePowderBottleBoxModel = new SourcePowderBottleBoxModel()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
SourcePowderBottleCollection = new ObservableCollection<SourcePowderBottleModel>()
};
for (int i = 0; i < 4; i++)
{
var sourcePowderBottle = uploadData.sourcePowderBottles.FirstOrDefault(s => s.PosId_InBox == i + 1);
if (sourcePowderBottle == null)
{
sourcePowderBottle = new SourcePowderBottleModel();
sourcePowderBottle.PosId_InBox = i + 1;
sourcePowderBottle.HaveBottle = false;
sourcePowderBottle.PowderBottleType = PowderBottleTypeEnum._16mL;
sourcePowderBottleBoxModel.SourcePowderBottleCollection.Add(sourcePowderBottle);
}
else
{
sourcePowderBottle.PowderBottleType = PowderBottleTypeEnum._16mL;
sourcePowderBottle.HaveBottle = true;
sourcePowderBottle.BoxSNCode = sourcePowderBottleBoxModel.BoxSNCode;
sourcePowderBottleBoxModel.SourcePowderBottleCollection.Add(sourcePowderBottle);
}
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[sourcePowderBottleBoxModel.BoxId_inDoseUpload - 1] = sourcePowderBottleBoxModel;
});
break;
case BoxTypeEnum._125mL粉末瓶工装:
var sourcePowderBottleBoxModel_125Ml = new SourcePowderBottleBoxModel_125ml()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
SourcePowderBottleCollection = new ObservableCollection<SourcePowderBottleModel>()
};
for (int i = 0; i < 2; i++)
{
var sourcePowderBottle = uploadData.sourcePowderBottles.FirstOrDefault(s => s.PosId_InBox == i + 1);
if (sourcePowderBottle == null)
{
sourcePowderBottle = new SourcePowderBottleModel();
sourcePowderBottle.PosId_InBox = i + 1;
sourcePowderBottle.HaveBottle = false;
sourcePowderBottle.PowderBottleType = PowderBottleTypeEnum._125mL;
sourcePowderBottleBoxModel_125Ml.SourcePowderBottleCollection.Add(sourcePowderBottle);
}
else
{
sourcePowderBottle.PowderBottleType = PowderBottleTypeEnum._125mL;
sourcePowderBottle.HaveBottle = true;
sourcePowderBottle.BoxSNCode = sourcePowderBottleBoxModel_125Ml.BoxSNCode;
sourcePowderBottleBoxModel_125Ml.SourcePowderBottleCollection.Add(sourcePowderBottle);
}
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[sourcePowderBottleBoxModel_125Ml.BoxId_inDoseUpload - 1] = sourcePowderBottleBoxModel_125Ml;
});
break;
case BoxTypeEnum._50uLTip头工装:
case BoxTypeEnum._300uLTip头工装:
case BoxTypeEnum._1000uLTip头工装:
TipBoxModel tipBoxModel = new TipBoxModel()
{
BoxId_inDoseUpload = uploadData.boxId_inDoseUpload,
FixtureType = uploadData.fixtureType,
BoxArea = BoxAreaEnum._手套箱传送平台,
BoxSNCode = uploadData.boxSNCode,
IsEmpty = false,
IsUseFinsh = false,
UseIndex = 96 - uploadData.RemainCount + 1,
TipItems = new ObservableCollection<TipHeadItem>()
};
tipBoxModel.TipType = uploadData.fixtureType == BoxTypeEnum._50uLTip头工装 ? TipTypeEnum._50UL : (uploadData.fixtureType == BoxTypeEnum._300uLTip头工装 ? TipTypeEnum._300UL : TipTypeEnum._1000UL);
for (int i = 0; i < tipBoxModel.UseIndex - 1; i++)
{
tipBoxModel.TipItems.Add(new TipHeadItem() { IsAvailable = false, UseIndex = i + 1 });
}
for (int i = tipBoxModel.UseIndex - 1; i < 96; i++)
{
tipBoxModel.TipItems.Add(new TipHeadItem() { IsAvailable = true, UseIndex = i + 1 });
}
App.Current.Dispatcher.Invoke(() =>
{
ProjectPro.TransferArea[tipBoxModel.BoxId_inDoseUpload - 1] = tipBoxModel;
});
break;
default:
break;
}
}
await msg.ReplyAsync(JsonConvert.SerializeObject(result));
Logger.LogInformation($"{DateTime.Now}收到机台开始上料指令,返回-{result.ToJson()}");
}
catch (Exception ex)
{
result.data = false; result.msg = ex.Message; result.code = 1;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,返回-{result.ToJson()}");
}
}
/// <summary>
/// 上料 同步序列
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
[Obsolete("弃用请使用SyncSeq")]
private async Task SyncSeq_old(HttpListenerMessage msg)
{
Response result = new Response() { code = 0, data = true, msg = ""};
string str = msg.GetMessageString();
//string str = await msg.GetRequestBodyStringAsync();
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,内容-{str}");
if (string.IsNullOrEmpty(str))
{
result.data = false; result.msg = "序列内容不能为空";
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,返回-{result.ToJson()}");
return;
}
try
{
var sampleBottles = JsonConvert.DeserializeObject<List<SampleBottleModel>>(str);
if (sampleBottles.Any(s => string.IsNullOrEmpty(s.SampleContentName)))
{
result.data = false; result.msg = "序列SampleContentName字段不能为空";
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,返回-{result.ToJson()}");
return;
}
List<SampleBottleModel> allSampleBottles = new List<SampleBottleModel>();
var sampleBoxs = ProjectPro.FixtureCacheArea.Where(fx => !fx.IsEmpty && (fx.FixtureType == BoxTypeEnum._12mL样品工装 || fx.FixtureType == BoxTypeEnum._5mL样品工装));
foreach (var sampleBox in sampleBoxs)
{
var sampleBoxtransfer = sampleBox as SampleBottleBoxModel;
allSampleBottles.AddRange(sampleBoxtransfer.SampleBottleList.Where(s => s.HaveBottle));
}
if (allSampleBottles.Count < sampleBottles.Count)
{
result.data = false; result.msg = "工单个数大于可用的空瓶数目";
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,返回-{result.ToJson()}");
return;
}
App.Current.Dispatcher.Invoke(() =>
{
for (int i = 0; i < sampleBottles.Count; i++)
{
allSampleBottles[i].SampleContentName = sampleBottles[i].SampleContentName;
allSampleBottles[i].MaterialDoseFlowList = sampleBottles[i].MaterialDoseFlowList;
}
});
result.msg = $"接口调用成功";
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,返回-{result.ToJson()}");
}
catch (Exception ex)
{
result.data = false; result.msg = ex.Message;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台同步序列指令,返回-{result.ToJson()}");
}
/*
//从BS中收到序列反序列到自己的类
this.UpdateBoxInfo_BS?.Invoke(null, new SampleBottleBoxModel()
{
BoxId_inDoseUpload = 1,
BoxArea = BoxAreaEnum._手套箱传送平台,
FixtureType = BoxTypeEnum._12mL样品工装,
IsDoseFinish = false,
IsUseFinsh = false,
BoxSNCode = "BS20240612001",
SampleBottleList = new ObservableCollection<SampleBottleModel>()
{
new SampleBottleModel()
{
HaveBottle=true,
SNCode="SAMPLE20240612001",
PosId_InBox=1,
},
new SampleBottleModel()
{
HaveBottle=true,
SNCode="SAMPLE20240612002",
PosId_InBox=2,
},
},
});
*/
}
/// <summary>
/// 添加序列
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
private async Task AddSeq(HttpListenerMessage msg)
{
Response result = new Response() { code = 0, data = true, msg = "" };
string str = msg.GetMessageString();
//string str = await msg.GetRequestBodyStringAsync();
Logger.LogInformation($"{DateTime.Now}收到机台增加序列指令,内容-{str}");
if (string.IsNullOrEmpty(str))
{
result.data = false; result.msg = "序列内容不能为空"; result.code = 1;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台增加序列指令,返回-{result.ToJson()}");
return;
}
try
{
var sampleBottles = JsonConvert.DeserializeObject<List<SampleBottleModel>>(str);
if (sampleBottles.Any(s => string.IsNullOrEmpty(s.SampleContentName)))
{
result.data = false; result.msg = "序列SampleContentName字段不能为空"; result.code = 1;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台增加序列指令,返回-{result.ToJson()}");
return;
}
var allSampleBottles = ProjectPro.FixtureCacheArea
.Where(fx => !fx.IsEmpty && (fx.FixtureType == BoxTypeEnum._12mL样品工装 || fx.FixtureType == BoxTypeEnum._5mL样品工装))
.OfType<SampleBottleBoxModel>()
.SelectMany(box => box.SampleBottleList)
.Where(item => item.HaveBottle && (item.MaterialDoseFlowList == null || item.MaterialDoseFlowList.Count == 0))
.ToList();
if (allSampleBottles.Count < sampleBottles.Count)
{
result.data = false; result.msg = "工单个数大于可用的空瓶数目"; result.code = 1;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台增加序列指令,返回-{result.ToJson()}");
return;
}
App.Current.Dispatcher.Invoke(() =>
{
for (int i = 0; i < sampleBottles.Count; i++)
{
allSampleBottles[i].SampleContentName = sampleBottles[i].SampleContentName;
allSampleBottles[i].MaterialDoseFlowList = sampleBottles[i].MaterialDoseFlowList;
}
});
result.msg = $"接口调用成功";
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台增加序列指令,返回-{result.ToJson()}");
}
catch (Exception ex)
{
result.data = false; result.msg = ex.Message; result.code = 1;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台增加序列指令,返回-{result.ToJson()}");
}
}
/// <summary>
/// 取消序列执行
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
private async Task DeleteSeq(HttpListenerMessage msg)
{
Response result = new Response() { code = 0, data = true, msg = "" };
string str = msg.GetMessageString();
//string str = await msg.GetRequestBodyStringAsync();
Logger.LogInformation($"{DateTime.Now}收到机台删除序列指令,内容-{str}");
if (string.IsNullOrEmpty(str))
{
result.data = false; result.msg = "序列内容不能为空"; result.code = 1;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台删除序列指令,返回-{result.ToJson()}");
return;
}
try
{
var sampleBottles = JsonConvert.DeserializeObject<List<SampleBottleModel>>(str);
if (sampleBottles.Any(s => string.IsNullOrEmpty(s.SampleContentName)))
{
result.data = false; result.msg = "序列SampleContentName字段不能为空";
await msg.ReplyAsync(result.ToJson()); result.code = 1;
Logger.LogInformation($"{DateTime.Now}收到机台删除序列指令,返回-{result.ToJson()}");
return;
}
var allSampleBottles = ProjectPro.FixtureCacheArea
.Where(fx => !fx.IsEmpty && (fx.FixtureType == BoxTypeEnum._12mL样品工装 || fx.FixtureType == BoxTypeEnum._5mL样品工装))
.OfType<SampleBottleBoxModel>()
.SelectMany(box => box.SampleBottleList)
.Where(item => item.HaveBottle)
.ToList();
App.Current.Dispatcher.Invoke(() =>
{
foreach (var sampleBottle in sampleBottles)
{
var findBottle = allSampleBottles.FirstOrDefault(x => !string.IsNullOrEmpty(x.SampleContentName) && x.SampleContentName.Equals(sampleBottle.SampleContentName));
if (findBottle != null)
{
findBottle.SampleContentName = "";
findBottle.MaterialDoseFlowList = new ObservableCollection<MaterialDoseFunctionFlow>();
}
else
{
result.data = false;
result.msg = $"未找到名称为-{sampleBottle.SampleContentName}的序列\n";
}
}
});
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台删除序列指令,返回-{result.ToJson()}");
}
catch (Exception ex)
{
result.data = false; result.msg = ex.Message; result.code = 1;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台删除序列指令,返回-{result.ToJson()}");
}
}
public (bool isSuccess, string msg) ValidateSampleBottle()
{
(bool isSuccess, string msg) result = (true,"");
var allSampleBottles = ProjectPro.FixtureCacheArea
.Where(fx => !fx.IsEmpty && (fx.FixtureType == BoxTypeEnum._12mL样品工装 || fx.FixtureType == BoxTypeEnum._5mL样品工装))
.OfType<SampleBottleBoxModel>()
.SelectMany(box => box.SampleBottleList)
.Where(item => item.HaveBottle && item.MaterialDoseFlowList != null && item.MaterialDoseFlowList.Count > 0)
.ToList();
if (allSampleBottles == null || allSampleBottles.Count < 1) return (false,"没有需要执行的样品!");
//todo:母液以及粉末都需要有
var allSourceBottles = ProjectPro.FixtureCacheArea
.Where(fx => !fx.IsEmpty && (fx.FixtureType == BoxTypeEnum._40mL原液工装))
.OfType<SourceLiquidBottleBoxModel>()
.SelectMany(box => box.SourceLiquidBottleCollection)
.Where(item => item.HaveBottle && !string.IsNullOrEmpty(item.SourceLiquidName))
.ToList();
int needTipCount = 0; int allTipCount = 0;
foreach (var bottle in allSampleBottles)
{
foreach (var addMaterial in bottle.MaterialDoseFlowList)
{
if (addMaterial.FunctionFlowType == FunctionTypeEnum.)
{
if (allSourceBottles.All(b => !b.SourceLiquidName.Equals(addMaterial.UseMaterialName)))
{
result.isSuccess = false; result.msg += $"{addMaterial.UseMaterialName}在原液区域找不到!";
}
needTipCount++;
}
else
{
if (ProjectPro.PowderHeaderCacheArea.All(p => !addMaterial.UseMaterialName.Equals(p.SourcePowderName)))
{
result.isSuccess = false;result.msg += $"{addMaterial.UseMaterialName}在粉末区域找不到!";
}
}
}
}
//todo:需要有tip确保tip足够
for (int i = 0;i<3; i++)
{
var tipFix = ProjectPro.TipHeadArea[i];
if (!tipFix.HaveBox) continue;
allTipCount += tipFix.TipItems.Count(t => t.IsAvailable);
}
if (needTipCount > allTipCount)
{
result.isSuccess = false; result.msg += $"tip不够需要{needTipCount}个现在一共{allTipCount}个!";
}
return result;
}
/// <summary>
/// 机台控制
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
private async Task MachineControl(HttpListenerMessage msg)
{
Response result = new Response() { code = 0, data = true, msg = "" };
string str = msg.GetMessageString();
//string str = await msg.GetRequestBodyStringAsync();
Logger.LogInformation($"{DateTime.Now}收到机台控制指令,内容-{str}");
if (string.IsNullOrEmpty(str))
{
result.data = false; result.msg = "未知命令"; result.code = 1;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台控制指令,返回-{result.ToJson()}");
return;
}
try
{
var controlCmd = JsonConvert.DeserializeObject<ControlCmd>(str);
switch (controlCmd.command)
{
//start,pause,resume,stop,init, reset, opendoor,load
case "init":
await stationService_Dose.ChangeDeviceStatus(Entities.DeviceStatus.Runing);
await stationService_Dose.WriteCmdToPlc("init");
break;
case "reset":
await stationService_Dose.WriteCmdToPlc("reset");
break;
case "start":
//todo需要做数据校验确保粉末、液体都能找到且数量是足够的
if (stationService_Dose.StationProp.deviceStatus != Entities.DeviceStatus.Idel)
{
result.data = false; result.msg = "设备不在就绪状态";
}
else
{
var res = ValidateSampleBottle();
result.data = res.isSuccess; result.msg = res.msg;
if (res.isSuccess)
{
await stationService_Dose.ChangeDeviceStatus(Entities.DeviceStatus.Runing);
await stationService_Dose.WriteCmdToPlc("start");
}
}
break;
case "pause":
if (stationService_Dose.StationProp.deviceStatus == Entities.DeviceStatus.Runing)
{
await stationService_Dose.ChangeDeviceStatus(Entities.DeviceStatus.Pause);
await stationService_Dose.WriteCmdToPlc("pause");
}
else
{
result.data = false; result.msg = "设备没有运行,不需要暂停"; result.code = 1;
}
//todo:向PLC发送状态
break;
case "resume":
if (stationService_Dose.StationProp.deviceStatus == Entities.DeviceStatus.Pause)
{
await stationService_Dose.ChangeDeviceStatus(Entities.DeviceStatus.Runing);
await stationService_Dose.WriteCmdToPlc("start");
}
else
{
result.data = false; result.msg = "设备没有暂停,不需要恢复"; result.code = 1;
}
//todo:向PLC发送启动
break;
case "stop":
if (stationService_Dose.StationProp.deviceStatus == Entities.DeviceStatus.Runing || stationService_Dose.StationProp.deviceStatus == Entities.DeviceStatus.Pause)
{
await stationService_Dose.ChangeDeviceStatus(Entities.DeviceStatus.Abort);
}
else
{
result.data = false; result.msg = "设备没有运行或暂停,不需要取消"; result.code = 1;
}
break;
case "opendoor":
await OpenDoor(msg);
return;
case "load":
await this.stationService_Dose.ChangeDeviceStatus(Entities.DeviceStatus.CarryOn);
await msg.ReplyAsync(JsonConvert.SerializeObject(result));
Logger.LogInformation($"{DateTime.Now}收到机台开始上料指令,返回-{result.ToJson()}");
_ = Task.Run(async () =>
{
await stationService_Dose.StartLoad();
await stationService_Dose.SendJson((new Guid()).ToString(), "loadsuccess", "");
});
return;
default:
result.data = false; result.msg = "未知命令";result.code = 1;
break;
}
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台控制指令,返回-{result.ToJson()}");
}
catch (Exception ex)
{
result.data = false;result.msg = ex.Message; result.code = 1;
await msg.ReplyAsync(result.ToJson());
Logger.LogInformation($"{DateTime.Now}收到机台控制指令,返回-{result.ToJson()}");
}
}
#region
internal T ConvertApiInputArgs<T>(HttpListenerMessage msg) where T : class
{
try
{
string inputJson = msg.GetMessageString();
//string inputJson = msg.GetRequestBodyStringAsync().GetAwaiter().GetResult();
if (!this._appConfigService.BlockKeywords.Contains(msg.Request.Url.Segments[^1]))
this.Logger.LogInformation($"API:{msg.Request.Url};Args:{inputJson}");
T request = inputJson.FromJson<T>(); //转换入参数据为实际实体模型对象
return request;
}
catch (Exception ex)
{
this.Logger.LogException(ex);
}
return null;
}
#endregion
}
}