Files
tnb.server/ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs
2024-06-11 13:41:56 +08:00

1657 lines
85 KiB
C#

using System;
using System.Data;
using System.DirectoryServices.ActiveDirectory;
using System.Dynamic;
using System.Security.Cryptography.X509Certificates;
using System.Security.Policy;
using System.Text;
using System.Text.RegularExpressions;
using Aop.Api.Domain;
using Aspose.Cells.Charts;
using JNPF;
using JNPF.Common.Cache;
using JNPF.Common.Core.Manager;
using JNPF.Common.Dtos.VisualDev;
using JNPF.Common.Extension;
using JNPF.Common.Security;
using JNPF.FriendlyException;
using JNPF.Systems.Interfaces.System;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NetTaste;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.OpenXmlFormats;
using NPOI.SS.Formula.Eval;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X509.Qualified;
using Qiniu.Util;
using Senparc.CO2NET.Helpers.Serializers;
using SqlSugar;
//using Swashbuckle.AspNetCore.SwaggerGen;
using Tnb.BasicData.Entities;
using Tnb.Common.Extension;
using Tnb.Common.Redis;
using Tnb.Common.Utils;
using Tnb.ProductionMgr.Entities;
using Tnb.ProductionMgr.Entities.Dto;
using Tnb.ProductionMgr.Entities.Enums;
using Tnb.ProductionMgr.Interfaces;
using Tnb.WarehouseMgr.Entities;
using Tnb.WarehouseMgr.Entities.Configs;
using Tnb.WarehouseMgr.Entities.Consts;
using Tnb.WarehouseMgr.Entities.Dto;
using Tnb.WarehouseMgr.Entities.Dto.Inputs;
using Tnb.WarehouseMgr.Entities.Entity;
using Tnb.WarehouseMgr.Entities.Enums;
using Tnb.WarehouseMgr.Interfaces;
namespace Tnb.ProductionMgr
{
//redis定时获取数采数据
public class RedisBackGround : IHostedService, IDisposable
{
private Timer? Readtimer;
private Timer? CheckGettimer;
private Timer? Scantimer;
private Timer? SSXcodetimer;
// 八工位缓存区补充空托盘
private Timer? BGWCarrySupplementtimer;
// 供料叠盘机空托盘自动入库
private Timer? YCLGLDPJInstocktimer;
// 外协叠盘机空托盘自动入库
private Timer? YCLWXDPJInstocktimer;
// 二楼上升降机
private Timer? Floor2UpMachinecodetimer;
// 二楼料架配送
private Timer? Floor2timer送空托到上升降区;
private Timer? Floor2timer送满托到下升降区;
private Timer? Floor2timer移走上升降区未生成预任务且满托的料架;
private Timer? Floor2timer移走下升降区未生成预任务且空托的料架;
// 7号线补充空料箱
//private Timer? SSX7Supplementtimer;
public SemaphoreSlim s_taskExecuteFloor2UpMachinecodetimer = new(1);
public SemaphoreSlim s_task送空托到上升降区 = new(1);
public SemaphoreSlim s_task送满托到下升降区 = new(1);
public SemaphoreSlim s_task移走上升降区未生成预任务且满托的料架 = new(1);
public SemaphoreSlim s_task移走下升降区未生成预任务且空托的料架 = new(1);
private StackExRedisHelper _redisData;
private readonly IPrdInstockService _prdInstockService;
private readonly ISqlSugarRepository<RedisReadConfig> _repository;
private readonly IWmsPDAScanInStockService _wmsPDAScanInStock;
private readonly IUserManager _userManager;
private readonly IBillRullService _billRullService;
private readonly IWareHouseService _wareHouseService;
private readonly IWmsCarryBindService _wmsCarryBindService;
private readonly IWmsEmptyOutstockService _wmsEmptyOutstockService;
private readonly ElevatorControlConfiguration _eleCtlCfg = App.Configuration.Build<ElevatorControlConfiguration>();
public RedisBackGround(StackExRedisHelper redisData, IPrdInstockService prdInstockService, ISqlSugarRepository<RedisReadConfig> repository, IWmsPDAScanInStockService wmsPDAScanInStock
, IUserManager userManager, IBillRullService billRullService, IWareHouseService wareHouseService, IWmsCarryBindService wmsCarryBindService, IWmsEmptyOutstockService wmsEmptyOutstockService)
{
_redisData = redisData;
_prdInstockService = prdInstockService;
_repository = repository;
_wmsPDAScanInStock = wmsPDAScanInStock;
_userManager = userManager;
_billRullService = billRullService;
_wareHouseService = wareHouseService;
_wmsCarryBindService = wmsCarryBindService;
_wmsEmptyOutstockService = wmsEmptyOutstockService;
//_redisData.rcvMsg += _redisData_rcvMsg;
}
//ctu取货
private async void CheckGet(object? state)
{
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 执行CheckGet");
Dictionary<string, string[]> getdic = new Dictionary<string, string[]>();
getdic.Add("SSX-021-005", new string[] { "YTCS", "AllowFullOut_CS05", "LiftCode" });
getdic.Add("SSX-011-002", new string[] { "YTCS", "AllowAgvFullIn_CS02", "Code_CS02" });
getdic.Add("SSX-011-004", new string[] { "YTCS", "AllowCtuFullOut_CS04", "Code_CS04" });
getdic.Add("SSX-011-008", new string[] { "东面提升机输送线", "入库输送线8允许出箱", "入库输送线8条码" });
getdic.Add("SSX-111-011", new string[] { "东面提升机输送线", "下升降机11允许出箱", "下升降机11条码" });
getdic.Add("SSX-111-012", new string[] { "东面提升机输送线", "下升降机12允许出箱", "下升降机12条码" });
getdic.Add("ZSSSXCTU02", new string[] { "YTCS", "AllowAgvEmptyOut_CS03", "" });
getdic.Add("ZSSSXCTU01", new string[] { "YTCS", "AllowAgvEmptyOut_CS01", "" });
foreach (var key in getdic.Keys)
{
try
{
var strs = getdic.Where(p => p.Key == key).First().Value;
bool result = await GetBoolTag(strs[0], strs[1]);
if (result)
{
if (!string.IsNullOrEmpty(strs[2]))
{
string coderesult = await GetStringTag(strs[0], strs[2]);
coderesult = coderesult.Replace("\r", "").Replace("\\r", "").Replace(" ", "");
if (string.IsNullOrEmpty(coderesult))
{
continue;
}
Logger.LogInformation($@"【定时任务CheckGet】 成功取到{strs[2]}值:{coderesult}");
using (var _db = _repository.AsSugarClient().CopyNew())
{
var DistaskH = _db.Queryable<WmsDistaskH>().Where(p => p.carry_code == coderesult && p.status == WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID && string.IsNullOrEmpty(p.extras)).First();
if (DistaskH != null)
{
Logger.LogInformation($@"【定时任务CheckGet】 成功找到载具:{coderesult} 对应的任务执行单{DistaskH.bill_code}");
dynamic reqBody = new ExpandoObject();
reqBody.taskCode = DistaskH.bill_code;
reqBody.slotCode = key;
reqBody.containerCode = coderesult;
CancellationTokenSource Ctu = new();
Logger.LogInformation($"【定时任务CheckGet】 开始发送请求到 http://192.168.11.104:1880/wcs/notify/cargo 载具:{coderesult}");
dynamic respBody = HttpClientHelper.PostStreamAsync("http://192.168.11.104:1880/wcs/notify/cargo", reqBody, Ctu.Token).Result;
Logger.LogInformation($"【定时任务CheckGet】 接收请求 http://192.168.11.104:1880/wcs/notify/cargo 结果 {respBody} ");
DistaskH.extras = respBody;
_db.Updateable(DistaskH).ExecuteCommand();
Ctu.Dispose();
}
else
{
LoggerSSX.LogInformation($@"【定时任务CheckGet】 {key}->{strs[0]} {strs[2]}
采集结果:{$@"(wms_distask_h) (carry_code){coderesult}
(status)(26126853976101) (extras)
select extras,* from wms_distask_h
where carry_code = '{coderesult}' and status = '{WmsWareHouseConst.TASK_BILL_STATUS_YXD_ID}' "}");
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("【CheckGet】" + ex.Message);
LoggerSSX.LogError(ex.ToString());
}
}
}
private static readonly Dictionary<LogLevel, string> s_logLevelMap = new()
{
[LogLevel.Debug] = "DBG",
[LogLevel.Information] = "INF",
[LogLevel.Warning] = "WRN",
[LogLevel.Error] = "ERR",
};
#region
protected ILogger Logger => LoggerFactory.Create(builder => builder.AddFile($"{AppContext.BaseDirectory}/logs/custom{DateTime.Now:yyyyMMdd}.log", cfgOpts =>
{
//cfgOpts.DateFormat = "yyyy-MM-dd HH:mm:ss.fff";
cfgOpts.MessageFormat = (logMsg) =>
{
var logLevel = s_logLevelMap[logMsg.LogLevel];
var sb = new StringBuilder();
_ = sb.Append($"[{logLevel}] ");
_ = sb.Append($"{logMsg.LogName} ");
_ = sb.Append($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} ");
_ = sb.Append($"#{logMsg.EventId.Id} ");
_ = sb.Append(logMsg.Message + " ");
_ = sb.Append(logMsg.Exception?.ToString());
return sb.ToString();
};
})).CreateLogger(this.GetType());
protected ILogger LoggerBGW => LoggerFactory.Create(builder => builder.AddFile($"{AppContext.BaseDirectory}/logs/customBGW{DateTime.Now:yyyyMMdd}.log", cfgOpts =>
{
//cfgOpts.DateFormat = "yyyy-MM-dd HH:mm:ss.fff";
cfgOpts.MessageFormat = (logMsg) =>
{
var logLevel = s_logLevelMap[logMsg.LogLevel];
var sb = new StringBuilder();
_ = sb.Append($"[{logLevel}] ");
_ = sb.Append($"{logMsg.LogName} ");
_ = sb.Append($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} ");
_ = sb.Append($"#{logMsg.EventId.Id} ");
_ = sb.Append(logMsg.Message + " ");
_ = sb.Append(logMsg.Exception?.ToString());
return sb.ToString();
};
})).CreateLogger(this.GetType());
protected ILogger LoggerSSX => LoggerFactory.Create(builder => builder.AddFile($"{AppContext.BaseDirectory}/logs/customSSX{DateTime.Now:yyyyMMdd}.log", cfgOpts =>
{
//cfgOpts.DateFormat = "yyyy-MM-dd HH:mm:ss.fff";
cfgOpts.MessageFormat = (logMsg) =>
{
var logLevel = s_logLevelMap[logMsg.LogLevel];
var sb = new StringBuilder();
_ = sb.Append($"[{logLevel}] ");
_ = sb.Append($"{logMsg.LogName} ");
_ = sb.Append($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} ");
_ = sb.Append($"#{logMsg.EventId.Id} ");
_ = sb.Append(logMsg.Message + " ");
_ = sb.Append(logMsg.Exception?.ToString());
return sb.ToString();
};
})).CreateLogger(this.GetType());
// 二楼上下升降机日志
protected ILogger LoggerFloor2UpDownMachine => LoggerFactory.Create(builder => builder.AddFile($"{AppContext.BaseDirectory}/logs/customFloor2UpDownMachine{DateTime.Now:yyyyMMdd}.log", cfgOpts =>
{
//cfgOpts.DateFormat = "yyyy-MM-dd HH:mm:ss.fff";
cfgOpts.MessageFormat = (logMsg) =>
{
var logLevel = s_logLevelMap[logMsg.LogLevel];
var sb = new StringBuilder();
_ = sb.Append($"[{logLevel}] ");
_ = sb.Append($"{logMsg.LogName} ");
_ = sb.Append($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} ");
_ = sb.Append($"#{logMsg.EventId.Id} ");
_ = sb.Append(logMsg.Message + " ");
_ = sb.Append(logMsg.Exception?.ToString());
return sb.ToString();
};
})).CreateLogger(this.GetType());
// 二楼料架补充
protected ILogger LoggerFloor2RackDelivery => LoggerFactory.Create(builder => builder.AddFile($"{AppContext.BaseDirectory}/logs/customFloor2RackDelivery{DateTime.Now:yyyyMMdd}.log", cfgOpts =>
{
//cfgOpts.DateFormat = "yyyy-MM-dd HH:mm:ss.fff";
cfgOpts.MessageFormat = (logMsg) =>
{
var logLevel = s_logLevelMap[logMsg.LogLevel];
var sb = new StringBuilder();
_ = sb.Append($"[{logLevel}] ");
_ = sb.Append($"{logMsg.LogName} ");
_ = sb.Append($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} ");
_ = sb.Append($"#{logMsg.EventId.Id} ");
_ = sb.Append(logMsg.Message + " ");
_ = sb.Append(logMsg.Exception?.ToString());
return sb.ToString();
};
})).CreateLogger(this.GetType());
protected ILogger LoggerBGWCarrySupplement => LoggerFactory.Create(builder => builder.AddFile($"{AppContext.BaseDirectory}/logs/customBGWCarrySupplement{DateTime.Now:yyyyMMdd}.log", cfgOpts =>
{
//cfgOpts.DateFormat = "yyyy-MM-dd HH:mm:ss.fff";
cfgOpts.MessageFormat = (logMsg) =>
{
var logLevel = s_logLevelMap[logMsg.LogLevel];
var sb = new StringBuilder();
_ = sb.Append($"[{logLevel}] ");
_ = sb.Append($"{logMsg.LogName} ");
_ = sb.Append($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} ");
_ = sb.Append($"#{logMsg.EventId.Id} ");
_ = sb.Append(logMsg.Message + " ");
_ = sb.Append(logMsg.Exception?.ToString());
return sb.ToString();
};
})).CreateLogger(this.GetType());
protected ILogger LoggerSSX7Supplementtimer => LoggerFactory.Create(builder => builder.AddFile($"{AppContext.BaseDirectory}/logs/customSSX7Supplementtimer{DateTime.Now:yyyyMMdd}.log", cfgOpts =>
{
//cfgOpts.DateFormat = "yyyy-MM-dd HH:mm:ss.fff";
cfgOpts.MessageFormat = (logMsg) =>
{
var logLevel = s_logLevelMap[logMsg.LogLevel];
var sb = new StringBuilder();
_ = sb.Append($"[{logLevel}] ");
_ = sb.Append($"{logMsg.LogName} ");
_ = sb.Append($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} ");
_ = sb.Append($"#{logMsg.EventId.Id} ");
_ = sb.Append(logMsg.Message + " ");
_ = sb.Append(logMsg.Exception?.ToString());
return sb.ToString();
};
})).CreateLogger(this.GetType());
protected ILogger LoggerYCLGLDPJInstock => LoggerFactory.Create(builder => builder.AddFile($"{AppContext.BaseDirectory}/logs/customYCLGLDPJInstock{DateTime.Now:yyyyMMdd}.log", cfgOpts =>
{
//cfgOpts.DateFormat = "yyyy-MM-dd HH:mm:ss.fff";
cfgOpts.MessageFormat = (logMsg) =>
{
var logLevel = s_logLevelMap[logMsg.LogLevel];
var sb = new StringBuilder();
_ = sb.Append($"[{logLevel}] ");
_ = sb.Append($"{logMsg.LogName} ");
_ = sb.Append($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} ");
_ = sb.Append($"#{logMsg.EventId.Id} ");
_ = sb.Append(logMsg.Message + " ");
_ = sb.Append(logMsg.Exception?.ToString());
return sb.ToString();
};
})).CreateLogger(this.GetType());
#endregion
#region
//扫码入库
private async void ScanInStock(object? state)
{
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 执行ScanInStock");
Dictionary<string, string[]> getdic = new Dictionary<string, string[]>();
getdic.Add("BGWRKYCL02", new string[] { "CP8", "AllowGetFullBox1", "code1", "PutDoneEmptyBox", "false" });
getdic.Add("BGWRKYCL01", new string[] { "CP8", "AllowGetFullBox2", "code2", "PutDoneEmptyBox", "false" });
foreach (var key in getdic.Keys)
{
try
{
var strs = getdic.Where(p => p.Key == key).First().Value;
bool result = await GetBoolTag(strs[0], strs[1]);
if (result)
{
Logger.LogInformation($"【ScanInStock】 八工位 {key} AllowGetFullBox1采集到 {result}");
Dictionary<string, string> dicCommand = new(StringComparer.OrdinalIgnoreCase)
{
["DevName"] = strs[0],
["token"] = _eleCtlCfg.token,
["TagName"] = strs[3],
["Value"] = strs[4],
};
Logger.LogInformation($"【ScanInStock】 八工位 {key} 发送PutDoneEmptyBox指令 {_eleCtlCfg.WriteTagUrl} {JsonConvert.SerializeObject(dicCommand)}");
HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand).Wait();
string coderesult = await GetStringTag(strs[0], strs[2]);
Logger.LogInformation($"【ScanInStock】 八工位 {key} 获取到扫码信息: {coderesult}");
using (var _db = _repository.AsSugarClient().CopyNew())
{
WmsCarryH? carry = _db.Queryable<WmsCarryH>().Single(it => it.carry_code == coderesult);
Logger.LogInformation($"【ScanInStock】 八工位 {key} 查找{coderesult}绑定的托盘: {JsonConvert.SerializeObject(carry)}");
if (carry != null)
{
if (_db.Queryable<WmsDistaskH>().Where(p => p.carry_id == carry.id && p.status != WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID).Any())
{
Logger.LogInformation($"【ScanInStock】 八工位 {key} 托盘 {carry.id} 对应的执行任务状态(status)不是26126860808229(已完成),此时不能执行入库");
continue;
}
var WmsCarryCode = _db.Queryable<WmsCarryCode>().Where(it => it.carry_id == carry.id).OrderByDescending(it => it.id).First();
// 用适当的字段替换 YourTimestampField
if (WmsCarryCode != null)
{
Logger.LogInformation($"【ScanInStock】 八工位 {key} 查找到托盘{carry.carry_code}在WmsCarryCode中存在");
VisualDevModelDataCrInput input = new VisualDevModelDataCrInput();
input.data = new Dictionary<string, object>();
input.data.Add("barcode", coderesult);
input.data.Add("codeqty", WmsCarryCode.codeqty);//条码数量
input.data.Add("material_code", WmsCarryCode.material_code);
input.data.Add("extras", key);//location_code
input.data.Add("warehouse_id", "1");//TEST
input.data.Add("bill_code", "");//采购收货单号
input.data.Add("code_batch", WmsCarryCode.code_batch!);//批次
input.data.Add("material_specification", WmsCarryCode.material_specification!);//规格型号
input.data.Add("container_no", WmsCarryCode.container_no!);//箱号
input.data.Add("material_id", WmsCarryCode.material_id);
input.data.Add("id", null);
_wmsPDAScanInStock.ScanInStockByRedis(input).Wait();
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("【ScanInStock】" + ex.Message);
Logger.LogInformation($"【ScanInStock】 八工位扫到码发送入库请求发生异常:{ex}");
}
}
}
/// <summary>
/// 八工位空托盘补充
/// </summary>
private async void BGWCarrySupplement(object? state)
{
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 执行BGWCarrySupplement");
Dictionary<string, string[]> getdic = new Dictionary<string, string[]>();
getdic.Add("YCLCKBGW", new string[] { "CP8", "AllowPutEmptyBox1" });
foreach (var key in getdic.Keys)
{
try
{
var strs = getdic.Where(p => p.Key == key).First().Value;
bool result = await GetBoolTag(strs[0], strs[1]);
if (result)
{
LoggerBGWCarrySupplement.LogInformation($"【BGWCarrySupplementtimer】读取到信号{strs[1]} 值为{result} ");
using (var _db = _repository.AsSugarClient().CopyNew())
{
BasLocation endLocation = _db.Queryable<BasLocation>().Where(r => r.location_code == key).First();
if (endLocation == null)
{
LoggerBGWCarrySupplement.LogWarning($"【BGWCarrySupplementtimer】 {key}未维护库位信息");
continue;
}
if (endLocation.is_lock == 1)
{
LoggerBGWCarrySupplement.LogInformation($"【BGWCarrySupplementtimer】 八工位 {key} 已锁定");
continue;
}
// 未锁定且已占用且库位中没有记录托盘 此时认为是叠盘机送过来的
var wmsLoc = _db.Queryable<BasLocation>()
.LeftJoin<WmsCarryH>((a, b) => a.id == b.location_id)
.Where((a, b) => a.is_lock == 0 && a.is_use == "1"
&& a.wh_id == WmsWareHouseConst.WAREHOUSE_YCL_ID && a.location_code.Contains("YCL-")
&& a.is_type == "0")
.OrderBy((a, b) => a.location_code) // 当前是按库位排序出库
.Select((a, b) => new
{
BasLocation = a,
WmsCarryH = b
}).ToList().GroupBy(p => p.BasLocation)
.Where(group =>
{
// 是否存在托盘
bool isExistsCarry = false;
foreach (var item in group)
{
if (!string.IsNullOrEmpty(item.WmsCarryH.carry_code))
{
isExistsCarry = true;
break;
}
}
if (isExistsCarry)
return false;
else
return true;
}).Select(r => r.Key);
if (wmsLoc.Count() == 0)
{
LoggerBGWCarrySupplement.LogInformation($"【BGWCarrySupplementtimer】 没有未锁定且已占用且库位中没有记录托盘的数据");
continue;
}
BasLocation startLocation = wmsLoc.First();
//锁定起点库位
await _db.Updateable<BasLocation>().SetColumns(r => r.is_lock == 1).Where(r => r.id == startLocation.id).ExecuteCommandAsync();
////锁定终点库位 更新为空闲
//await _db.Updateable<BasLocation>().SetColumns(r => new BasLocation { is_lock = 1, is_use = "0" }).Where(r => r.id == endLocation.id).ExecuteCommandAsync();
LoggerBGWCarrySupplement.LogInformation($"【BGWCarrySupplementtimer】锁定起点库位 开始生成 {startLocation.location_code} 到 {endLocation.location_code} 预任务 ");
bool result_createPretask = await createPretask(startLocation.id, endLocation.id, "", "", LoggerBGWCarrySupplement);
if (!result_createPretask)
{
LoggerBGWCarrySupplement.LogWarning($"【BGWCarrySupplementtimer】 {startLocation.location_code} 到 {endLocation.location_code} 预任务生成失败 ");
continue;
}
LoggerBGWCarrySupplement.LogInformation($"【BGWCarrySupplementtimer】 {startLocation.location_code} 到 {endLocation.location_code} 预任务生成成功");
}
_ = _wareHouseService.GenTaskExecute();
}
}
catch (Exception ex)
{
Console.WriteLine("【BGWCarrySupplement】" + ex.Message);
LoggerBGWCarrySupplement.LogInformation($"【BGWCarrySupplementtimer】 八工位空托盘补充发生异常:{ex}");
}
}
}
#region
//获取redis数据
private async void GetRedisData(object? state)
{
var _redisReadConfigs = _repository.AsQueryable().Where(p => p.enabled == 1).ToList();
foreach (var config in _redisReadConfigs)
{
try
{
var json = await _redisData.GetHash(config.dev_name!, config.tag_name!);
if (json == null)
{
continue;
}
JObject? res = JsonConvert.DeserializeObject<JObject>(json);
if (config.data_type == (int)DataType.INT)
{
if (config.check_type == (int)CheckType.)
{
if (res.Value<int>("Value") == int.Parse(config.data!))
{
InstockInput instockInput = new()
{
equip_code = res["DevName"]!.ToString(),
label_code = res["TagName"]!.ToString()
};
TriggerEvent((EventType)config.event_type, instockInput);
}
}
else if (config.check_type == (int)CheckType.)
{
int[] ints = Array.ConvertAll(config.data!.Replace("[", "").Replace("]", "").Split(",", StringSplitOptions.RemoveEmptyEntries), int.Parse);
if (ints.Contains(res.Value<int>("Value")))
{
InstockInput instockInput = new()
{
equip_code = res["DevName"]!.ToString(),
label_code = res["TagName"]!.ToString()
};
TriggerEvent((EventType)config.event_type, instockInput);
}
}
}
else if (config.data_type == (int)DataType.BOOL)
{
if (config.check_type == (int)CheckType.)
{
if (res.Value<bool>("Value") == bool.Parse(config.data!))
{
InstockInput instockInput = new()
{
equip_code = res["DevName"]!.ToString(),
label_code = res["TagName"]!.ToString()
};
TriggerEvent((EventType)config.event_type, instockInput);
}
}
}
}
catch (Exception)
{
}
}
}
private void TriggerEvent(EventType eventType, InstockInput instockInput)
{
switch (eventType)
{
case EventType.:
_prdInstockService.InstockTypeOne(instockInput);
break;
case EventType.:
_prdInstockService.InstockTubeOne(instockInput);
break;
case EventType.:
_prdInstockService.InstockOutPack(instockInput);
break;
default:
break;
}
}
#endregion
/// <summary>
/// 供料叠盘机空托盘自动入库
/// </summary>
private async void YCLGLDPJInstock(object? state)
{
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 执行YCLGLDPJInstock");
Dictionary<string, string[]> getdic = new Dictionary<string, string[]>();
getdic.Add("SGW-YCL", new string[] { "CP3-5", "AllowGetFullBox" });
foreach (var key in getdic.Keys)
{
try
{
var strs = getdic.Where(p => p.Key == key).First().Value;
bool result = await GetBoolTag(strs[0], strs[1]);
if (result)
{
LoggerYCLGLDPJInstock.LogInformation($"【YCLGLDPJInstock】 三工位叠盘机 {key} {strs[1]}采集到 {result}");
using (var db = _repository.AsSugarClient().CopyNew())
{
BasLocation startLocation = db.Queryable<BasLocation>().Where(r => r.location_code == key).First();
if (startLocation == null)
{
LoggerYCLGLDPJInstock.LogWarning($"【YCLGLDPJInstock】 {key}未维护库位信息");
continue;
}
if (startLocation.is_lock == 1)
{
LoggerYCLGLDPJInstock.LogInformation($"【YCLGLDPJInstock】 三工位叠盘机 {key} 已锁定");
continue;
}
// 找到未锁定且未占用的库位
var endLocations = db.Queryable<BasLocation>()
.Where(a => a.is_lock == 0 && a.is_use == "0" && a.wh_id == WmsWareHouseConst.WAREHOUSE_YCL_ID && a.location_code.Contains("YCL-") && a.is_type == "0");
LoggerYCLGLDPJInstock.LogInformation($"【YCLGLDPJInstock】 sql {endLocations.ToSqlString()}");
if (endLocations.Count() == 0)
{
LoggerYCLGLDPJInstock.LogWarning($"【YCLGLDPJInstock】 当前没有空库位可以入库");
continue;
}
BasLocation endLocation = endLocations.First();
//锁定起点库位 更新为空闲
await db.Updateable<BasLocation>().SetColumns(r => new BasLocation { is_lock = 1, is_use = "0" }).Where(r => r.id == startLocation.id).ExecuteCommandAsync();
//锁定终点库位
await db.Updateable<BasLocation>().SetColumns(r => new BasLocation { is_lock = 1 }).Where(r => r.id == endLocation.id).ExecuteCommandAsync();
bool result_createPretask = await createPretask(startLocation.id, endLocation.id, "", "", LoggerYCLGLDPJInstock);
if (!result_createPretask)
{
LoggerYCLGLDPJInstock.LogWarning($"【YCLGLDPJInstock】 {startLocation.location_code} 到 {endLocation.location_code} 预任务生成失败");
continue;
}
LoggerYCLGLDPJInstock.LogWarning($"【YCLGLDPJInstock】 {startLocation.location_code} 到 {endLocation.location_code} 预任务生成成功");
}
_ = _wareHouseService.GenTaskExecute();
}
}
catch (Exception ex)
{
Console.WriteLine("【YCLGLDPJInstock】" + ex.Message);
LoggerYCLGLDPJInstock.LogInformation($"【YCLGLDPJInstock】 三工位叠盘机空托入库发生异常:{ex}");
}
}
}
/// <summary>
/// 外协叠盘机空托盘自动入库
/// </summary>
private async void YCLWXDPJInstock(object? state)
{
Dictionary<string, string[]> getdic = new Dictionary<string, string[]>();
getdic.Add("未定", new string[] { "CP3-3", "AllowGetFullBox" });
foreach (var key in getdic.Keys)
{
try
{
var strs = getdic.Where(p => p.Key == key).First().Value;
bool result = await GetBoolTag(strs[0], strs[1]);
if (result)
{
LoggerYCLGLDPJInstock.LogInformation($"【YCLWXDPJInstock】 外协叠盘机 {key} {strs[1]}采集到 {result}");
BasLocation startLocation = _repository.AsSugarClient().Queryable<BasLocation>().Where(r => r.location_code == key).First();
if (startLocation == null)
{
LoggerYCLGLDPJInstock.LogWarning($"【YCLWXDPJInstock】 {key}未维护库位信息");
continue;
}
if (startLocation.is_lock == 1)
{
LoggerYCLGLDPJInstock.LogInformation($"【YCLWXDPJInstock】 外协叠盘机 {key} 已锁定");
continue;
}
// 找到未锁定且未占用的库位
var endLocations = _repository.AsSugarClient().Queryable<BasLocation>()
.Where(a => a.is_lock == 0 && a.is_use == "0" && a.wh_id == WmsWareHouseConst.WAREHOUSE_YCL_ID && a.location_code.Contains("YCL-") && a.is_type == "0");
LoggerYCLGLDPJInstock.LogInformation($"【YCLWXDPJInstock】 sql {endLocations.ToSqlString()}");
if (endLocations.Count() == 0)
{
LoggerYCLGLDPJInstock.LogWarning($"【YCLWXDPJInstock】 当前没有空库位可以入库");
continue;
}
BasLocation endLocation = endLocations.First();
//锁定起点库位 更新为空闲
await _repository.AsSugarClient().Updateable<BasLocation>().SetColumns(r => new BasLocation { is_lock = 1, is_use = "0" }).Where(r => r.id == startLocation.id).ExecuteCommandAsync();
//锁定终点库位
await _repository.AsSugarClient().Updateable<BasLocation>().SetColumns(r => new BasLocation { is_lock = 1 }).Where(r => r.id == endLocation.id).ExecuteCommandAsync();
bool result_createPretask = await createPretask(startLocation.id, endLocation.id, "", "", LoggerYCLGLDPJInstock);
if (!result_createPretask)
{
LoggerYCLGLDPJInstock.LogWarning($"【YCLWXDPJInstock】 {startLocation.location_code} 到 {endLocation.location_code} 预任务生成失败");
continue;
}
LoggerYCLGLDPJInstock.LogWarning($"【YCLWXDPJInstock】 {startLocation.location_code} 到 {endLocation.location_code} 预任务生成成功");
_ = _wareHouseService.GenTaskExecute();
}
}
catch (Exception ex)
{
LoggerYCLGLDPJInstock.LogInformation($"【YCLWXDPJInstock】 外协叠盘机空托入库发生异常:{ex}");
}
}
}
#endregion
#region
private async void SSXcode(object? state)
{
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 执行SSXcode");
Dictionary<string, string[]> dic = new Dictionary<string, string[]>();
dic.Add("东面提升机输送线", new string[] { "下升降机判断请求", "下升降机判断条码", "下升降机判断完毕", "下升降机判断结果" });
Dictionary<string, int> putdic = new Dictionary<string, int>();
putdic.Add("SSX-111-011", 11);
putdic.Add("SSX-111-012", 12);
foreach (var key in dic.Keys)
{
try
{
var strs = dic.Where(p => p.Key == key).First().Value;
bool re = await GetBoolTag(key, strs[0]);
if (!re)
continue;
string? result = await GetStringTag(key, strs[1]);
if (!string.IsNullOrEmpty(result))
{
if (result.Length < 5)
{
result = "LX" + result.Replace("\r", "");
}
var DistaskH = _repository.AsSugarClient().Queryable<WmsDistaskH>().Where(p => p.carry_code == result && p.status != WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID).OrderByDescending(p => p.create_time).First();
if (DistaskH != null)
{
Logger.LogInformation($"【定时任务SSXcode】DistaskH != null putdic.Keys.Contains(DistaskH.startlocation_code):{putdic.Keys.Contains(DistaskH.startlocation_code)} {result}");
Dictionary<string, string> dicCommand2 = new(StringComparer.OrdinalIgnoreCase)
{
["DevName"] = key,
["token"] = _eleCtlCfg.token,
["TagName"] = strs[3],
["Value"] = putdic.Keys.Contains(DistaskH.startlocation_code) ? putdic.Where(p => p.Key == DistaskH.startlocation_code).First().Value.ToString() : "13",
};
HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand2).Wait();
Dictionary<string, string> dicCommand = new(StringComparer.OrdinalIgnoreCase)
{
["DevName"] = key,
["token"] = _eleCtlCfg.token,
["TagName"] = strs[2],
["Value"] = "true",
};
HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand).Wait();
}
else
{
Logger.LogInformation($"【定时任务SSXcode】DistaskH == null {_repository.AsSugarClient().Queryable<WmsDistaskH>().Where(p => p.carry_code == result && p.status != WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID).OrderByDescending(p => p.create_time).ToSqlString()}");
Dictionary<string, string> dicCommand2 = new(StringComparer.OrdinalIgnoreCase)
{
["DevName"] = key,
["token"] = _eleCtlCfg.token,
["TagName"] = strs[3],
["Value"] = "13",
};
HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand2).Wait();
Dictionary<string, string> dicCommand = new(StringComparer.OrdinalIgnoreCase)
{
["DevName"] = key,
["token"] = _eleCtlCfg.token,
["TagName"] = strs[2],
["Value"] = "true",
};
HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand).Wait();
}
}
}
catch (Exception ex)
{
Console.WriteLine("【SSXcode】" + ex.Message);
Logger.LogInformation($"【定时任务SSXcode】发生异常 {ex}");
}
}
}
#endregion
public void Dispose()
{
Readtimer?.Dispose();
CheckGettimer?.Dispose();
Scantimer?.Dispose();
SSXcodetimer?.Dispose();
Floor2UpMachinecodetimer?.Dispose();
Floor2timer送空托到上升降区?.Dispose();
Floor2timer送满托到下升降区?.Dispose();
Floor2timer移走上升降区未生成预任务且满托的料架?.Dispose();
Floor2timer移走下升降区未生成预任务且空托的料架?.Dispose();
BGWCarrySupplementtimer?.Dispose();
YCLGLDPJInstocktimer?.Dispose();
YCLWXDPJInstocktimer?.Dispose();
//SSX7Supplementtimer?.Dispose();
}
#region
// 上升降机扫码 需要等待空料架区 此处需要轮询
private async void Floor2UpMachinecode(object? args)
{
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 执行Floor2UpMachinecode");
string barcode = await GetStringTag("东面提升机输送线", MechanicalArmConsts.);
if (string.IsNullOrEmpty(barcode))
{
LoggerFloor2UpDownMachine.LogError($@"【上升降机】未取到条码数据");
return;
}
using (var db = _repository.AsSugarClient().CopyNew())
{
try
{
s_taskExecuteFloor2UpMachinecodetimer.Wait();
// 读取上升降机的左右料架区配置
string[] configs = new string[2] { "二楼上升降机机械臂左", "二楼上升降机机械臂右" };
// 左右料架区配置
List<WmsMechanicalArmH> WmsMechanicalArmHs = db.Queryable<WmsMechanicalArmH>()
.Where(r => configs.Contains(r.name) && r.agvconfirm == 1).ToList();
// 是否可以放货
if (WmsMechanicalArmHs.Count == 0)
{
LoggerFloor2UpDownMachine.LogWarning($@"【上升降机】目前没有可以放货的料架区(料架区一个料架都没有,如果实际有料架说明系统缓存表与实际不对应,需要重置缓存表信息)");
return;
}
// 如果条码已被绑定
if (WmsMechanicalArmHs.Where(r => !string.IsNullOrEmpty(r.barcodes) && r.barcodes.Contains(barcode)).Count() > 0)
{
LoggerFloor2UpDownMachine.LogWarning($@"【上升降机】条码{barcode}已被绑定");
return;
}
LoggerFloor2UpDownMachine.LogInformation($@"【上升降机】扫描到有效条码 {barcode}");
// 获取下到输送线9和10的未完成的转库单
List<WmsMaterialTransfer> WmsMaterialTransfers = db.Queryable<WmsMaterialTransfer>()
.InnerJoin<WmsMaterialTransferCarry>((a, b) => a.id == b.bill_id)
.Where((a, b) => a.warehouse_instock == "33780009364245" && a.warehouse_outstock == "2" && a.remainbindracknum > 0
&& b.carry_code == barcode).ToList();
if (WmsMaterialTransfers.Count() == 0)
{
LoggerFloor2UpDownMachine.LogWarning($@"【上升降机】未找到条码{barcode}的输送线为9、10的转库单");
return;
}
// 转库单
WmsMaterialTransfer WmsMaterialTransfer = WmsMaterialTransfers.OrderByDescending(r => r.create_time).First();
// 找到条码在的转库单
string ckdCode = WmsMaterialTransfer.bill_code;
int ckdRemainBindRackNum = (int)(WmsMaterialTransfer.remainbindracknum != null ? WmsMaterialTransfer.remainbindracknum : 0);
//扫描到的料箱 a.对应转库单的b.码垛计数未达到满托数量的料架区
IEnumerable<WmsMechanicalArmH> targetConfigs = WmsMechanicalArmHs.Where(r => r.outbill == ckdCode && r.stackingcount < r.maxnum);
WmsMechanicalArmH target;
await db.Ado.BeginTranAsync();
// 找不到对应的料架
if (targetConfigs.Count() == 0)
{
// 有空闲料架区且绑定了料架时
targetConfigs = WmsMechanicalArmHs.Where(r => string.IsNullOrEmpty(r.outbill)).OrderBy(r => r.id);
if (targetConfigs.Count() > 0)
{
target = targetConfigs.First();
// 计算当前料架区的满托数量
int? maxnum = ckdRemainBindRackNum > target.maxracknum ? ckdRemainBindRackNum % target.maxracknum : ckdRemainBindRackNum;
// 更新 转库单、满托数量
LoggerFloor2UpDownMachine.LogInformation($@"【上升降机】为条码 {barcode} 所在的转库单 {ckdCode} 占用了一个空闲料架");
await db.Updateable<WmsMechanicalArmH>().SetColumns(r => new WmsMechanicalArmH
{
outbill = ckdCode,
maxnum = maxnum
}).Where(r => r.id == target.id).ExecuteCommandAsync();
bool result = await Floor2UpDownMachinecode_SetTag($"上升降机满托{target.stackingposition}数量", maxnum.ToString());
LoggerFloor2UpDownMachine.LogInformation($@"【上升降机】设定升降机满托{target.stackingposition}满托数量为 {maxnum} 结果为 {result}");
if (!result)
{
throw new Exception($@"【上升降机】设定升降机满托{target.stackingposition}满托数量为 {maxnum} 结果为 {result}");
}
// 尝试写入空托送到信号
bool result上升降机空托送到 = await Floor2UpDownMachinecode_SetTag($"上升降机空托{target.stackingposition}送到", "true");
LoggerFloor2UpDownMachine.LogInformation($@"【上升降机】回写 上升降机空托{target.stackingposition}送到 结果为{result上升降机空托送到}");
if (!result上升降机空托送到)
{
return;
}
}
else
{
LoggerFloor2UpDownMachine.LogError($@"【上升降机】条码{barcode}找不到绑定转库单{ckdCode}的料架区,且没有空闲的料架区可以用于绑定此转库单!");
await db.Ado.RollbackTranAsync();
return;
}
}
//如有多个料架绑定同个转库单则取第一个未满托的料架
target = targetConfigs.First();
LoggerFloor2UpDownMachine.LogInformation($@"【上升降机】当前条码目标料架区为 {JsonConvert.SerializeObject(target)}");
// 料架信息
WmsCarryH rack = db.Queryable<WmsCarryH>().Where(r => r.id == target.rackid).ToList()[0];
// 料箱信息
WmsCarryH LX = db.Queryable<WmsCarryH>().Where(r => r.carry_code == barcode).ToList()[0];
// 开始码垛
bool result_开始码垛 = await Floor2UpDownMachinecode_SetTag(MechanicalArmConsts., target.stackingposition.ToString());
LoggerFloor2UpDownMachine.LogInformation($@"【上升降机】码垛结果 {result_开始码垛}");
if (!result_开始码垛)
{
throw new Exception($@"【上升降机】码垛结果 {result_开始码垛}");
}
// 回写料箱条码、码垛计数
await db.Updateable<WmsMechanicalArmH>().SetColumns(r => new WmsMechanicalArmH
{
barcodes = $"{target.barcodes},{barcode}".Trim(','),
stackingcount = r.stackingcount + 1,
mechanicalconfirm = 1
}).Where(r => r.id == target.id).ExecuteCommandAsync();
LoggerFloor2UpDownMachine.LogInformation($@"【上升降机】回写料箱条码、码垛计数");
// 回写转库单的剩余可绑定料架数量
await db.Updateable<WmsMaterialTransfer>().SetColumns(r => new WmsMaterialTransfer
{
remainbindracknum = r.remainbindracknum - 1
}).Where(r => r.id == WmsMaterialTransfer.id).ExecuteCommandAsync();
LoggerFloor2UpDownMachine.LogInformation($@"【上升降机】回写转库单的剩余可绑定料架数量");
// 绑定料箱到料架
CarryBindInput carryBindInput = new();
carryBindInput.carry_id = target.rackid;
carryBindInput.carry_code = target.rackcode;
carryBindInput.membercarry_id = LX.id;
carryBindInput.membercarry_code = LX.carry_code;
carryBindInput.carrystd_id = rack.carrystd_id;
carryBindInput.source_code = target.outbill;
await _wmsCarryBindService.CarryBind(carryBindInput);
await db.Ado.CommitTranAsync();
}
catch (Exception ex)
{
LoggerFloor2UpDownMachine.LogError(ex.ToString());
LoggerFloor2UpDownMachine.LogError(ex.StackTrace);
await db.Ado.RollbackTranAsync();
}
finally
{
s_taskExecuteFloor2UpMachinecodetimer.Release();
}
}
}
// 二楼机械臂信号对应机械臂字典
Dictionary<string, string> floor2mechanicalAtmDic = new Dictionary<string, string>()
{
{"上升降机请求送空托1","二楼上升降机机械臂左"},
{"上升降机请求送空托2","二楼上升降机机械臂右"},
{"下升降机请求送满托1","二楼下升降机机械臂左"},
{"下升降机请求送满托2","二楼下升降机机械臂右"},
{"上升降机请求取满托1","二楼上升降机机械臂左"},
{"上升降机请求取满托2","二楼上升降机机械臂右"},
{"下升降机请求取空托1","二楼下升降机机械臂左"},
{"下升降机请求取空托2","二楼下升降机机械臂右"},
};
/// <summary>
/// 送空托到上升降区
/// </summary>
/// <returns></returns>
public async void (object? args)
{
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 执行送空托到上升降区");
#region
List<string> configs_upMachine = new List<string>();
if (await GetBoolTag("东面提升机输送线", $"上升降机请求送空托1"))
{
LoggerFloor2RackDelivery.LogError($"【送空托到上升降区】上升降机请求送空托1 true");
configs_upMachine.Add(floor2mechanicalAtmDic["上升降机请求送空托1"]);
}
if (await GetBoolTag("东面提升机输送线", $"上升降机请求送空托2"))
{
LoggerFloor2RackDelivery.LogError($"【送空托到上升降区】上升降机请求送空托2 true");
configs_upMachine.Add(floor2mechanicalAtmDic["上升降机请求送空托2"]);
}
// 没有有效信号
if (configs_upMachine.Count == 0)
return;
#endregion
await s_task送空托到上升降区.WaitAsync();
using (var db = _repository.AsSugarClient().CopyNew())
{
try
{
// 找到没有绑定料架的且库位未锁定的料架区
ISugarQueryable<WmsMechanicalArmH> WmsMechanicalArmHsuagar = db.Queryable<WmsMechanicalArmH>()
.InnerJoin<BasLocation>((a, b) => a.location_id == b.id)
.Where((a, b) => string.IsNullOrEmpty(a.rackcode) && b.is_lock == 0 && configs_upMachine.Contains(a.name));
List<WmsMechanicalArmH> WmsMechanicalArmHs = WmsMechanicalArmHsuagar.ToList();
if (WmsMechanicalArmHs.Count() == 0)
{
LoggerFloor2RackDelivery.LogWarning($"【送空托到上升降区】 无需补充料架区 {WmsMechanicalArmHsuagar.ToSqlString()}");
return;
}
//await db.BeginTranAsync();
// 料架区
foreach (WmsMechanicalArmH wmsMechanicalArmH in WmsMechanicalArmHs)
{
// 找到占用且未锁定的库位上的空料架
ISugarQueryable<BasLocation> rackStartLocations =
db.Queryable<BasLocation>()
.InnerJoin<WmsCarryH>((a, b) => a.id == b.location_id)
.LeftJoin<WmsCarryD>((a, b, c) => b.id == c.carry_id)
.Where((a, b, c) => a.wh_id == "33780009364245" && a.is_use == "1" && a.is_lock == 0 && string.IsNullOrEmpty(c.id)
&& b.carrystd_id == WmsWareHouseConst.CARRY_LJSTD_ID).OrderBy(a => a.id).Take(1);
if (rackStartLocations.Count() == 0)
{
LoggerFloor2RackDelivery.LogWarning($"【送空托到上升降区】 暂存仓中没有可用的空料架 {rackStartLocations.ToSqlString()}");
continue;
}
LoggerFloor2RackDelivery.LogInformation($"【送空托到上升降区】 即将补充料架区{wmsMechanicalArmH.name}");
BasLocation startLocation = rackStartLocations.First();
List<WmsCarryH> wmsCarryHs = db.Queryable<WmsCarryH>().Where(r => r.location_id == startLocation.id).ToList();
if (wmsCarryHs.Count == 0)
{
LoggerFloor2RackDelivery.LogError($"【送空托到上升降区】 起点{startLocation.id} {startLocation.location_code}上找不到料架");
continue;
}
if (wmsCarryHs.Count > 1)
{
LoggerFloor2RackDelivery.LogError($"【送空托到上升降区】 起点{startLocation.id} {startLocation.location_code}上存在多个料架");
continue;
}
// 空料架
WmsCarryH targetCarry = wmsCarryHs[0];
await db.Updateable<BasLocation>().SetColumns(r => new BasLocation
{
is_lock = 1
}).Where(r => r.id == startLocation.id).ExecuteCommandAsync();
await db.Updateable<BasLocation>().SetColumns(r => new BasLocation
{
is_lock = 1
}).Where(r => r.id == wmsMechanicalArmH.location_id).ExecuteCommandAsync();
LoggerFloor2RackDelivery.LogInformation($"【送空托到上升降区】 开始生成预任务 起点{startLocation.location_code} 终点{wmsMechanicalArmH.location_code} 料架 {targetCarry.carry_code}");
bool result = await createPretask(startLocation.id, wmsMechanicalArmH.location_id, targetCarry.id, targetCarry.carry_code, LoggerFloor2RackDelivery);
if (!result)
{
LoggerFloor2RackDelivery.LogInformation($"【送空托到上升降区】 未成功生成预任务 起点{startLocation.location_code} 终点{wmsMechanicalArmH.location_code} 料架 {targetCarry.carry_code}");
throw new Exception($"【送空托到上升降区】 未成功生成预任务 起点{startLocation.location_code} 终点{wmsMechanicalArmH.location_code} 料架 {wmsMechanicalArmH.rackcode}");
}
}
//await db.CommitTranAsync();
}
catch (Exception ex)
{
LoggerFloor2RackDelivery.LogInformation($"【送空托到上升降区】 {ex.Message}");
LoggerFloor2RackDelivery.LogInformation($"【送空托到上升降区】 {ex.StackTrace}");
//await db.RollbackTranAsync();
}
finally
{
s_task送空托到上升降区.Release();
_wareHouseService.GenTaskExecute();
}
}
}
/// <summary>
/// 送满托到下升降区
/// </summary>
/// <returns></returns>
public async void (object? args)
{
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 执行送满托到下升降区");
#region
List<string> configs_upMachine = new List<string>();
if (await GetBoolTag("东面提升机输送线", $"下升降机请求送满托1"))
{
LoggerFloor2RackDelivery.LogError($"【送满托到下升降区】下升降机请求送满托1 true");
configs_upMachine.Add(floor2mechanicalAtmDic["下升降机请求送满托1"]);
}
if (await GetBoolTag("东面提升机输送线", $"下升降机请求送满托2"))
{
LoggerFloor2RackDelivery.LogError($"【送满托到下升降区】下升降机请求送满托2 true");
configs_upMachine.Add(floor2mechanicalAtmDic["下升降机请求送满托2"]);
}
// 没有有效信号
if (configs_upMachine.Count == 0)
return;
#endregion
await s_task送满托到下升降区.WaitAsync();
using (var db = _repository.AsSugarClient().CopyNew())
{
try
{
// 找到没有绑定料架的且库位未锁定的料架区
ISugarQueryable<WmsMechanicalArmH> WmsMechanicalArmHsuagar = db.Queryable<WmsMechanicalArmH>()
.InnerJoin<BasLocation>((a, b) => a.location_id == b.id)
.Where((a, b) => string.IsNullOrEmpty(a.rackcode) && b.is_lock == 0 && configs_upMachine.Contains(a.name));
List<WmsMechanicalArmH> WmsMechanicalArmHs = WmsMechanicalArmHsuagar.ToList();
if (WmsMechanicalArmHs.Count() == 0)
{
LoggerFloor2RackDelivery.LogWarning($"【送满托到下升降区】 无需补充料架区 {WmsMechanicalArmHsuagar.ToSqlString()}");
return;
}
//await db.BeginTranAsync();
// 料架区
foreach (WmsMechanicalArmH wmsMechanicalArmH in WmsMechanicalArmHs)
{
// 找到占用且未锁定的库位上的满料架且料架中的料箱是空的
List<BasLocation> rackStartLocations =
db.Queryable<BasLocation>()
.InnerJoin<WmsCarryH>((a, b) => a.id == b.location_id)
.LeftJoin<WmsCarryD>((a, b, c) => b.id == c.carry_id) // 有料箱
.LeftJoin<WmsCarryCode>((a, b, c, d) => c.membercarry_id == d.carry_id)
.Where((a, b, c, d) => a.wh_id == "33780009364245" && a.is_use == "1" && a.is_lock == 0 && !string.IsNullOrEmpty(c.id)
&& b.carrystd_id == WmsWareHouseConst.CARRY_LJSTD_ID).OrderBy((a, b, c, d) => d.id).Select((a, b, c, d) => new // 关联载具物料明细表
{
basLocation = a,
WmsCarryCode_id = d.id
}).ToList().GroupBy(r => r.basLocation.location_code).Select(r =>
{
var item = r.FirstOrDefault();
// 前面通过OrderBy(d => d.id)对WmsCarryCode_id进行了排序 那么如果第一行有数据则说明存在非空料箱
if (!string.IsNullOrEmpty(item.WmsCarryCode_id))
{
return new BasLocation();
}
else
{
// 进这里说明库位下的料箱都为空
return item.basLocation;
}
})
// 筛选非空库位数据
.Where(r => !string.IsNullOrEmpty(r.location_code)).ToList();
if (rackStartLocations.Count() == 0)
{
//LoggerFloor2RackDelivery.LogWarning($"【送满托到下升降区】 暂存仓中没有可用的满料架 {rackStartLocations.ToSqlString()}");
continue;
}
LoggerFloor2RackDelivery.LogInformation($"【送满托到下升降区】 即将补充料架区{wmsMechanicalArmH.name}");
BasLocation startLocation = rackStartLocations.First();
List<WmsCarryH> wmsCarryHs = db.Queryable<WmsCarryH>().Where(r => r.location_id == startLocation.id).ToList();
if (wmsCarryHs.Count == 0)
{
LoggerFloor2RackDelivery.LogError($"【送满托到下升降区】 起点{startLocation.id} {startLocation.location_code}上找不到料架");
continue;
}
if (wmsCarryHs.Count > 1)
{
LoggerFloor2RackDelivery.LogError($"【送满托到下升降区】 起点{startLocation.id} {startLocation.location_code}上存在多个料架");
continue;
}
// 满料架
WmsCarryH targetCarry = wmsCarryHs[0];
await db.Updateable<BasLocation>().SetColumns(r => new BasLocation
{
is_lock = 1
}).Where(r => r.id == startLocation.id).ExecuteCommandAsync();
await db.Updateable<BasLocation>().SetColumns(r => new BasLocation
{
is_lock = 1
}).Where(r => r.id == wmsMechanicalArmH.location_id).ExecuteCommandAsync();
LoggerFloor2RackDelivery.LogInformation($"【送满托到下升降区】 开始生成预任务 起点{startLocation.location_code} 终点{wmsMechanicalArmH.location_code} 料架 {targetCarry.carry_code}");
bool result = await createPretask(startLocation.id, wmsMechanicalArmH.location_id, targetCarry.id, targetCarry.carry_code, LoggerFloor2RackDelivery);
if (!result)
{
LoggerFloor2RackDelivery.LogInformation($"【送满托到下升降区】 未成功生成预任务 起点{startLocation.location_code} 终点{wmsMechanicalArmH.location_code} 料架 {targetCarry.carry_code}");
continue;
}
}
//await db.CommitTranAsync();
}
catch (Exception ex)
{
LoggerFloor2RackDelivery.LogInformation($"【送满托到下升降区】 {ex.Message}");
LoggerFloor2RackDelivery.LogInformation($"【送满托到下升降区】 {ex.StackTrace}");
//await db.RollbackTranAsync();
}
finally
{
s_task送满托到下升降区.Release();
_wareHouseService.GenTaskExecute();
}
}
}
/// <summary>
/// 移走上升降区未生成预任务且满托的料架
/// </summary>
/// <returns></returns>
public async void (object? args)
{
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 执行移走上升降区未生成预任务且满托的料架");
#region
List<string> configs_upMachine = new List<string>();
if (await GetBoolTag("东面提升机输送线", $"上升降机请求取满托1"))
{
LoggerFloor2RackDelivery.LogError($"【移走上升降区未生成预任务且满托的料架】上升降机请求取满托1 true");
configs_upMachine.Add(floor2mechanicalAtmDic["上升降机请求取满托1"]);
}
if (await GetBoolTag("东面提升机输送线", $"上升降机请求取满托2"))
{
LoggerFloor2RackDelivery.LogError($"【移走上升降区未生成预任务且满托的料架】上升降机请求取满托2 true");
configs_upMachine.Add(floor2mechanicalAtmDic["上升降机请求取满托2"]);
}
// 没有有效信号
if (configs_upMachine.Count == 0)
return;
#endregion
await s_task移走上升降区未生成预任务且满托的料架.WaitAsync();
using (var db = _repository.AsSugarClient().CopyNew())
{
try
{
//await db.BeginTranAsync();
// 读取上升降机的左右料架区配置
List<WmsMechanicalArmH> WmsMechanicalArmHs = db.Queryable<WmsMechanicalArmH>().Where(r => r.stackingcount == r.maxnum && r.maxnum != 0 && !string.IsNullOrEmpty(r.rackcode) && r.iscreatepretask == 0 && configs_upMachine.Contains(r.name) && r.mechanicalconfirm == 1).ToList();
foreach (WmsMechanicalArmH wmsMechanicalArmH in WmsMechanicalArmHs)
{
LoggerFloor2RackDelivery.LogInformation($"【移走上升降区满托的料架】 开始执行预任务生成 {wmsMechanicalArmH.location_code} {wmsMechanicalArmH.outbill} {wmsMechanicalArmH.barcodes}");
await db.Updateable<WmsMechanicalArmH>().SetColumns(r => new WmsMechanicalArmH
{
iscreatepretask = 1
}).Where(r => r.id == wmsMechanicalArmH.id).ExecuteCommandAsync();
// 找到未占用且未锁定的库位
ISugarQueryable<BasLocation> rackEndLocations =
db.Queryable<BasLocation>()
.Where(r => r.wh_id == "33780009364245" && r.is_use == "0" && r.is_lock == 0).OrderBy(a => a.id).Take(1);
if (rackEndLocations.Count() == 0)
{
LoggerFloor2RackDelivery.LogWarning($"【移走上升降区满托的料架】 暂存仓中没有可用的空库位 {rackEndLocations.ToSqlString()}");
continue;
}
BasLocation endLocation = rackEndLocations.First();
// 锁住终点库位
//await db.Updateable<BasLocation>(r => new BasLocation
//{
// is_lock = 1
//}).Where(r => r.id == endLocation.id).ExecuteCommandAsync();
LoggerFloor2RackDelivery.LogInformation($"【移走上升降区满托的料架】 开始执行预任务生成: 料架区为{wmsMechanicalArmH.name}{wmsMechanicalArmH.stackingposition} 料架为{wmsMechanicalArmH.rackcode}");
bool result = await createPretask(wmsMechanicalArmH.location_id, endLocation.id, wmsMechanicalArmH.rackid, wmsMechanicalArmH.rackcode, LoggerFloor2RackDelivery);
if (!result)
{
LoggerFloor2RackDelivery.LogError($"【移走上升降区满托的料架】 未成功生成预任务 起点{wmsMechanicalArmH.location_code} 终点{endLocation.location_code} 料架 {wmsMechanicalArmH.rackcode}");
throw new Exception($"【移走上升降区满托的料架】 未成功生成预任务 起点{wmsMechanicalArmH.location_code} 终点{endLocation.location_code} 料架 {wmsMechanicalArmH.rackcode}");
}
LoggerFloor2RackDelivery.LogInformation($"【移走上升降区满托的料架】 成功生成预任务 {result}");
}
//await db.CommitTranAsync();
}
catch (Exception ex)
{
LoggerFloor2RackDelivery.LogInformation($"【移走上升降区未生成预任务且满托的料架】 {ex.Message}");
LoggerFloor2RackDelivery.LogInformation($"【移走上升降区未生成预任务且满托的料架】 {ex.StackTrace}");
//await db.RollbackTranAsync();
}
finally
{
s_task移走上升降区未生成预任务且满托的料架.Release();
_wareHouseService.GenTaskExecute();
}
}
}
/// <summary>
/// 移走下升降区未生成预任务且空托的料架
/// </summary>
/// <returns></returns>
public async void (object? args)
{
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 执行移走下升降区未生成预任务且空托的料架");
#region
List<string> configs_upMachine = new List<string>();
if (await GetBoolTag("东面提升机输送线", $"下升降机请求取空托1"))
{
LoggerFloor2RackDelivery.LogError($"【移走下升降区空托的料架】下升降机请求取空托1 true");
configs_upMachine.Add(floor2mechanicalAtmDic["下升降机请求取空托1"]);
}
if (await GetBoolTag("东面提升机输送线", $"下升降机请求取空托2"))
{
LoggerFloor2RackDelivery.LogError($"【移走下升降区空托的料架】下升降机请求取空托2 true");
configs_upMachine.Add(floor2mechanicalAtmDic["下升降机请求取空托2"]);
}
// 没有有效信号
if (configs_upMachine.Count == 0)
return;
#endregion
await s_task移走下升降区未生成预任务且空托的料架.WaitAsync();
using (var db = _repository.AsSugarClient().CopyNew())
{
try
{
//await db.BeginTranAsync();
// 读取下升降机的左右料架区配置
List<WmsMechanicalArmH> WmsMechanicalArmHs = db.Queryable<WmsMechanicalArmH>().Where(r => !string.IsNullOrEmpty(r.rackcode) && r.iscreatepretask == 0 && configs_upMachine.Contains(r.name)).ToList();
foreach (WmsMechanicalArmH wmsMechanicalArmH in WmsMechanicalArmHs)
{
LoggerFloor2RackDelivery.LogInformation($"【移走下升降区空托的料架】 开始执行预任务生成 {wmsMechanicalArmH.location_code} {wmsMechanicalArmH.outbill} {wmsMechanicalArmH.barcodes}");
await db.Updateable<WmsMechanicalArmH>().SetColumns(r => new WmsMechanicalArmH
{
iscreatepretask = 1
}).Where(r => r.id == wmsMechanicalArmH.id).ExecuteCommandAsync();
// 找到未占用且未锁定的库位
ISugarQueryable<BasLocation> rackEndLocations =
db.Queryable<BasLocation>()
.Where(r => r.wh_id == "33780009364245" && r.is_use == "0" && r.is_lock == 0).OrderBy(a => a.id).Take(1);
if (rackEndLocations.Count() == 0)
{
//LoggerFloor2RackDelivery.LogWarning($"【移走下升降区空托的料架】 暂存仓中没有可用的空库位 {rackEndLocations.ToSqlString()}");
continue;
}
BasLocation endLocation = rackEndLocations.First();
// 解除绑定料箱到料架
CarryBindInput carryBindInput = new() { };
carryBindInput.carry_id = wmsMechanicalArmH.rackid;
carryBindInput.carry_code = wmsMechanicalArmH.rackcode;
carryBindInput.source_code = wmsMechanicalArmH.outbill;
await _wmsCarryBindService.CarryUnbind(carryBindInput);
// 锁住终点库位
await db.Updateable<BasLocation>(r => new BasLocation
{
is_lock = 1
}).Where(r => r.id == endLocation.id).ExecuteCommandAsync();
LoggerFloor2RackDelivery.LogInformation($"【移走下升降区空托的料架】 开始执行预任务生成: 料架区为{wmsMechanicalArmH.name}{wmsMechanicalArmH.stackingposition} 料架为{wmsMechanicalArmH.rackcode}");
bool result = await createPretask(wmsMechanicalArmH.location_id, endLocation.id, wmsMechanicalArmH.rackid, wmsMechanicalArmH.rackcode, LoggerFloor2RackDelivery);
if (!result)
{
LoggerFloor2RackDelivery.LogInformation($"【移走下升降区空托的料架】 未成功生成预任务 起点{wmsMechanicalArmH.location_code} 终点{endLocation.location_code} 料架 {wmsMechanicalArmH.rackcode}");
continue;
}
}
//await db.CommitTranAsync();
}
catch (Exception ex)
{
LoggerFloor2RackDelivery.LogInformation($"【移走下升降区空托的料架】 {ex.Message}");
LoggerFloor2RackDelivery.LogInformation($"【移走下升降区空托的料架】 {ex.StackTrace}");
//await db.RollbackTranAsync();
}
finally
{
s_task移走下升降区未生成预任务且空托的料架.Release();
_wareHouseService.GenTaskExecute();
}
}
}
// 上下升降机生成预任务(补充料架、上升降机取货到料架、上升降机满托运走,下升降机拿货到输送线、下升降机空托运走)
private async Task<bool> createPretask(string startlocation_id, string endlocation_id, string carry_id, string carry_code, ILogger logger)
{
CommonCreatePretaskInput commonCreatePretaskInput = new CommonCreatePretaskInput();
commonCreatePretaskInput.startlocation_id = startlocation_id;
commonCreatePretaskInput.endlocation_id = endlocation_id;
commonCreatePretaskInput.carry_id = carry_id;
commonCreatePretaskInput.carry_code = carry_code;
commonCreatePretaskInput.task_type = WmsWareHouseConst.BIZTYPE_WMSTRANSFER_ID;
commonCreatePretaskInput.biz_type = "";
commonCreatePretaskInput.require_id = "";
commonCreatePretaskInput.isExcuteMission = false;
logger.LogInformation($"开始执行 GenPreTask {JsonConvert.SerializeObject(commonCreatePretaskInput)}");
var res = await _wareHouseService.CommonCreatePretask(commonCreatePretaskInput);
if (res.code == JNPF.Common.Enums.HttpStatusCode.OK)
{
logger.LogInformation($"GenPreTask 结果 {JsonConvert.SerializeObject(res)}");
return true;
}
return false;
}
#region
public async Task<bool> GetBoolTag(string DevName, string field)
{
try
{
string jsonString = await _redisData.GetHash(DevName, field);
JObject jsonObject = JObject.Parse(jsonString);
if (jsonObject.TryGetValue("Value", out JToken valueToken2))
{
return bool.Parse(valueToken2.ToString());
}
else
{
Console.WriteLine($"未找到匹配项 {DevName} {field}");
}
}
catch (Exception ex)
{
Console.WriteLine($"未找到匹配项{DevName} {field}");
}
return false;
}
public async Task<string> GetStringTag(string DevName, string field)
{
#region
//try
//{
// string jsonString = await _redisData.GetHash(DevName, field);
// JObject jsonObject = JObject.Parse(jsonString);
// if (jsonObject.TryGetValue("StatusCode", out JToken valueToken1))
// {
// if (valueToken1.ToString() == "-1")
// return "";
// }
// if (jsonObject.TryGetValue("Value", out JToken valueToken2))
// {
// return valueToken2.ToString();
// }
// else
// {
// Console.WriteLine($"未找到匹配项 {DevName} {field}");
// }
//}
//catch (Exception ex)
//{
// // 捕获并处理异常
// Console.WriteLine($"发生异常: {ex.Message}");
//}
//return $"未找到匹配项 {DevName} {field}";
#endregion
try
{
string jsonString = await _redisData.GetHash(DevName, field);
string pattern = "\"Value\":\"(.*?)\"";
System.Text.RegularExpressions.Match match = Regex.Match(jsonString, pattern);
if (match.Success)
{
return match.Groups[1].Value;
}
else
{
Console.WriteLine($"未找到匹配项{DevName} {field}");
}
}
catch (Exception ex)
{
Console.WriteLine($"未找到匹配项{DevName} {field}");
}
return $"未找到匹配项 {DevName} {field}";
}
private async Task<bool> Floor2UpDownMachinecode_SetTag(string tag, string value)
{
string DevName = "东面提升机输送线";
Dictionary<string, string> dicCommand = new(StringComparer.OrdinalIgnoreCase)
{
["DevName"] = DevName,
["token"] = _eleCtlCfg.token,
["TagName"] = tag,
["Value"] = value,
};
string result = await HttpClientHelper.GetRequestAsync(_eleCtlCfg.WriteTagUrl, dicCommand);
return result.Contains("Ok");
// 测试
//string DevName = "东面提升机输送线";
//JObject valueJson = new JObject();
//valueJson["Value"] = value;
//_redisData.SetHash(DevName, tag, valueJson.ToString());
//return true;
}
#endregion
#endregion
public Task StartAsync(CancellationToken cancellationToken)
{
//Readtimer = new Timer(GetRedisData, null, TimeSpan.Zero, TimeSpan.FromSeconds(300));
CheckGettimer = new Timer(CheckGet, null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
Scantimer = new Timer(ScanInStock, null, TimeSpan.Zero, TimeSpan.FromSeconds(60));
SSXcodetimer = new Timer(SSXcode, null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
// 八工位缓存区补充空托盘
BGWCarrySupplementtimer = new Timer(BGWCarrySupplement, null, TimeSpan.Zero, TimeSpan.FromSeconds(30));
// 供料叠盘机空托盘自动入库
YCLGLDPJInstocktimer = new Timer(YCLGLDPJInstock, null, TimeSpan.Zero, TimeSpan.FromSeconds(30));
// 外协叠盘机空托盘自动入库
//YCLWXDPJInstocktimer = new Timer(YCLWXDPJInstock, null, TimeSpan.Zero, TimeSpan.FromSeconds(100000));
// 二楼上升降机
Floor2UpMachinecodetimer = new Timer(Floor2UpMachinecode, null, TimeSpan.Zero, TimeSpan.FromSeconds(20));
// 二楼料架配送
Floor2timer送空托到上升降区 = new Timer(, null, TimeSpan.Zero, TimeSpan.FromSeconds(30));
Floor2timer送满托到下升降区 = new Timer(, null, TimeSpan.Zero, TimeSpan.FromSeconds(30));
Floor2timer移走上升降区未生成预任务且满托的料架 = new Timer(, null, TimeSpan.Zero, TimeSpan.FromSeconds(30));
Floor2timer移走下升降区未生成预任务且空托的料架 = new Timer(, null, TimeSpan.Zero, TimeSpan.FromSeconds(30));
// 7号线补充空料箱 (弃用)
//SSX7Supplementtimer = new Timer(SSX7Supplement, null, TimeSpan.Zero, TimeSpan.FromSeconds(30));
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
}