Files
wcs/WCS.BLL/HardWare/MXL4Shelf.cs
2024-12-10 19:09:43 +08:00

671 lines
29 KiB
C#

using System;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using WCS.BLL.Config;
using WCS.BLL.DbModels;
using WCS.BLL.DbModels.Task;
using WCS.BLL.Manager;
using WCS.DAL.Db;
using WCS.DAL.DbModels;
using WCS.Model;
using WCS.Model.ApiModel.InOutRecord;
using WCS.Model.ApiModel.OutStore;
using WCS.Model.WebSocketModel;
using static WCS.BLL.HardWare.WarningLight;
namespace WCS.BLL.HardWare
{
/// <summary>
/// 智能货架
/// </summary>
public class MXL4Shelf : IShelfBase
{
public MXL4Shelf(ShelfInfo shelfInfo)
{
ShelfTypeName = shelfInfo.ShelfTypeName;
ShelfId = shelfInfo.Id;
ShelfCode = shelfInfo.ShelfCode;
RowCounts = shelfInfo.Rowcounts;
ColumnCounts = shelfInfo.Columncounts;
SetCurrentMode(TaskModeEnum.);
ClientIp = shelfInfo.ClientIp;
LightId = shelfInfo.LightId;
WarningLight = new WarningLight() { LightId = shelfInfo.LightId };
//初始化Module
var task = Task.Run(() =>
{
var modules = DbHelp.db.Queryable<ModuleInfo>().Where(t => t.ShelfId == ShelfId).ToList();
foreach (var module in modules)
{
MXL4Modules.Add(new MXL4ShelfModule()
{
ModuleId = module.Id,
ModuleCode = module.ModuleCode,
BoardId = module.BoardId,
IsEnable = module.IsEnable,
CurrentMode = module.CurrentMode
});
}
ModulesStr = string.Join(";", MXL4Modules.Select(t => t.ModuleCode));
ModuleIds = MXL4Modules.Select(t => t.BoardId).ToList();
});
//一个货架存在一个线程去刷新数据
Task.Run(async () =>
{
//等待模组加载完毕再开始发送数据进行刷新
Task.WaitAll(task);
while (true)
{
Logs.Write($"[test]{ShelfCode}");
try
{
//未完成首次连接时 暂不发送
if (TcpCleint.IsFirstConnected == false)
{
await Task.Delay(2000);
continue;
}
//查询是否有需要刷新的
var needRefreshModules = MXL4Modules.Where(t => t.IsNeedRefresh)
.ToList();
foreach (var module in needRefreshModules)
{
//查询当前是否有任务
var currentTasks = DbHelp.db.Queryable<CurrentTask>()
.Where(t => t.ModuleId == module.ModuleId)
.Where(t => t.IsSended == false)
.OrderBy(t => t.CreateTime)
.ToList();
//入库、出库、盘点等任务
if (currentTasks != null && currentTasks.Count > 0)
{
var firstTask = currentTasks.First();
var taskMode = currentTasks.First().TaskMode;
#region Continue
if (module.CurrentMode == TaskModeEnum.)
{
//进入对应模式
switch (taskMode)
{
case (TaskModeEnum.):
module.GoInInstoreMode(TcpCleint);
break;
case (TaskModeEnum.):
module.GoInOutstoreMode(TcpCleint);
break;
case (TaskModeEnum.):
module.GoInStocktakingMode(TcpCleint);
break;
default:
break;
}
//等待10ms这边将状态成功更新了来
await Task.Delay(10);
}
else
{
taskMode = module.CurrentMode;
}
#endregion
//只显示当前模式的任务
currentTasks = currentTasks.Where(t => t.TaskMode == taskMode).ToList();
//这个分支应该很少跑到 有刷新必然有新任务
if (currentTasks == null || currentTasks.Count == 0)
{
Logs.Write($"【后台发送线程】{module.ModuleCode}当前模式{module.CurrentMode},需要刷新!但是没有对应的新任务!");
var tasks = DbHelp.db.Queryable<CurrentTask>()
.Where(t => t.ModuleId == module.ModuleId)
.Where(t => t.IsSended == true)
.Where(t => t.TaskMode == taskMode)
.OrderBy(t => t.CreateTime)
.ToList();
if (tasks != null && tasks.Count > 0)
{
Logs.Write($"【后台发送线程】{module.ModuleCode}当前模式{module.CurrentMode},需要刷新!但是没有对应的新任务!有已发送的任务未完成故不处理!");
module.IsNeedRefresh = false;
continue;
}
//退出对应模式到待机模式! 后续持续刷新数据!
else
{
Logs.Write($"【后台发送线程】{module.ModuleCode}当前模式{module.CurrentMode},需要刷新!但是没有对应的新任务!没有已发送未完成的任务!退出当前模式!");
// 退出对应模式
switch (taskMode)
{
case (TaskModeEnum.):
module.GoOutInstoreMode(TcpCleint);
break;
case (TaskModeEnum.):
module.GoOutOutstoreMode(TcpCleint);
break;
case (TaskModeEnum.):
module.GoOutStocktakingMode(TcpCleint);
break;
default:
break;
}
continue;
}
}
//按照任务顺序给其发送数据
foreach (var currentTask in currentTasks)
{
module.SendTaskId(currentTask.TaskID, TcpCleint);
module.SendMatCode(currentTask.MatCode, TcpCleint);
module.SendMatName(currentTask.MatName, TcpCleint);
module.SendMatSpec(currentTask.MatSpec, TcpCleint);
module.SendMatBatch(currentTask.MatBatch, TcpCleint);
module.SendMatQty(currentTask.Qty, TcpCleint);
currentTask.IsSended = true;
DbHelp.db.Updateable(currentTask).ExecuteCommand();
}
//发送完毕后就不刷新了
module.IsNeedRefresh = false;
continue;
}
//不存在入库、出库、盘点等任务 应该变成待机
else
{
//退出对应模式到待机模式! 后续持续刷新数据!
if (module.CurrentMode != TaskModeEnum.)
{
// 退出对应模式
switch (module.CurrentMode)
{
case (TaskModeEnum.):
module.GoOutInstoreMode(TcpCleint);
break;
case (TaskModeEnum.):
module.GoOutOutstoreMode(TcpCleint);
break;
case (TaskModeEnum.):
module.GoOutStocktakingMode(TcpCleint);
break;
default:
break;
}
continue;
}
//向上层系统获取数据
//获取成功 有数据 绑定对应数据
//获取成功 无数据
module.StandbyNoInfoDisplay(TcpCleint);
module.IsNeedRefresh = false;//未获取到库存数据 回没有库位显示信息给硬件
//获取失败 跳过此次循环后继续获取
}
}
}
catch (Exception ex)
{
Logs.Write($"【后台发送线程】遇到异常{ex.Message},{ex.StackTrace}");
}
await Task.Delay(1000);
}
});
}
public string ShelfTypeName { get; set; }
public int ShelfId { get; set; }
public string ShelfCode { get; set; }
public int RowCounts { get; set; }
public int ColumnCounts { get; set; }
public TaskModeEnum CurrentMode { get; set; }
public DateTime SetCurrentModeTime { get; set; }
public string ModulesStr { get; set; }//当前货架所有模组的Str
public string GroupName { get; set; }
public List<SmartShelfModule> Modules { get; set; } = new List<SmartShelfModule>();
public List<MXL4ShelfModule> MXL4Modules { get; set; } = new List<MXL4ShelfModule>();
public TCPClient TcpCleint { get { return TCPClientManager.GetTCPClientByIPHost(ClientIp); } }
public int LightId { get; set; }
public LightColorEnum LightColor { get; set; }
public bool IsWarning { get; set; } = false;
public WarningLight WarningLight { get; set; }
public void ClearWarning()
{
if (this.CurrentMode == TaskModeEnum.)
{
WarningLight.BlueLight(TcpCleint);
}
else if (this.CurrentMode == TaskModeEnum.)
{
WarningLight.GreenLight(TcpCleint);
}
else if (this.CurrentMode == TaskModeEnum.)
{
WarningLight.GreenLight(TcpCleint);
}
else
{
WarningLight.CloseLight(TcpCleint);
}
}
/// <summary>
/// 自检异常、未响应对应模式的异常
/// </summary>
public List<string> ExceptionMessages { get; set; } = new List<string>();
/// <summary>
/// 过程中异常 入库过程中异常/出库过程中异常
/// </summary>
public List<ProcessingExceptionType> ProcessingExceptions { get; set; } = new List<ProcessingExceptionType>();
public string? CurrentCom { get; set; } = string.Empty;
public MatInfoResponse InStoreData { get; set; }
public List<string> CurrentOutStoreMatSNs { get; set; } = new List<string>();
public OutOrder CurrentOutOrder { get; set; }
public string OrderNumber { get; set; }
public StockTakingOrder CurrentStockTakingOrder { get; set; }
public List<int> ModuleIds { get; set; }
public string ClientIp { get; set; }
//websocket通知的前端的IP地址
public string WebSocketIpAddress { get; set; } = "127.0.0.2";
public string OutOperateUser { get; set; } = string.Empty;
#region
public void Reset()
{
MXL4Modules.ForEach(t => t.Reset(TcpCleint));
}
#region
void IShelfBase.Warning()
{
}
public void ShelfCheck()
{
}
public void GoInInstore(string? IPAddress)
{
}
public void GoOutInstore()
{
}
public void GoInOutstore(List<OutOrderMatDetail> MatDetails, OutOrder outOrder, string OperateUser)
{
}
public void GoOutOutstore()
{
}
public void GoInStocktaking(List<StockTakingOrderMatDetail> MatDetails, StockTakingOrder stockTakingOrder)
{
}
/// <summary>
/// 确认盘点 Pda进行触发
/// </summary>
public bool ConfirmStocktakingSingle(int BoardId, int LightNumber)
{
return false;
}
public void GoOutStocktaking()
{
}
#endregion
public void SetCurrentMode(TaskModeEnum mode)
{
this.CurrentMode = mode;
this.SetCurrentModeTime = DateTime.Now;
Task.Run(() =>
{
var shelf = DbHelp.db.Queryable<ShelfInfo>().Where(t => t.Id == ShelfId).First();
if (shelf != null)
{
shelf.CurrentMode = mode;
shelf.SetCurrentModeTime = SetCurrentModeTime;
DbHelp.db.Updateable(shelf).ExecuteCommand();
}
});
}
#endregion
#region
public void WarningLightProcess(byte[] data, int boardId)
{
if (data[TcpCleint.PreFixLength + 2] == 0x20 && data[TcpCleint.PreFixLength + 3] == 0x01)
{
//常亮或关闭 0x00常亮 0x01关闭
if (data[TcpCleint.PreFixLength + 5] == 0x00)
{
LightColor = LightColorEnum.;
Logs.Write($"货架[{ShelfCode}],灯状态更新为:{LightColor}");
}
else if (data[TcpCleint.PreFixLength + 5] == 0x01)
{
switch (data[7])
{
case 0x01:
LightColor = LightColorEnum.;
break;
case 0x02:
LightColor = LightColorEnum.绿;
break;
case 0x03:
LightColor = LightColorEnum.;
break;
default:
break;
}
Logs.Write($"货架[{ShelfCode}],灯状态更新为:{LightColor}");
}
}
}
#endregion
#region
public void ProtocolProcess(byte[] data, int boardId)
{
//协议处理 判断功能位
switch (data[TcpCleint.PreFixLength + 2])
{
case 0xA4://标签回到待机模式 请求获取显示数据的信号
if (data[TcpCleint.PreFixLength + 3] == 0x02)
GoBackStandbyModeReturnProcess(data, boardId);
break;
case 0xA1:
//标签返回入库成功信号
if (data[TcpCleint.PreFixLength + 3] == 0x05)
InStoreSuccessProcess(data, boardId);
//进入入库模式成功
else if (data[TcpCleint.PreFixLength + 3] == 0x01)
GoInInStoreReturnProcess(data, boardId);
//退出入库模式
else if (data[TcpCleint.PreFixLength + 3] == 0x03)
GoBackStandbyModeReturnProcess(data, boardId);
break;
case 0xA2:
//标签返回出库成功信号
if (data[TcpCleint.PreFixLength + 3] == 0x04)
OutStoreSuccessProcess(data, boardId);
//进入出库模式成功
else if (data[TcpCleint.PreFixLength + 3] == 0x01)
GoInOutStoreReturnProcess(data, boardId);
//退出出库模式
else if (data[TcpCleint.PreFixLength + 3] == 0x03)
GoBackStandbyModeReturnProcess(data, boardId);
break;
case 0xA3:
//标签返回盘点成功信号
if (data[TcpCleint.PreFixLength + 3] == 0x03)
StocktakingSuccessProcess(data, boardId);
//进入盘点模式
else if (data[TcpCleint.PreFixLength + 3] == 0x01)
GoInStocktakingReturnProcess(data, boardId);
//退出盘点模式
else if (data[TcpCleint.PreFixLength + 3] == 0x02)
GoBackStandbyModeReturnProcess(data, boardId);
break;
default:
;
break;
}
}
/// <summary>
/// 标签回到待机模式
/// </summary>
/// <param name="data"></param>
public void GoBackStandbyModeReturnProcess(byte[] data, int boardId)
{
//获取对应的模组
var module = MXL4Modules.Where(t => t.BoardId == boardId)
.FirstOrDefault();
if (module != null)
{
module.IsNeedRefresh = true;
}
else
{
Logs.Write($"【回到待机模式】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!");
}
SetCurrentMode(TaskModeEnum.);
}
/// <summary>
/// 标签返回进入入库模式信号
/// </summary>
/// <param name="data"></param>
public void GoInInStoreReturnProcess(byte[] data, int boardId)
{
//获取对应的模组
var module = MXL4Modules.Where(t => t.BoardId == boardId)
.FirstOrDefault();
if (module != null)
{
module.SetCurrentMode(TaskModeEnum.);
}
else
{
Logs.Write($"【进入入库模式成功】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!");
}
}
/// <summary>
/// 标签返回进入出库模式信号
/// </summary>
/// <param name="data"></param>
public void GoInOutStoreReturnProcess(byte[] data, int boardId)
{
//获取对应的模组
var module = MXL4Modules.Where(t => t.BoardId == boardId)
.FirstOrDefault();
if (module != null)
{
module.SetCurrentMode(TaskModeEnum.);
}
else
{
Logs.Write($"【进入出库模式成功】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!");
}
}
/// <summary>
/// 标签返回进入盘点模式信号
/// </summary>
/// <param name="data"></param>
public void GoInStocktakingReturnProcess(byte[] data, int boardId)
{
//获取对应的模组
var module = MXL4Modules.Where(t => t.BoardId == boardId)
.FirstOrDefault();
if (module != null)
{
module.SetCurrentMode(TaskModeEnum.);
}
else
{
Logs.Write($"【进入盘点模式成功】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!");
}
}
/// <summary>
/// 标签返回入库成功信号
/// </summary>
/// <param name="data"></param>
public void InStoreSuccessProcess(byte[] data, int boardId)
{
var taskId = Convert.ToInt32(data[TcpCleint.PreFixLength + 4]);
var finishQty = (data[TcpCleint.PreFixLength + 5] << 8) + data[TcpCleint.PreFixLength + 6];
//获取对应的模组
var module = MXL4Modules.Where(t => t.BoardId == boardId)
.FirstOrDefault();
if (module != null)
{
//获取对应的任务
var task = DbHelp.db.Queryable<CurrentTask>()
.Where(t => t.ModuleCode == module.ModuleCode)
.Where(t => t.TaskID == taskId)
.First();
if (task != null)
{
var finishedTask = new FinishedTask()
{
ShelfId = task.ShelfId,
ShelfCode = task.ShelfCode,
ModuleId = task.ModuleId,
ModuleCode = task.ModuleCode,
StoreId = task.StoreId,
StoreCode = task.StoreCode,
TaskID = task.TaskID,
Guid = task.Guid,
TaskMode = task.TaskMode,
OrderNumber = task.OrderNumber,
ButtonColor = task.ButtonColor,
MatCode = task.MatCode,
MatName = task.MatName,
MatSpec = task.MatSpec,
MatBatch = task.MatBatch,
MatSN = task.MatSN,
CreateTime = task.CreateTime,
FinishQty = finishQty,
FinishTime = DateTime.Now,
};
DbHelp.db.Insertable(finishedTask).ExecuteCommand();
DbHelp.db.Deleteable(task).ExecuteCommand();
}
else
{
Logs.Write($"【入库成功】货架【{ShelfCode}】通过模组{module.ModuleCode}({boardId}),通过任务id{taskId}未找到对应任务!");
}
}
else
{
Logs.Write($"【入库成功】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!");
}
}
/// <summary>
/// 标签返回出库成功信号
/// </summary>
/// <param name="data"></param>
public void OutStoreSuccessProcess(byte[] data, int boardId)
{
var taskId = Convert.ToInt32(data[TcpCleint.PreFixLength + 4]);
var finishQty = (data[TcpCleint.PreFixLength + 5] << 8) + data[TcpCleint.PreFixLength + 6];
//获取对应的模组
var module = MXL4Modules.Where(t => t.BoardId == boardId)
.FirstOrDefault();
if (module != null)
{
//获取对应的任务
var task = DbHelp.db.Queryable<CurrentTask>()
.Where(t => t.ModuleCode == module.ModuleCode)
.Where(t => t.TaskID == taskId)
.First();
if (task != null)
{
var finishedTask = new FinishedTask()
{
ShelfId = task.ShelfId,
ShelfCode = task.ShelfCode,
ModuleId = task.ModuleId,
ModuleCode = task.ModuleCode,
StoreId = task.StoreId,
StoreCode = task.StoreCode,
TaskID = task.TaskID,
Guid = task.Guid,
TaskMode = task.TaskMode,
OrderNumber = task.OrderNumber,
ButtonColor = task.ButtonColor,
MatCode = task.MatCode,
MatName = task.MatName,
MatSpec = task.MatSpec,
MatBatch = task.MatBatch,
MatSN = task.MatSN,
CreateTime = task.CreateTime,
FinishQty = finishQty,
FinishTime = DateTime.Now,
};
DbHelp.db.Insertable(finishedTask).ExecuteCommand();
DbHelp.db.Deleteable(task).ExecuteCommand();
}
else
{
Logs.Write($"【出库成功】货架【{ShelfCode}】通过模组{module.ModuleCode}({boardId}),通过任务id{taskId}未找到对应任务!");
}
}
else
{
Logs.Write($"【出库成功】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!");
}
}
/// <summary>
/// 标签返回盘点成功信号
/// </summary>
/// <param name="data"></param>
public void StocktakingSuccessProcess(byte[] data, int boardId)
{
var taskId = Convert.ToInt32(data[TcpCleint.PreFixLength + 4]);
var finishQty = (data[TcpCleint.PreFixLength + 5] << 8) + data[TcpCleint.PreFixLength + 6];
//获取对应的模组
var module = MXL4Modules.Where(t => t.BoardId == boardId)
.FirstOrDefault();
if (module != null)
{
//获取对应的任务
var task = DbHelp.db.Queryable<CurrentTask>()
.Where(t => t.ModuleCode == module.ModuleCode)
.Where(t => t.TaskID == taskId)
.First();
if (task != null)
{
var finishedTask = new FinishedTask()
{
ShelfId = task.ShelfId,
ShelfCode = task.ShelfCode,
ModuleId = task.ModuleId,
ModuleCode = task.ModuleCode,
StoreId = task.StoreId,
StoreCode = task.StoreCode,
TaskID = task.TaskID,
Guid = task.Guid,
TaskMode = task.TaskMode,
OrderNumber = task.OrderNumber,
ButtonColor = task.ButtonColor,
MatCode = task.MatCode,
MatName = task.MatName,
MatSpec = task.MatSpec,
MatBatch = task.MatBatch,
MatSN = task.MatSN,
CreateTime = task.CreateTime,
FinishQty = finishQty,
FinishTime = DateTime.Now,
};
DbHelp.db.Insertable(finishedTask).ExecuteCommand();
DbHelp.db.Deleteable(task).ExecuteCommand();
}
else
{
Logs.Write($"【盘点成功】货架【{ShelfCode}】通过模组{module.ModuleCode}({boardId}),通过任务id{taskId}未找到对应任务!");
}
}
else
{
Logs.Write($"【盘点成功】货架【{ShelfCode}】通过板子ID【{boardId}】未找到对应模组!");
}
}
#endregion
}
}