Files
wcs/WCS.BLL/HardWare/SmartShelf.cs
hehaibing-1996 549a45dcf0 1.智能货架退出出库后解锁
2.数据库支持多线程
3.调整出库单据导入模板
2025-03-14 08:34:03 +08:00

2507 lines
119 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

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

using System;
using WCS.BLL.Config;
using WCS.BLL.DbModels;
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 SmartShelf : IShelfBase
{
public SmartShelf(ShelfInfo shelfInfo)
{
ShelfId = shelfInfo.Id;
ShelfCode = shelfInfo.ShelfCode;
RowCounts = shelfInfo.Rowcounts;
ColumnCounts = shelfInfo.Columncounts;
SetCurrentMode(Mode.);
ClientIp = shelfInfo.ClientIp;
LightId = shelfInfo.LightId;
WarningLight = new WarningLight() { LightId = shelfInfo.LightId };
//初始化Module
Task.Run(() =>
{
var modules = DbHelp.db.Queryable<ModuleInfo>().Where(t => t.ShelfId == ShelfId).ToList();
foreach (var module in modules)
{
Modules.Add(new SmartShelfModule()
{
ModuleId = module.Id,
ModuleCode = module.ModuleCode,
BoardId = module.BoardId,
IsEnable = module.IsEnable,
CurrentMode = module.CurrentMode
});
}
ModulesStr = string.Join(";", Modules.Select(t => t.ModuleCode));
ModuleIds = Modules.Select(t => t.BoardId).ToList();
});
}
public int ShelfId { get; set; }
public string ShelfCode { get; set; }
public int RowCounts { get; set; }
public int ColumnCounts { get; set; }
public Mode 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 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 == Mode.)
{
WarningLight.BlueLight(TcpCleint);
}
else if (this.CurrentMode == Mode.)
{
WarningLight.GreenLight(TcpCleint);
}
else if (this.CurrentMode == Mode.)
{
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 GoInInstore(string? IPAddress)
{
try
{
Logs.Write($"[GoInInstore IPAddress]{IPAddress}", LogsType.Instore);
if (this.CurrentMode == Mode.)
{
CurrentCom = IPAddress;
return;
}
//判断当前模式是否为待机模式
else if (this.CurrentMode != Mode.)
{
return;
}
else
{
//this.CurrentMode = Mode.入库模式;
SetCurrentMode(Mode.);
}
//清空错误
ExceptionMessages.Clear();
ProcessingExceptions.Clear();
this.IsWarning = false; //清空报警状态以免报警后 处理了异常后续无法亮灯
//货架所有模组发送指令进入入库模式
Logs.Write($"货架{ShelfCode}开始发送指令进入入库模式", LogsType.Instore);
foreach (var module in Modules.Where(t => t.IsEnable).ToList())
{
Logs.Write($"货架{ShelfCode}模组【{module.ModuleCode}】发送指令进入入库模式", LogsType.Instore);
module.GoInInstoreMode(TcpCleint);
}
Logs.Write($"货架{ShelfCode}指令发送完毕", LogsType.Instore);
//延时获取异常
var timeOut = 3000;
var timeSpan = TimeSpan.FromMilliseconds(0);
var beginTime = DateTime.Now;
while (timeSpan <= TimeSpan.FromMilliseconds(timeOut))
{
timeSpan = DateTime.Now - beginTime;
//所有板子成功进入入库模式 表示进入入库模式成功,跳出循环
var isExistsNotInstore = Modules.Where(t => t.CurrentMode != Mode.)
.Where(t => t.IsEnable)
.Any();
if (!isExistsNotInstore)
{
break;
}
//接收到第一个异常就不继续循环了
if (ExceptionMessages.Count() > 0)
{
var deficientTime = timeOut - (int)timeSpan.TotalMilliseconds;
if (deficientTime > 0)
Thread.Sleep(deficientTime);
//出现异常的未进入入库模式,有红灯进行指引
break;
}
//循环延时处理
Thread.Sleep(50);
}
//循环结束后判断当前板子状态
var notInstoreList = Modules.Where(t => t.CurrentMode != Mode.)
.Where(t => t.IsEnable).ToList();
if (notInstoreList.Count > 0)
{
Logs.Write($"货架{ShelfCode}存在模组未进入入库模式", LogsType.Instore);
foreach (var item in notInstoreList)
{
ExceptionMessages.Add($"模组{item.ModuleCode}未进入入库模式!");
}
//通信校验
var messages = notInstoreList.Select(t => $"模组{t.ModuleCode}未进入入库模式!").ToList();
messages.Add("请及时联系技术人员处理!");
var exceptionMessage = string.Join("\r\n", messages);
var warningModel = new WebSocketMessageModel()
{
IsWarning = true,
WarningType = WarningTypeEnum.,
StoreId = 0,
StoreCode = "",
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress,
};
WarningManager.SendWarning(warningModel);
IsWarning = true;
WarningLight.WaringLightAlwaysRed(TcpCleint);
}
//没有报警才亮蓝灯
Logs.Write($"货架{ShelfCode}IsWarning现在为{IsWarning}", LogsType.Instore);
if (!IsWarning)
WarningLight.BlueLight(TcpCleint);
//绑定当前进入入库PDA/WCS前端的IP
CurrentCom = IPAddress;
Logs.Write($"[GoInInstore CurrentCom]{CurrentCom}", LogsType.Instore);
//返回成功
return;
}
catch (Exception ex)
{
GoOutInstore();
throw ex;
}
}
public void GoOutInstore()
{
//当前货架是否为入库模式
if (CurrentMode != Mode.)
{
return;
}
else
{
//this.CurrentMode = Mode.待机模式;
SetCurrentMode(Mode.);
}
//清空错误
ExceptionMessages.Clear();
//货架所有模组发送指令退出入库模式
foreach (var module in Modules.Where(t => t.IsEnable)
.ToList())
{
if (module.CurrentMode == Mode.)
module.GoOutInstoreMode(TcpCleint);
}
var timeOut = 3000;
var timeSpan = TimeSpan.FromMilliseconds(0);
var beginTime = DateTime.Now;
while (timeSpan <= TimeSpan.FromMilliseconds(timeOut))
{
timeSpan = DateTime.Now - beginTime;
//所有板子是否成功退出入库模式
var isExistsInstore = Modules.Where(t => t.CurrentMode != Mode.)
.Where(t => t.IsEnable)
.Any();
if (!isExistsInstore)
{
break;
}
//循环延时处理
Thread.Sleep(50);
}
//循环结束后判断当前板子状态
var list = Modules.Where(t => t.CurrentMode != Mode.)
.Where(t => t.IsEnable)
.ToList();
if (list.Count > 0)
{
//CurrentMode = Mode.待机模式;
SetCurrentMode(Mode.);
foreach (var item in list)
{
ExceptionMessages.Add($"模组{item.ModuleCode}未成功退出入库模式!");
}
var messages = list.Select(t => $"模组{t.ModuleCode}未成功退出入库模式!").ToList();
messages.Add("请及时联系技术人员处理!");
var exceptionMessage = string.Join("\r\n", messages);
var warningModel = new WebSocketMessageModel()
{
IsWarning = true,
WarningType = WarningTypeEnum.退,
StoreId = 0,
StoreCode = "",
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress,
};
WarningManager.SendWarning(warningModel);
}
//报警灯熄灭
WarningLight.CloseLight(TcpCleint);
//通知前台货架已结束入库
Task.Run(() =>
{
var warningModel = new WebSocketMessageModel()
{
IsWarning = false,
WarningType = WarningTypeEnum.,
StoreId = 0,
StoreCode = "",
ShelfCode = ShelfCode,
ShelfId = ShelfId,
ClientIp = WebSocketIpAddress,
};
WarningManager.SendWarning(warningModel);
});
}
/// <summary>
/// 由自检异常等错误导致的 手动操作处理后重新进入出库模式
/// </summary>
/// <param name="ModuleId"></param>
public void GoInOutstoreByWebSocket(int moduleId)
{
try
{
Logs.Write("GoInOutstoreByWebSocket", LogsType.Outstore);
//找到对应的模组
var module = Modules.Where(t => t.ModuleId == moduleId).First();
if (module == null)
{
Logs.Write($"GoInOutstoreByModule货架【{ShelfCode}】未找到MouduleId为{moduleId}的模组", LogsType.Outstore);
return;
}
//判断删除后是否还有继续需要亮灯的情况
if (module.CurrentOutSns == null || module.CurrentOutSns.Count == 0)
{
Logs.Write($"GoInOutstoreByModule货架【{ShelfCode}】,模组【{module.ModuleCode}】,不存在需要继续出的物料,给其复位。", LogsType.Outstore);
//不需要这个模组继续亮灯了
module.GoOutOutStoreMode(TcpCleint);
Thread.Sleep(400);
//判断此货架是否还有出库模式的模块
#region 退
var isExsistOut = CurrentOutStoreMatSNs.Any();
//本次亮灯的物料已全部取出
if (!isExsistOut)
{
Logs.Write($"货架【{ShelfCode}】,本次亮灯的物料已全部取出", LogsType.Outstore);
CurrentOutOrder = null;
//退出出库模式
var taskGoOut = Task.Run(() =>
{
Thread.Sleep(10);
GoOutOutstore();
});
//看是否是分批次出库的情况 分批次亮灯
Task.Run(async () =>
{
await Task.WhenAll(taskGoOut);
if (LocalFile.Config.IsSameMatCodeOut)
{
#region
//查一下是否是当前发料单最后一个货架(在出库模式 同一个发料单下)
var isLastShelf = ShelfManager.Shelves
.Where(t => t.OrderNumber == OrderNumber)
.Where(t => t.CurrentMode == Mode.)
.Any();
if (!isLastShelf)
{
Logs.Write($"发料单{OrderNumber},最后一个出库货架,触发精准发料机制!查询是否还存在待出库物料", LogsType.Outstore);
var outOrder = DbHelp.db.Queryable<OutOrder>()
.Where(t => t.OrderNumber == OrderNumber)
.WhereIF(!string.IsNullOrEmpty(LocalFile.Config.GroupName), t => t.GroupName == LocalFile.Config.GroupName)
.First();
if (outOrder != null)
{
var outOrderMatDetails = DbHelp.db.Queryable<OutOrderMatDetail>()
.Where(t => t.OrderId == outOrder.Id)
.Where(t => t.IsSended == false)
.Includes(t => t.StoreInfo)
.ToList();
if (outOrderMatDetails != null && outOrderMatDetails.Count > 0)
{
//相邻物料亮不同颜色 这里绿色和蓝色互相切换
LocalStatic.CurrentOutStoreColor = LocalStatic.CurrentOutStoreColor == (byte)0x02 ? (byte)0x04 : (byte)0x02;
//存在待出库 然后之前又没亮灯的情况 => 继续分批次亮灯
Logs.Write($"发料单{OrderNumber},还有物料未出!", LogsType.Outstore);
var outOrderDetailCount = outOrderMatDetails.GroupBy(t => t.MatCode)
.Select(o => new { count = o.Count(), bb = o })
.Where(o => o.count >= 2)
.OrderByDescending(o => o.count)
.ToList();
//相同物料存在盘数超过2的情况亮下一个盘数多的物料
if (outOrderDetailCount.Count > 0)
{
var matCode = outOrderDetailCount.First().bb.Key;
outOrderMatDetails = outOrderMatDetails.Where(t => t.MatCode == matCode)
.ToList();
Logs.Write($"发料单{OrderNumber},本次亮灯物料{matCode}", LogsType.Outstore);
}
//相同物料不存在盘数超过n的情况剩余物料全部亮灯
else
{
//剩余物料全出
Logs.Write($"发料单{OrderNumber},剩余所有物料灯全亮(发送命令)!", LogsType.Outstore);
}
var shelfIds = outOrderMatDetails.Select(t => t.StoreInfo.ShelfId)
.Distinct()
.ToList();
var shelfs = ShelfManager.Shelves.Where(t => shelfIds.Contains(t.ShelfId)).ToList();
var otherModeShelfs = shelfs.Where(t => t.CurrentMode != HardWare.Mode.).ToList();
if (otherModeShelfs != null && otherModeShelfs.Count > 0)
{
otherModeShelfs.ForEach(t =>
{
t.Reset();
});
Thread.Sleep(1000);
}
//对应的货架对应位置 进入出库模式 亮灯
shelfs.ForEach(shelf =>
{
var matDetails = outOrderMatDetails.Where(t => t.StoreInfo.ShelfCode == shelf.ShelfCode)
.Distinct()
.ToList();
shelf.GoInOutstore(matDetails, outOrder, OutOperateUser);
shelf.OrderNumber = outOrder.OrderNumber;
});
}
else
{
#region
Logs.Write($"发料单{OrderNumber},当前物料已发完!", LogsType.Outstore);
//清空发料单缓存
var outingShelfs = ShelfManager.Shelves.Where(t => t.OrderNumber == OrderNumber).ToList();
outingShelfs.ForEach(t =>
{
t.OrderNumber = string.Empty;
});
Task.Run(() =>
{
//判断是否是当前订单最后一个出库货架
var isOuting = ShelfManager.Shelves.Where(t => t.CurrentMode == Mode. && t.OrderNumber == OrderNumber)
.Any();
//WebSocket通知前台以更新左侧出库单列表的状态
if (!isOuting)
{
#region WebSocket
var messageMode = new WebSocketMessageModel()
{
IsWarning = false,
ClientIp = WebSocketIpAddress,
WarningType = WarningTypeEnum.,
};
WarningManager.SendWarning(messageMode);
#endregion
}
});
#endregion
}
}
else
{
Logs.Write($"发料单{OrderNumber}OutOrder为null肯定是有问题", LogsType.Outstore);
}
}
else
{
Logs.Write($"发料单{OrderNumber},非最后一个出库货架!", LogsType.Outstore);
var otherShelfs = ShelfManager.Shelves
.Where(t => t.OrderNumber == OrderNumber)
.Where(t => t.CurrentMode == Mode.)
.ToList();
otherShelfs.ForEach(shelf =>
{
try
{
if (shelf is SmartShelf)
{
var smartShelf = (SmartShelf)shelf;
Logs.Write($"货架【{smartShelf.ShelfCode}】待取物料{string.Join(",", smartShelf.CurrentOutStoreMatSNs)}", LogsType.Outstore);
}
}
catch
{ }
});
}
#endregion
}
else
{
#region
Logs.Write($"发料单{OrderNumber},当前物料已发完!", LogsType.Outstore);
//清空发料单缓存
var outingShelfs = ShelfManager.Shelves.Where(t => t.OrderNumber == OrderNumber).ToList();
outingShelfs.ForEach(t =>
{
t.OrderNumber = string.Empty;
});
Task.Run(() =>
{
//判断是否是当前订单最后一个出库货架
var isOuting = ShelfManager.Shelves.Where(t => t.CurrentMode == Mode. && t.OrderNumber == OrderNumber)
.Any();
//WebSocket通知前台以更新左侧出库单列表的状态
if (!isOuting)
{
#region WebSocket
var messageMode = new WebSocketMessageModel()
{
IsWarning = false,
ClientIp = WebSocketIpAddress,
WarningType = WarningTypeEnum.,
};
WarningManager.SendWarning(messageMode);
#endregion
}
});
#endregion
}
});
}
#endregion
}
else
{
//继续亮灯
Logs.Write($"GoInOutstoreByModule货架【{ShelfCode}】,模组【{module.ModuleCode}】,存在需要继续出的物料,继续亮灯。", LogsType.Outstore);
module.GoInOutStoreMode(TcpCleint, module.CurrentOutSns);
Thread.Sleep(65);
WarningLight.GreenLight(TcpCleint);
Logs.Write("GoInOutstoreByWebSocket", LogsType.Outstore);
}
}
catch (Exception e)
{
Logs.Write($"GoInOutstoreByModule货架【{ShelfCode}】进入出库模式发生异常!", LogsType.Outstore);
GoOutOutstore();
throw e;
}
}
public void GoInOutstore(List<OutOrderMatDetail> MatDetails, OutOrder outOrder, string OperateUser)
{
try
{
//第一步:设置货架当前模式
if (CurrentMode != Mode.)
{
Modules.ForEach(t => { t.Reset(TcpCleint); });
//复位需要点时间间隔才能响应指令
Thread.Sleep(1500);
}
//CurrentMode = Mode.出库模式;
SetCurrentMode(Mode.);
//设置当前操作人
OutOperateUser = OperateUser;
//第二步货架添加需要出的SN 出库的领料单号
//移除货架所有现有待出库的MatSN
CurrentOutStoreMatSNs.Clear();
////添加属于当前货架的物料
CurrentOutStoreMatSNs.AddRange(MatDetails.Select(t => t.MatSN).ToList());
Logs.Write($"货架【{ShelfCode}】本次发料物料为{string.Join(",", CurrentOutStoreMatSNs)}", LogsType.Outstore);
////记录当前出库的发料单
CurrentOutOrder = outOrder;
////第三步:对应的模组进入出库模式
var boardIds = MatDetails.Select(t => t.StoreInfo.BoardId)
.Distinct()
.OrderBy(t => t)
.ToList();
var outModules = Modules.Where(t => boardIds.Contains(t.BoardId)).ToList();
outModules.ForEach(t =>
{
var outMatSns = MatDetails.Where(mat => mat.StoreInfo.BoardId == t.BoardId)
.Select(mat => mat.MatSN)
.ToList();
t.GoInOutStoreMode(TcpCleint, outMatSns);
Thread.Sleep(45);//出库每块板子之间增加15ms的间隔
});
Thread.Sleep(20);//报警灯在板子之后增加间隔
//所有板子亮灯后 亮警示灯
WarningLight.GreenLight(TcpCleint);
Task.Run(() =>
{
//通信校验
var timeOut = 3000;
var timeSpan = TimeSpan.FromMilliseconds(0);
var beginTime = DateTime.Now;
while (timeSpan <= TimeSpan.FromMilliseconds(timeOut))
{
timeSpan = DateTime.Now - beginTime;
//所有板子成功进入出库模式 表示进入出库模式成功,跳出循环
var isExistsNotInstore = outModules.Where(t => t.CurrentMode != Mode.)
.Where(t => t.IsEnable)
.Any();
if (!isExistsNotInstore)
{
break;
}
//循环延时处理
Thread.Sleep(50);
}
var list = outModules.Where(t => t.IsEnable && t.CurrentMode != Mode.).ToList();
if (list != null && list.Count > 0)
{
var messages = list.Select(t => $"模组{t.ModuleCode}未进入出库模式!").ToList();
messages.Add("请及时联系技术人员处理!");
var exceptionMessage = string.Join("\r\n", messages);
var warningModel = new WebSocketMessageModel()
{
IsWarning = true,
WarningType = WarningTypeEnum.,
StoreId = 0,
StoreCode = "",
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress,
};
WarningManager.SendWarning(warningModel);
}
});
}
catch (Exception e)
{
Logs.Write($"货架【{ShelfCode}】进入出库模式发生异常!", LogsType.Outstore);
GoOutOutstore();
throw e;
}
}
public void GoOutOutstore()
{
try
{
Logs.Write($"货架【{ShelfCode}】,开始退出出库", LogsType.Outstore);
//找到在出库中的模组
var outingModules = Modules.Where(t => t.CurrentMode == Mode.)
.ToList();
foreach (var module in outingModules)
{
module.GoOutOutStoreMode(TcpCleint);
}
//通信校验
var timeOut = 3000;
var timeSpan = TimeSpan.FromMilliseconds(0);
var beginTime = DateTime.Now;
while (timeSpan <= TimeSpan.FromMilliseconds(timeOut))
{
timeSpan = DateTime.Now - beginTime;
//所有板子成功退出出库模式 表示退出出库模式成功,跳出循环
var isExistsOutstore = outingModules.Where(t => t.CurrentMode == Mode.)
.Where(t => t.IsEnable)
.Any();
if (!isExistsOutstore)
{
break;
}
//循环延时处理
Thread.Sleep(50);
}
var list = outingModules.Where(t => t.IsEnable && t.CurrentMode == Mode.).ToList();
if (list != null && list.Count > 0)
{
var messages = list.Select(t => $"模组{t.ModuleCode}未退出出库模式!").ToList();
messages.Add("请及时联系技术人员处理!");
var exceptionMessage = string.Join("\r\n", messages);
var warningModel = new WebSocketMessageModel()
{
IsWarning = true,
WarningType = WarningTypeEnum.退,
StoreId = 0,
StoreCode = "",
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress,
};
WarningManager.SendWarning(warningModel);
}
var currentOutStoreMatSns = CurrentOutStoreMatSNs.ToList();
Task.Run(() =>
{
var matDetails = DbHelp.db.Queryable<InventoryDetail>()
.Where(t => currentOutStoreMatSns.Contains(t.MatSN))
.Where(t => t.IsLocked)
.ToList();
matDetails.ForEach(t => t.IsLocked = false);
DbHelp.db.Updateable(matDetails).ExecuteCommand();
});
CurrentOutStoreMatSNs.Clear();
WarningLight.CloseLight(TcpCleint);
SetCurrentMode(Mode.);
Logs.Write($"货架【{ShelfCode}】,结束退出出库", LogsType.Outstore);
//Task.Run(() =>
//{
// //判断是否是当前订单最后一个出库货架
// var isOuting = ShelfManager.Shelves.Where(t => t.CurrentMode == Mode.出库模式 && t.OrderNumber == OrderNumber)
// .Any();
// //WebSocket通知前台以更新左侧出库单列表的状态
// if (!isOuting)
// {
// #region WebSocket
// var messageMode = new WebSocketMessageModel()
// {
// IsWarning = false,
// ClientIp = WebSocketIpAddress,
// WarningType = WarningTypeEnum.通知刷新出库单列表,
// };
// WarningManager.SendWarning(messageMode);
// #endregion
// }
//});
}
catch (Exception ex)
{
Logs.Write($"货架【{ShelfCode}】,退出出库时发生异常{ex.Message}", LogsType.Outstore);
}
}
public void GoInStocktaking(List<StockTakingOrderMatDetail> MatDetails, StockTakingOrder stockTakingOrder)
{
try
{
//第一步:设置货架当前模式
if (CurrentMode != Mode.)
{
Modules.ForEach(t =>
{
if (CurrentMode != Mode.)
t.Reset(TcpCleint);
});
//复位需要点时间间隔才能响应指令
Thread.Sleep(1500);
}
//CurrentMode = Mode.盘点模式;
SetCurrentMode(Mode.);
//第二步:货架添加 盘点单号 记录当前盘点的发料单
CurrentStockTakingOrder = stockTakingOrder;
//第三步:对应的模组进入盘点模式
var boardIds = MatDetails.Select(t => t.StoreInfo.BoardId)
.Distinct()
.OrderBy(t => t)
.ToList();
var outModules = Modules.Where(t => boardIds.Contains(t.BoardId)).ToList();
outModules.ForEach(t =>
{
var noStockTakings = MatDetails.Where(mat => mat.StoreInfo.BoardId == t.BoardId)
.Where(t => t.IsStocktaking == false)
.Select(mat => mat.MatSN)
.ToList();
t.GoInStockTakingMode(TcpCleint, noStockTakings);
var stockTakings = MatDetails.Where(mat => mat.StoreInfo.BoardId == t.BoardId)
.Where(t => t.IsStocktaking)
.Select(mat => mat.MatSN)
.ToList();
t.ConfirmStockTaking(TcpCleint, stockTakings);
});
//所有板子亮灯后 亮警示灯
WarningLight.GreenLight(TcpCleint);
Task.Run(() =>
{
//通信校验
var timeOut = 3000;
var timeSpan = TimeSpan.FromMilliseconds(0);
var beginTime = DateTime.Now;
while (timeSpan <= TimeSpan.FromMilliseconds(timeOut))
{
timeSpan = DateTime.Now - beginTime;
//所有板子成功进入盘点模式 表示进入盘点模式成功,跳出循环
var isExistsNotInstore = outModules.Where(t => t.CurrentMode != Mode.)
.Where(t => t.IsEnable)
.Any();
if (!isExistsNotInstore)
{
break;
}
//循环延时处理
Thread.Sleep(50);
}
var list = outModules.Where(t => t.IsEnable && t.CurrentMode != Mode.).ToList();
if (list != null && list.Count > 0)
{
var messages = list.Select(t => $"模组{t.ModuleCode}未进入盘点模式!").ToList();
messages.Add("请及时联系技术人员处理!");
var exceptionMessage = string.Join("\r\n", messages);
var warningModel = new WebSocketMessageModel()
{
IsWarning = true,
WarningType = WarningTypeEnum.,
StoreId = 0,
StoreCode = "",
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress,
};
WarningManager.SendWarning(warningModel);
}
});
}
catch (Exception e)
{
GoOutStocktaking();
throw e;
}
}
/// <summary>
/// 确认盘点 Pda进行触发
/// </summary>
public bool ConfirmStocktakingSingle(int BoardId, int LightNumber)
{
//寻找对应模组
var module = Modules.Where(t => t.BoardId == BoardId).FirstOrDefault(); ;
if (module == null)
return false;
else
{
module.ConfirmStockTakingSingle(TcpCleint, LightNumber);
//报警灯闪一下
WarningLight.SuccessLightGreenEnd(TcpCleint);
return true;
}
}
public void GoOutStocktaking()
{
//找到在盘点中的模组
var stockTakingModules = Modules.Where(t => t.CurrentMode == Mode.)
.ToList();
foreach (var module in stockTakingModules)
{
module.GoOutStockTakingMode(TcpCleint);
}
Task.Run(() =>
{
//通信校验
var timeOut = 3000;
var timeSpan = TimeSpan.FromMilliseconds(0);
var beginTime = DateTime.Now;
while (timeSpan <= TimeSpan.FromMilliseconds(timeOut))
{
timeSpan = DateTime.Now - beginTime;
//所有板子成功退出盘点模式 表示退出盘点模式成功,跳出循环
var isExistsNotInstore = stockTakingModules.Where(t => t.CurrentMode == Mode.)
.Where(t => t.IsEnable)
.Any();
if (!isExistsNotInstore)
{
break;
}
//循环延时处理
Thread.Sleep(50);
}
var list = stockTakingModules.Where(t => t.IsEnable && t.CurrentMode == Mode.).ToList();
if (list != null && list.Count > 0)
{
var messages = list.Select(t => $"模组{t.ModuleCode}未退出盘点模式!").ToList();
messages.Add("请及时联系技术人员处理!");
var exceptionMessage = string.Join("\r\n", messages);
var warningModel = new WebSocketMessageModel()
{
IsWarning = true,
WarningType = WarningTypeEnum.退,
StoreId = 0,
StoreCode = "",
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress,
};
WarningManager.SendWarning(warningModel);
}
});
CurrentOutStoreMatSNs.Clear();
WarningLight.CloseLight(TcpCleint);
//this.CurrentMode = Mode.待机模式;
SetCurrentMode(Mode.);
}
public void Reset()
{
var modules = Modules.Where(t => t.IsEnable).ToList();
if (modules != null && modules.Count > 0)
{
modules.ForEach(t =>
{
t.Reset(TcpCleint);
});
}
WarningLight.CloseLight(TcpCleint);
//this.CurrentMode = Mode.待机模式;
SetCurrentMode(Mode.);
}
public void QueryVoltage(int moduleId)
{
var moudle = Modules.Where(t => t.ModuleId == moduleId).First();
if (moudle != null)
{
moudle.QueryVoltage(TcpCleint);
}
}
public void CalibrationSetOffset(int moduleId, int offSet)
{
var moudle = Modules.Where(t => t.ModuleId == moduleId).First();
if (moudle != null)
{
moudle.CalibrationSetOffset(offSet, TcpCleint);
}
}
public void SetCurrentMode(Mode 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();
}
});
}
void IShelfBase.Warning()
{
throw new NotImplementedException();
}
public void ShelfCheck()
{
try
{
if (CurrentMode == Mode.)
OrderNumber = "自检中...";
foreach (var module in Modules.Where(t => t.IsEnable).ToList())
{
module.IsSelfCheck = true;
module.ShelfCheck(TcpCleint);
}
//状态校验 自检模式未响应
Task.Run(() =>
{
var timeOut = 3000;
var timeSpan = TimeSpan.FromMilliseconds(0);
var beginTime = DateTime.Now;
while (timeSpan <= TimeSpan.FromMilliseconds(timeOut))
{
timeSpan = DateTime.Now - beginTime;
//所有板子成功进入入库模式 表示进入入库模式成功,跳出循环
var isSelfChecking = Modules.Where(t => t.IsSelfCheck)
.Where(t => t.IsEnable)
.Any();
if (!isSelfChecking)
{
break;
}
//循环延时处理
Thread.Sleep(50);
}
var notReturnList = Modules.Where(t => t.IsSelfCheck)
.Where(t => t.IsEnable).ToList();
if (notReturnList.Count > 0)
{
Logs.Write($"货架{ShelfCode}存在模组自检未响应:", LogsType.Instore);
foreach (var item in notReturnList)
{
ExceptionMessages.Add($"模组{item.ModuleCode}未响应自检!");
}
//通信校验
var messages = notReturnList.Select(t => $"模组{t.ModuleCode}({t.CurrentMode})未响应自检!").ToList();
var exceptionMessage = string.Join("\r\n", messages);
var warningModel = new WebSocketMessageModel()
{
IsWarning = false,
WarningType = WarningTypeEnum.,
StoreId = 0,
StoreCode = "",
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress,
};
WarningManager.SendWarning(warningModel);
}
});
}
catch (Exception ex)
{
Logs.Write("自检发现异常:" + ex);
}
finally
{
if (CurrentMode == Mode.)
OrderNumber = string.Empty;
}
}
#endregion
#region
public void WarningLightProcess(byte[] data, int boardId, int lightNumber)
{
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, int lightNumber)
{
//协议处理 判断功能位
switch (data[TcpCleint.PreFixLength + 2])
{
case 0x01://进入入库模式返回信号
GoInInstoreProcess(data, boardId, lightNumber);
break;
case 0x02://退出入库模式返回信号
GoOutInstoreProcess(data, boardId, lightNumber);
break;
case 0x03://正常入库信号
InStoreReturnProcess(data);
break;
case 0x04://入库模式中异常信号
InStoreExceptionReturnProcess(data, boardId, lightNumber);
break;
case 0x05://进入出库模式返回信号
GoInOutstoreProcess(data, boardId, lightNumber);
break;
case 0x06://退出出库模式返回信号
GoOutOutstoreProcess(data, boardId, lightNumber);
break;
case 0x07://正常出库返回信号
OutstoreReturnProcess(data, boardId, lightNumber);
break;
case 0x08://出库模式中异常信号
OutstoreExceptionReturnProcess(data, boardId, lightNumber);
break;
case 0x09://进入盘点模式返回信号
GoInStockTakingReturnProcess(data, boardId, lightNumber);
break;
case 0x0A://退出盘点模式返回信号
GoOutStockTakingReturnProcess(data, boardId, lightNumber);
break;
case 0x13://复位的返回信号
ResetReturnProcess(data, boardId, lightNumber);
break;
case 0x17://电压值1
QueryVoltageProcess(data, boardId, lightNumber);
break;
case 0x18://电压值2
QueryVoltageProcess(data, boardId, lightNumber);
break;
case 0x19://电压值3
QueryVoltageProcess(data, boardId, lightNumber);
break;
case 0x0B://自检结果反馈
SelfCheckProcess(data, boardId, lightNumber);
break;
default:
;
break;
}
}
/// <summary>
/// 进入入库模式返回信号处理
/// </summary>
/// <param name="data"></param>
public void GoInInstoreProcess(byte[] data, int boardId, int lightNumber)
{
//库存物料与实际情况匹配
if (data[TcpCleint.PreFixLength + 3] == 0x01)
{
var module = this.Modules.Where(t => t.BoardId == boardId)
.FirstOrDefault();
if (module == null)
{
return;
}
else
{
module.CurrentMode = Mode.;
}
}
//库存物料与实际情况不匹配
else if (data[TcpCleint.PreFixLength + 3] == 0x00)
{
var module = this.Modules.Where(t => t.BoardId == boardId).FirstOrDefault();
if (module == null)
{
return;
}
else
{
module.CurrentMode = Mode.;
}
//获取当前板所有库位
var storeInfos = DbHelp.db.Queryable<StoreInfo>()
.Where(t => t.ShelfId == ShelfId)
.Where(t => t.BoardId == boardId)
.ToList();
//当前板子的灯数量
var boardStoreNumber = storeInfos.Count();
List<char> dataTemp = new List<char>();
int index11 = 0;
while (boardStoreNumber > 0)
{
if (boardStoreNumber >= 4)
{
dataTemp.AddRange(Convert.ToString(data[TcpCleint.PreFixLength + 4 + index11], 2).PadLeft(8, '0').Reverse().ToList());
boardStoreNumber = boardStoreNumber - 4;
}
else
{
dataTemp.AddRange(Convert.ToString(data[TcpCleint.PreFixLength + 4 + index11], 2).PadLeft(2 * boardStoreNumber, '0').Reverse().ToList());
boardStoreNumber = 0;
}
index11++;
}
//当前板子的灯数量
boardStoreNumber = storeInfos.Count();
for (int index = 0; index <= boardStoreNumber - 1; index++)
{
//当前库位异常
if (dataTemp[2 * index + 1] == '1')
{
if (dataTemp[2 * index] == '1')
{
var storeInfo = storeInfos.Where(t => t.LightNumber == index + 1).First();
if (storeInfo != null)
{
#region
ExceptionMessages.Add($"{storeInfo.StoreCode}物料{storeInfo.CurrentMatSn}丢失,库存数据已删除,请重新扫码后入库");
#endregion
#region WebSocket通知前台
var exceptionMessage = storeInfo.StoreCode + $"进入入库自检发现物料{storeInfo.CurrentMatSn}丢失,请确认是否删除?";
var warningModel = new WebSocketMessageModel()
{
WarningType = WarningTypeEnum.,
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
ModuleId = module.ModuleId,
ModuleCode = module.ModuleCode,
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress
};
WarningManager.SendWarning(warningModel);
this.IsWarning = true;
#endregion
Logs.Write($"货架【{ShelfCode},模组{module}发现物料丢失,开始发送红灯】", LogsType.Instore);
WarningLight.WaringLightAlwaysRed(TcpCleint);
Logs.Write($"货架【{ShelfCode},模组{module}发现物料丢失,发送红灯完成】", LogsType.Instore);
}
//库位未配置、返回数据异常
else
{
Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!");
}
}
else if (dataTemp[2 * index] == '0')
{
var storeInfo = storeInfos.Where(t => t.LightNumber == index + 1).First();
if (storeInfo != null)
{
#region
ExceptionMessages.Add($"库位{storeInfo.StoreCode}:存在物料未扫描上架");
#endregion
#region WebSocket通知前台
var exceptionMessage = $"进入入库自检发现库位{storeInfo.StoreCode}存在物料未扫描上架,请拿下后点击【确认】消除报警";
var warningModel = new WebSocketMessageModel()
{
WarningType = WarningTypeEnum.,
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
ModuleId = module.ModuleId,
ModuleCode = module.ModuleCode,
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress
};
WarningManager.SendWarning(warningModel);
this.IsWarning = true;
#endregion
Logs.Write($"货架【{ShelfCode},模组{module}发现物料未扫描上架,开始发送红灯】", LogsType.Instore);
WarningLight.WaringLightAlwaysRed(TcpCleint);
Logs.Write($"货架【{ShelfCode},模组{module}发现物料未扫描上架,发送红灯完成】", LogsType.Instore);
}
else
{
Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!");
}
}
}
}
}
}
/// <summary>
/// 退出入库模式返回信号处理
/// </summary>
/// <param name="data"></param>
public void GoOutInstoreProcess(byte[] data, int boardId, int lightNumber)
{
var module = this.Modules.Where(t => t.BoardId == boardId && t.CurrentMode == Mode.).FirstOrDefault();
if (module == null)
{
return;
}
else
{
module.CurrentMode = Mode.;
}
}
/// <summary>
/// 正常入库信号
/// </summary>
/// <param name="data"></param>
public void InStoreReturnProcess(byte[] data)
{
var boardId = (data[TcpCleint.PreFixLength + 0] << 8) + data[TcpCleint.PreFixLength + 1];
var number = Convert.ToInt32(data[TcpCleint.PreFixLength + 3]);
var storeInfo = DbHelp.db.Queryable<StoreInfo>().Where(t =>
t.ShelfId == ShelfId
&& t.BoardId == boardId
&& t.LightNumber == number).First();
if (storeInfo == null)
{
return;
}
var module = this.Modules.Where(t => t.BoardId == boardId)
.FirstOrDefault();
if (module == null)
{
return;
}
#region
//物料未扫码
if (this.InStoreData == null)
{
//重复给了多次信号
if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn))
{
module.ComfirmInstore(TcpCleint);
Logs.Write($"CAN给了多次正常入库信号防止硬件异常返回了确认入库");
return;
}
else
{
var exceptionMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!";
var warningModel = new WebSocketMessageModel()
{
WarningType = WarningTypeEnum.,
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
ModuleId = module.ModuleId,
ModuleCode = module.ModuleCode,
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!",
ClientIp = WebSocketIpAddress
};
WarningManager.SendWarning(warningModel);
module.ComfirmErrInstore(TcpCleint);
WarningLight.WaringLightAlwaysRed(TcpCleint);
return;
}
}
//该位置已放置物料
else if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn))
{
module.ComfirmErrInstore(TcpCleint);
WarningLight.WaringLightBlueEnd(TcpCleint);
Logs.Write($"{storeInfo.StoreCode}该位置已放置物料!", LogsType.Instore);
return;
}
#endregion
#region
{
try
{
DbHelp.db.BeginTran();
//库存明细表
var inventoryDetail = new InventoryDetail
{
StoreCode = storeInfo.StoreCode,
StoreId = storeInfo.Id,
R = storeInfo.R,
C = storeInfo.C,
Wei = storeInfo.Wei,
BigShelfCode = storeInfo.BigShelfCode,
GroupName = storeInfo.GroupName,
MatSN = this.InStoreData.materialBar,
MatCode = this.InStoreData.materialCode,
MatName = this.InStoreData.materialName,
MatSpec = this.InStoreData.materialSpec,
MatBatch = this.InStoreData.batchNo,
MatQty = (int)this.InStoreData.materialQty,
MatCustomer = this.InStoreData.customer,
MatSupplier = this.InStoreData.supplier,
InstoreTime = DateTime.Now,
InstoreUser = this.InStoreData.InstoreUser,
};
//出入库记录表
var inOutRecord = new InOutRecord()
{
StoreCode = storeInfo.StoreCode,
StoreId = storeInfo.Id,
StoreInfo = storeInfo,
R = storeInfo.R,
C = storeInfo.C,
Wei = storeInfo.Wei,
BigShelfCode = storeInfo.BigShelfCode,
GroupName = storeInfo.GroupName,
MatSN = this.InStoreData.materialBar,
MatCode = this.InStoreData.materialCode,
MatName = this.InStoreData.materialName,
MatSpec = this.InStoreData.materialSpec,
MatBatch = this.InStoreData.batchNo,
MatQty = (int)this.InStoreData.materialQty,
MatCustomer = this.InStoreData.customer,
MatSupplier = this.InStoreData.supplier,
OperateUser = this.InStoreData.InstoreUser,
Direction = DirectionEnum.,
};
//库位表
storeInfo.CurrentMatSn = this.InStoreData.materialBar;
//保存and更新数据
DbHelp.db.Insertable(inventoryDetail).ExecuteCommand();
DbHelp.db.Insertable(inOutRecord).ExecuteCommand();
DbHelp.db.Updateable(storeInfo).ExecuteCommand();
DbHelp.db.CommitTran();
//清空扫码信息
this.InStoreData = null;
//实际入库位置亮灯1S报警灯同时进行亮绿灯并鸣叫一次提示。
Task.Run(() =>
{
//确认入库硬件入库位置亮灯1秒
module.ComfirmInstore(TcpCleint);
//报警灯亮绿灯 鸣叫一次提示
WarningLight.SuccessLightBlueEnd(TcpCleint);
});
}
catch (Exception ex)
{
DbHelp.db.RollbackTran();
Logs.Write($"入库保存数据异常,异常信息为{ex.Message}");
//报警灯报警
WarningLight.WaringLightBlueEnd(TcpCleint);
}
}
#endregion
}
/// <summary>
/// 入库模式中异常处理
/// </summary>
/// <param name="data"></param>
/// <param name="boardId"></param>
/// <param name="lightNumber"></param>
public void InStoreExceptionReturnProcess(byte[] data, int boardId, int lightNumber)
{
lightNumber = (int)data[TcpCleint.PreFixLength + 4];
var storeInfo = DbHelp.db.Queryable<StoreInfo>()
.Where(t => t.ShelfId == ShelfId)
.Where(t => t.BoardId == boardId && t.LightNumber == lightNumber)
.First();
//库位未找到
if (storeInfo == null)
{
Logs.Write($"【InStoreExceptionReturnProcess】boardId:{boardId},lightNumber{lightNumber},库位未找到 ", LogsType.Instore);
return;
}
//已放物料丢失了 物料多放了 储位恢复正常
switch (data[TcpCleint.PreFixLength + 3])
{
case 0x00:
{
var warnings = WarningManager.Warnings.Where(t => t.IsWarning = true)
.Where(t => t.ShelfId == ShelfId && t.StoreId == storeInfo.Id)
.ToList();
var exceptionMessage = storeInfo.StoreCode + "恢复正常!";
var warningModel = new WebSocketMessageModel()
{
IsWarning = false,
WarningType = WarningTypeEnum.,
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress,
SolvedGuids = warnings.Select(t => t.Guid).ToList(),
};
WarningManager.SendWarning(warningModel);
//自动消除本地缓存的报警
warnings.ForEach(warning =>
{
WarningManager.ClearWarning(warning, SolveTypeEnum.);
});
ProcessingExceptions.RemoveAll(t => t.BoardId == boardId);
}
break;
case 0x01:
{
var exceptionMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!";
var warningModel = new WebSocketMessageModel()
{
WarningType = WarningTypeEnum.,
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
//ModuleId = module.ModuleId,
//ModuleCode = module.ModuleCode,
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress
};
WarningManager.SendWarning(warningModel);
WarningLight.WaringLightAlwaysRed(TcpCleint);
ProcessingExceptions.Add(new ProcessingExceptionType()
{
BoardId = boardId,
LightNumber = lightNumber,
ExceptionMessage = storeInfo.StoreCode + "入库过程中存在物料未扫描上架!"
});
}
break;
case 0x02:
{
var exceptionMessage = storeInfo.StoreCode + "物料被取出!";
var warningModel = new WebSocketMessageModel()
{
WarningType = WarningTypeEnum.,
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
//ModuleId = module.ModuleId,
//ModuleCode = module.ModuleCode,
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress
};
WarningManager.SendWarning(warningModel);
WarningLight.WaringLightAlwaysRed(TcpCleint);
ProcessingExceptions.Add(new ProcessingExceptionType()
{
BoardId = boardId,
LightNumber = lightNumber,
ExceptionMessage = storeInfo.StoreCode + "入库过程中物料丢失!"
});
}
break;
default:
break;
}
}
/// <summary>
/// 进入出库模式协议返回
/// </summary>
/// <param name="data"></param>
/// <param name="boardId"></param>
/// <param name="lightNumber"></param>
public void GoInOutstoreProcess(byte[] data, int boardId, int lightNumber)
{
//库存物料与实际情况匹配
if (data[TcpCleint.PreFixLength + 3] == 0x01)
{
var module = this.Modules.Where(t => t.BoardId == boardId)
.FirstOrDefault();
if (module == null)
{
//TO DO 报错
return;
}
else
{
module.CurrentMode = Mode.;
}
}
//库存物料与实际情况不匹配
else if (data[TcpCleint.PreFixLength + 3] == 0x00)
{
var module = this.Modules.Where(t => t.BoardId == boardId).FirstOrDefault();
if (module == null)
{
//TO DO 报错
return;
}
else
{
module.CurrentMode = Mode.;
}
//获取当前板所有库位
var storeInfos = DbHelp.db.Queryable<StoreInfo>()
.Where(t => t.ShelfId == ShelfId)
.Where(t => t.BoardId == boardId)
.ToList();
//当前板子的灯数量
var boardStoreNumber = storeInfos.Count();
List<char> dataTemp = new List<char>();
int index11 = 0;
while (boardStoreNumber > 0)
{
if (boardStoreNumber >= 4)
{
dataTemp.AddRange(Convert.ToString(data[TcpCleint.PreFixLength + 4 + index11], 2).PadLeft(8, '0').Reverse().ToList());
boardStoreNumber = boardStoreNumber - 4;
}
else
{
dataTemp.AddRange(Convert.ToString(data[TcpCleint.PreFixLength + 4 + index11], 2).PadLeft(2 * boardStoreNumber, '0').Reverse().ToList());
boardStoreNumber = 0;
}
index11++;
}
//当前板子的灯数量
boardStoreNumber = storeInfos.Count();
for (int index = 0; index <= boardStoreNumber - 1; index++)
{
//当前库位异常
if (dataTemp[2 * index + 1] == '1')
{
if (dataTemp[2 * index] == '1')
{
var storeInfo = storeInfos.Where(t => t.LightNumber == index + 1).First();
if (storeInfo != null)
{
#region
ExceptionMessages.Add($"{storeInfo.StoreCode}物料{storeInfo.CurrentMatSn}丢失,库存数据已删除,请重新扫码后入库");
#endregion
#region WebSocket通知前台
var exceptionMessage = storeInfo.StoreCode + $"进入出库自检发现物料{storeInfo.CurrentMatSn}丢失,请确认是否删除?";
var warningModel = new WebSocketMessageModel()
{
WarningType = WarningTypeEnum.,
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
ModuleId = module.ModuleId,
ModuleCode = module.ModuleCode,
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress
};
WarningManager.SendWarning(warningModel);
#endregion
WarningLight.WaringLightAlwaysRed(TcpCleint);
}
//库位未配置、返回数据异常
else
{
//Logs.Write($"[进入入库模式异常]板Id{boardIds},库位号{index + 1}找不到对应库位!");
}
}
else if (dataTemp[2 * index] == '0')
{
var storeInfo = storeInfos.Where(t => t.LightNumber == index + 1).First();
if (storeInfo != null)
{
#region
ExceptionMessages.Add($"库位{storeInfo.StoreCode}:存在物料未扫描上架");
#endregion
#region WebSocket通知前台
var exceptionMessage = $"进入出库自检发现库位{storeInfo.StoreCode}存在物料未扫描上架,请拿下后点击【确认】消除报警";
var warningModel = new WebSocketMessageModel()
{
WarningType = WarningTypeEnum.,
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
ModuleId = module.ModuleId,
ModuleCode = module.ModuleCode,
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress
};
WarningManager.SendWarning(warningModel);
#endregion
WarningLight.WaringLightAlwaysRed(TcpCleint);
}
else
{
Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!");
}
}
}
}
}
}
public void OutstoreReturnProcess(byte[] data, int boardId, int lightNumber)
{
if (CurrentMode != Mode.)
{
Logs.Write($"出库错误:{ShelfCode}该货架模式不是出库模式或盘点模式!", LogsType.Outstore);
return;
}
lightNumber = Convert.ToInt32(data[TcpCleint.PreFixLength + 3]);
var storeInfo = DbHelp.db.Queryable<StoreInfo>().Where(t => t.BoardId == boardId
&& t.ShelfId == ShelfId
&& t.LightNumber == lightNumber)
.First();
if (storeInfo == null)
{
return;
}
var module = this.Modules.Where(t => t.BoardId == boardId)
.FirstOrDefault();
if (module == null)
{
return;
}
//当前库位未记录MatSn
if (string.IsNullOrEmpty(storeInfo.CurrentMatSn))
{
if (data[TcpCleint.PreFixLength + 6] == 0x0D &&
data[TcpCleint.PreFixLength + 7] == 0x0D &&
data[TcpCleint.PreFixLength + 8] == 0x0D &&
data[TcpCleint.PreFixLength + 9] == 0x0D)
{
Task.Run(() =>
{
var historyVoltage = new StoreInfoHistoryVoltage()
{
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
ShelfTypeId = storeInfo.ShelfTypeId,
ModuleId = storeInfo.ModuleId,
ModuleCode = storeInfo.ModuleCode,
ShelfId = storeInfo.ShelfId,
ShelfCode = storeInfo.ShelfCode,
BoardId = storeInfo.BoardId,
LightNumber = storeInfo.LightNumber,
Priority = storeInfo.Priority,
CurrentMatSn = storeInfo.CurrentMatSn,
CurrentVoltage = storeInfo.CurrentVoltage,
StandardVoltage = storeInfo.StandardVoltage,
OffsetVoltage = storeInfo.OffsetVoltage,
BigShelfCode = storeInfo.BigShelfCode,
R = storeInfo.R,
C = storeInfo.C,
Wei = storeInfo.Wei,
GroupName = "出库自动标定记录历史电压",
CreateTime = DateTime.Now,
};
//自动保存最新的电压值
storeInfo.CurrentVoltage = (data[TcpCleint.PreFixLength + 4] << 8) + data[TcpCleint.PreFixLength + 5];
DbHelp.db.Insertable(historyVoltage).ExecuteCommand();
DbHelp.db.Updateable(storeInfo).ExecuteCommand();
});
Thread.Sleep(10);
return;
}
else
{
//该库位是需要出库的库位物料被多次取出or给了多个正常出库信号
Logs.Write($"该库位是需要出库的库位物料被反复取出or给了多个正常出库信号,库位{storeInfo.StoreCode}", LogsType.Outstore);
//暂不进行处理
return;
}
}
//不是本次出库需要出的物料
if (!CurrentOutStoreMatSNs.Contains(storeInfo.CurrentMatSn))
{
Logs.Write($"{storeInfo.CurrentMatSn}不是本次需要出库的物料", LogsType.Outstore);
//报警灯报警
WarningLight.WaringLightAlwaysRed(TcpCleint);
return;
}
//获取当前的库存信息
var inventoryDetail = DbHelp.db.Queryable<InventoryDetail>().Where(t => t.MatSN == storeInfo.CurrentMatSn).First();
if (inventoryDetail == null)
{
Logs.Write($"{storeInfo.CurrentMatSn}库存信息不存在", LogsType.Outstore);
//报警灯报警
WarningLight.WaringLightAlwaysRed(TcpCleint);
return;
}
//获取对应的出库单物料明细
var orderMatDetails = DbHelp.db.Queryable<OutOrderMatDetail>()
.Where(t => t.OrderId == CurrentOutOrder.Id)
.Where(t => t.MatSN == inventoryDetail.MatSN)
.Where(t => t.IsSended == false)
.First();
if (orderMatDetails == null)
{
Logs.Write($"{storeInfo.CurrentMatSn},OrderDetail出库明细信息不存在", LogsType.Outstore);
//报警灯报警
WarningLight.WaringLightAlwaysRed(TcpCleint);
return;
}
//当前库位的SN
var matSN = storeInfo.CurrentMatSn;
try
{
#region
DbHelp.db.BeginTran();
//库存明细表 删除
;
//出入库记录表 新增
var inOutRecord = new InOutRecord()
{
StoreCode = storeInfo.StoreCode,
StoreId = storeInfo.Id,
StoreInfo = storeInfo,
R = storeInfo.R,
C = storeInfo.C,
Wei = storeInfo.Wei,
BigShelfCode = storeInfo.BigShelfCode,
GroupName = storeInfo.GroupName,
MatSN = inventoryDetail.MatSN,
MatCode = inventoryDetail.MatCode,
MatName = inventoryDetail.MatName,
MatBatch = inventoryDetail.MatBatch,
MatQty = inventoryDetail.MatQty,
MatSpec = inventoryDetail.MatSpec,
MatCustomer = inventoryDetail.MatCustomer,
MatSupplier = inventoryDetail.MatSupplier,
OrderNumber = orderMatDetails.OrderNumber,
OperateUser = OutOperateUser,
Direction = orderMatDetails.IsMXPD == false ? DirectionEnum. : DirectionEnum.,
};
//库位表 修改
storeInfo.CurrentMatSn = string.Empty;
//发料单物料明细表 更新为已出库
orderMatDetails.IsSended = true;
//发料需求表增加数量
if (CurrentOutOrder.SyncType == SyncTypeEnum.ByMatCode)
{
//同步更新发料需求表已发数量
var outOrderDetail = DbHelp.db.Queryable<OutOrderDetail>()
.Where(t => t.Id == orderMatDetails.OutOrderDetailId)
.First();
if (outOrderDetail != null)
{
outOrderDetail.OutQty += orderMatDetails.MatQty;
DbHelp.db.Updateable(outOrderDetail).ExecuteCommand();
}
}
//保存数据
DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand();
DbHelp.db.Insertable(inOutRecord).ExecuteCommand();
DbHelp.db.Updateable(storeInfo).ExecuteCommand();
DbHelp.db.Updateable(orderMatDetails).ExecuteCommand();
DbHelp.db.CommitTran();
//报警灯同时亮绿灯并鸣叫一次提示。
WarningLight.SuccessLightGreenEnd(TcpCleint);
//确认本次出库
module.ComfirmOutstore(TcpCleint, data[TcpCleint.PreFixLength + 3]);
//更新时间 避免超时被自动退出
Task.Run(() =>
{
var shelves = ShelfManager.Shelves.Where(t => t.CurrentMode == Mode. && t.OrderNumber == OrderNumber).ToList();
foreach (var shelf in shelves)
{
shelf.SetCurrentModeTime = DateTime.Now;
}
});
//当前柜子是否还存在未出库的
Logs.Write($"货架【{ShelfCode}】,用户取出物料{matSN}", LogsType.Outstore);
CurrentOutStoreMatSNs.RemoveAll(t => t == matSN);//删除本次已出的物料SN
Logs.Write($"货架【{ShelfCode}】,当前货架剩余物料{string.Join(",", CurrentOutStoreMatSNs)}", LogsType.Outstore);
#endregion
#region
var tempOrder = CurrentOutOrder;
var isMXPD = orderMatDetails.IsMXPD == true;
//通知前台刷新
Task.Run(() =>
{
//更新订单状态
UpdateOutOrderStatus(tempOrder);
var messageMode = new WebSocketMessageModel()
{
IsWarning = false,
ClientIp = WebSocketIpAddress,
WarningType = isMXPD ? WarningTypeEnum. : WarningTypeEnum.
};
WarningManager.SendWarning(messageMode);
});
#endregion
#region 退
var isExsistOut = CurrentOutStoreMatSNs.Any();
//本次亮灯的物料已全部取出
if (!isExsistOut)
{
Logs.Write($"货架【{ShelfCode}】,本次亮灯的物料已全部取出", LogsType.Outstore);
CurrentOutOrder = null;
//退出出库模式
var taskGoOut = Task.Run(() =>
{
GoOutOutstore();
});
//看是否是分批次出库的情况 分批次亮灯
Task.Run(async () =>
{
await Task.WhenAll(taskGoOut);
if (LocalFile.Config.IsSameMatCodeOut)
{
#region
//查一下是否是当前发料单最后一个货架(在出库模式 同一个发料单下)
var isLastShelf = ShelfManager.Shelves
.Where(t => t.OrderNumber == OrderNumber)
.Where(t => t.CurrentMode == Mode.)
.Any();
if (!isLastShelf)
{
Logs.Write($"发料单{OrderNumber},最后一个出库货架,触发精准发料机制!查询是否还存在待出库物料", LogsType.Outstore);
var outOrder = DbHelp.db.Queryable<OutOrder>()
.Where(t => t.OrderNumber == OrderNumber)
.WhereIF(!string.IsNullOrEmpty(LocalFile.Config.GroupName), t => t.GroupName == LocalFile.Config.GroupName)
.First();
if (outOrder != null)
{
var outOrderMatDetails = DbHelp.db.Queryable<OutOrderMatDetail>()
.Where(t => t.OrderId == outOrder.Id)
.Where(t => t.IsSended == false)
.Includes(t => t.StoreInfo)
.ToList();
if (outOrderMatDetails != null && outOrderMatDetails.Count > 0)
{
//相邻物料亮不同颜色 这里绿色和蓝色互相切换
LocalStatic.CurrentOutStoreColor = LocalStatic.CurrentOutStoreColor == (byte)0x02 ? (byte)0x04 : (byte)0x02;
//存在待出库 然后之前又没亮灯的情况 => 继续分批次亮灯
Logs.Write($"发料单{OrderNumber},还有物料未出!", LogsType.Outstore);
var outOrderDetailCount = outOrderMatDetails.GroupBy(t => t.MatCode)
.Select(o => new { count = o.Count(), bb = o })
.Where(o => o.count >= 2)
.OrderByDescending(o => o.count)
.ToList();
//相同物料存在盘数超过2的情况亮下一个盘数多的物料
if (outOrderDetailCount.Count > 0)
{
var matCode = outOrderDetailCount.First().bb.Key;
outOrderMatDetails = outOrderMatDetails.Where(t => t.MatCode == matCode)
.ToList();
Logs.Write($"发料单{OrderNumber},本次亮灯物料{matCode}", LogsType.Outstore);
}
//相同物料不存在盘数超过n的情况剩余物料全部亮灯
else
{
//剩余物料全出
Logs.Write($"发料单{OrderNumber},剩余所有物料灯全亮(发送命令)!", LogsType.Outstore);
}
var shelfIds = outOrderMatDetails.Select(t => t.StoreInfo.ShelfId)
.Distinct()
.ToList();
var shelfs = ShelfManager.Shelves.Where(t => shelfIds.Contains(t.ShelfId)).ToList();
var otherModeShelfs = shelfs.Where(t => t.CurrentMode != HardWare.Mode.).ToList();
if (otherModeShelfs != null && otherModeShelfs.Count > 0)
{
otherModeShelfs.ForEach(t =>
{
t.Reset();
});
Thread.Sleep(1000);
}
//对应的货架对应位置 进入出库模式 亮灯
shelfs.ForEach(shelf =>
{
var matDetails = outOrderMatDetails.Where(t => t.StoreInfo.ShelfCode == shelf.ShelfCode)
.Distinct()
.ToList();
shelf.GoInOutstore(matDetails, outOrder, OutOperateUser);
shelf.OrderNumber = outOrder.OrderNumber;
});
}
else
{
Logs.Write($"发料单{OrderNumber},当前物料已发完!", LogsType.Outstore);
//清空发料单缓存
var outingShelfs = ShelfManager.Shelves.Where(t => t.OrderNumber == OrderNumber).ToList();
outingShelfs.ForEach(t =>
{
t.OrderNumber = string.Empty;
});
Task.Run(() =>
{
//判断是否是当前订单最后一个出库货架
var isOuting = ShelfManager.Shelves.Where(t => t.CurrentMode == Mode. && t.OrderNumber == OrderNumber)
.Any();
//WebSocket通知前台以更新左侧出库单列表的状态
if (!isOuting)
{
#region WebSocket
var messageMode = new WebSocketMessageModel()
{
IsWarning = false,
ClientIp = WebSocketIpAddress,
WarningType = WarningTypeEnum.,
};
WarningManager.SendWarning(messageMode);
#endregion
}
});
}
}
else
{
Logs.Write($"发料单{OrderNumber}OutOrder为null肯定是有问题", LogsType.Outstore);
}
}
else
{
Logs.Write($"发料单{OrderNumber},非最后一个出库货架!", LogsType.Outstore);
var otherShelfs = ShelfManager.Shelves
.Where(t => t.OrderNumber == OrderNumber)
.Where(t => t.CurrentMode == Mode.)
.ToList();
otherShelfs.ForEach(shelf =>
{
try
{
if (shelf is SmartShelf)
{
var smartShelf = (SmartShelf)shelf;
Logs.Write($"货架【{smartShelf.ShelfCode}】待取物料{string.Join(",", smartShelf.CurrentOutStoreMatSNs)}", LogsType.Outstore);
}
}
catch
{ }
});
}
#endregion
}
else
{
//清空发料单缓存
var outingShelfs = ShelfManager.Shelves.Where(t => t.OrderNumber == OrderNumber).ToList();
outingShelfs.ForEach(t =>
{
t.OrderNumber = string.Empty;
});
Task.Run(() =>
{
//判断是否是当前订单最后一个出库货架
var isOuting = ShelfManager.Shelves.Where(t => t.CurrentMode == Mode. && t.OrderNumber == OrderNumber)
.Any();
//WebSocket通知前台以更新左侧出库单列表的状态
if (!isOuting)
{
#region WebSocket
var messageMode = new WebSocketMessageModel()
{
IsWarning = false,
ClientIp = WebSocketIpAddress,
WarningType = WarningTypeEnum.,
};
WarningManager.SendWarning(messageMode);
#endregion
}
});
}
});
}
#endregion
}
catch (Exception ex)
{
DbHelp.db.RollbackTran();
//报警灯报警
WarningLight.WaringLightAlwaysRed(TcpCleint);
}
}
public void UpdateOutOrderStatus(OutOrder order)
{
//再去获取一遍Order
order = DbHelp.db.Queryable<OutOrder>()
.Where(t => t.Id == order.Id)
.First();
if (order != null)
{
#region
var orderMatDetails = DbHelp.db.Queryable<OutOrderMatDetail>()
.Where(t => t.OrderId == order.Id)
.ToList();
var isExistNoSendMat = orderMatDetails.Where(t => t.IsSended == false)
.Any();
if (isExistNoSendMat)
{
order.OrderStatus = OutOrderStatus.;
}
else
{
order.OrderStatus = OutOrderStatus.;
order.OutOrderExeStatus = OutOrderExeStatus.;
}
#endregion
#region
if (order.OrderStatus == OutOrderStatus. &&
order.SyncType == SyncTypeEnum.ByMatCode)
{
var orderDetails = DbHelp.db.Queryable<OutOrderDetail>()
.Where(t => t.OrderId == order.Id)
.ToList();
var isExistNoSend = orderDetails.Where(t => t.ReqQty > t.OutQty).Any();
if (isExistNoSend)
{
order.OrderStatus = OutOrderStatus.;
}
else
{
order.OrderStatus = OutOrderStatus.;
}
}
#endregion
DbHelp.db.Updateable(order).ExecuteCommand();
}
}
/// <summary>
/// 退出出库模式返回信号处理
/// </summary>
/// <param name="data"></param>
public void GoOutOutstoreProcess(byte[] data, int boardId, int lightNumber)
{
var module = this.Modules.Where(t => t.BoardId == boardId && t.CurrentMode == Mode.).FirstOrDefault();
if (module == null)
{
return;
}
else
{
module.CurrentMode = Mode.;
}
}
/// <summary>
/// 出库模式中异常处理
/// </summary>
/// <param name="data"></param>
/// <param name="boardId"></param>
/// <param name="lightNumber"></param>
public void OutstoreExceptionReturnProcess(byte[] data, int boardId, int lightNumber)
{
lightNumber = (int)data[TcpCleint.PreFixLength + 4];
var storeInfo = DbHelp.db.Queryable<StoreInfo>()
.Where(t => t.ShelfId == ShelfId)
.Where(t => t.BoardId == boardId && t.LightNumber == lightNumber)
.First();
if (storeInfo == null)
{
Logs.Write($"[OutstoreExceptionReturnProcess]boardId{boardId};lightNumber{lightNumber}库位未找到!", LogsType.Outstore);
return;
}
//已放物料丢失了 物料多放了 储位恢复正常
switch (data[TcpCleint.PreFixLength + 3])
{
case 0x00:
{
//对应的异常
var warnings = WarningManager.Warnings.Where(t => t.IsWarning = true)
.Where(t => t.ShelfId == ShelfId && t.StoreId == storeInfo.Id)
.ToList();
var exceptionMessage = storeInfo.StoreCode + "恢复正常!";
var warningModel = new WebSocketMessageModel()
{
IsWarning = false,
WarningType = WarningTypeEnum.,
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress,
SolvedGuids = warnings.Select(t => t.Guid).ToList(),
};
WarningManager.SendWarning(warningModel);
//自动消除本地缓存的报警
warnings.ForEach(warning =>
{
Logs.Write($"ClearWarning,{warning.Guid}", LogsType.Outstore);
WarningManager.ClearWarning(warning, SolveTypeEnum.);
});
ProcessingExceptions.RemoveAll(t => t.BoardId == boardId);
}
break;
case 0x01:
{
var exceptionMessage = storeInfo.StoreCode + "出库过程中存在物料上架!";
var warningModel = new WebSocketMessageModel()
{
WarningType = WarningTypeEnum.,
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress,
};
WarningManager.SendWarning(warningModel);
WarningLight.WaringLightAlwaysRed(TcpCleint);
ProcessingExceptions.Add(new ProcessingExceptionType()
{
BoardId = boardId,
LightNumber = lightNumber,
ExceptionMessage = storeInfo.StoreCode + "出库过程中存在物料上架!"
});
}
break;
case 0x02:
{
var exceptionMessage = storeInfo.StoreCode + "物料被取出!";
var warningModel = new WebSocketMessageModel()
{
WarningType = WarningTypeEnum.,
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
//ModuleId = module.ModuleId,
//ModuleCode = module.ModuleCode,
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress
};
WarningManager.SendWarning(warningModel);
WarningLight.WaringLightAlwaysRed(TcpCleint);
ProcessingExceptions.Add(new ProcessingExceptionType()
{
BoardId = boardId,
LightNumber = lightNumber,
ExceptionMessage = storeInfo.StoreCode + "出库过程中物料被异常取出!"
});
}
break;
default:
break;
}
}
/// <summary>
/// 进入盘点模式返回信号
/// </summary>
/// <param name="data"></param>
/// <param name="boardId"></param>
/// <param name="lightNumber"></param>
public void GoInStockTakingReturnProcess(byte[] data, int boardId, int lightNumber)
{
var module = this.Modules.Where(t => t.BoardId == boardId).FirstOrDefault();
if (module == null)
{
return;
}
else
{
module.CurrentMode = Mode.;
}
}
public void GoOutStockTakingReturnProcess(byte[] data, int boardId, int lightNumber)
{
var module = this.Modules.Where(t => t.BoardId == boardId && t.CurrentMode == Mode.).FirstOrDefault();
if (module == null)
{
return;
}
else
{
module.CurrentMode = Mode.;
}
}
public void ResetReturnProcess(byte[] data, int boardId, int lightNumber)
{
var module = this.Modules
.Where(t => t.BoardId == boardId)
.FirstOrDefault();
if (module == null)
{
return;
}
else
{
module.CurrentMode = Mode.;
}
}
public void QueryVoltageProcess(byte[] data, int boardId, int lightNumber)
{
//第n帧
var n = (int)data[TcpCleint.PreFixLength + 3];
var voltage1 = (data[TcpCleint.PreFixLength + 4] << 8) + data[TcpCleint.PreFixLength + 5];
var voltage2 = (data[TcpCleint.PreFixLength + 6] << 8) + data[TcpCleint.PreFixLength + 7];
var voltage3 = (data[TcpCleint.PreFixLength + 8] << 8) + data[TcpCleint.PreFixLength + 9];
var number1 = (n - 1) * 3 + 1;
var number2 = (n - 1) * 3 + 2;
var number3 = (n - 1) * 3 + 3;
if (number1 <= 16)
{
var storeInfo1 = DbHelp.db.Queryable<StoreInfo>()
.Where(t => t.BoardId == boardId && t.LightNumber == number1 && t.ShelfId == ShelfId)
.First();
if (storeInfo1 != null)
{
if (data[TcpCleint.PreFixLength + 2] == 0x17)
storeInfo1.CurrentVoltage = voltage1;
else if (data[TcpCleint.PreFixLength + 2] == 0x18)
storeInfo1.OffsetVoltage = voltage1;
else
storeInfo1.StandardVoltage = voltage1;
DbHelp.db.Updateable(storeInfo1).ExecuteCommand();
}
}
if (number2 <= 16)
{
var storeInfo2 = DbHelp.db.Queryable<StoreInfo>()
.Where(t => t.BoardId == boardId && t.LightNumber == number2 && t.ShelfId == ShelfId)
.First();
if (storeInfo2 != null)
{
if (data[TcpCleint.PreFixLength + 2] == 0x17)
storeInfo2.CurrentVoltage = voltage2;
else if (data[TcpCleint.PreFixLength + 2] == 0x18)
storeInfo2.OffsetVoltage = voltage2;
else
storeInfo2.StandardVoltage = voltage2;
DbHelp.db.Updateable(storeInfo2).ExecuteCommand();
}
}
if (number1 <= 16)
{
var storeInfo3 = DbHelp.db.Queryable<StoreInfo>()
.Where(t => t.BoardId == boardId && t.LightNumber == number3 && t.ShelfId == ShelfId)
.First();
if (storeInfo3 != null)
{
if (data[TcpCleint.PreFixLength + 2] == 0x17)
storeInfo3.CurrentVoltage = voltage3;
else if (data[TcpCleint.PreFixLength + 2] == 0x18)
storeInfo3.OffsetVoltage = voltage3;
else
storeInfo3.StandardVoltage = voltage3;
DbHelp.db.Updateable(storeInfo3).ExecuteCommand();
}
}
}
public void SelfCheckProcess(byte[] data, int boardId, int lightNumber)
{
var module = this.Modules.Where(t => t.BoardId == boardId).FirstOrDefault();
if (module == null)
{
return;
}
else
{
module.IsSelfCheck = false;
}
if (data[TcpCleint.PreFixLength + 3] == 0x01)
{
//比对结果相同
}
//比对结果不同
else if (data[TcpCleint.PreFixLength + 3] == 0x00)
{
//获取当前板所有库位
var storeInfos = DbHelp.db.Queryable<StoreInfo>()
.Where(t => t.BoardId == boardId && t.ShelfId == ShelfId)
.ToList();
//当前设置的板库位数
var boardStoreNumber = storeInfos.Count();
List<char> dataTemp = new List<char>();
int index11 = 0;
while (boardStoreNumber > 0)
{
if (boardStoreNumber >= 4)
{
dataTemp.AddRange(Convert.ToString(data[TcpCleint.PreFixLength + 4 + index11], 2).PadLeft(8, '0').Reverse().ToList());
boardStoreNumber = boardStoreNumber - 4;
}
else
{
dataTemp.AddRange(Convert.ToString(data[TcpCleint.PreFixLength + 4 + index11], 2).PadLeft(2 * boardStoreNumber, '0').Reverse().ToList());
boardStoreNumber = 0;
}
index11++;
}
boardStoreNumber = storeInfos.Count();
for (int index = 0; index <= boardStoreNumber - 1; index++)
{
//当前库位异常
if (dataTemp[2 * index + 1] == '1')
{
if (dataTemp[2 * index] == '1')
{
var storeInfo = storeInfos.Where(t => t.LightNumber == index + 1).First();
if (storeInfo != null)
{
#region WebSocket通知前台
var exceptionMessage = storeInfo.StoreCode + $"自检发现物料{storeInfo.CurrentMatSn}丢失,请确认是否删除?";
var warningModel = new WebSocketMessageModel()
{
WarningType = WarningTypeEnum.,
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
ModuleId = storeInfo.ModuleId,
ModuleCode = storeInfo.ModuleCode,
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress
};
WarningManager.SendWarning(warningModel);
#endregion
IsWarning = true;
Logs.Write($"货架自检【{ShelfCode},库位{storeInfo.StoreCode}发现物料丢失,开始发送红灯】", LogsType.Instore);
WarningLight.WaringLightAlwaysRed(TcpCleint);
Logs.Write($"货架自检【{ShelfCode},库位{storeInfo.StoreCode}发现物料丢失,发送红灯完成】", LogsType.Instore);
}
//库位未配置、返回数据异常
else
{
Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!");
}
}
else if (dataTemp[2 * index] == '0')
{
var storeInfo = storeInfos.Where(t => t.LightNumber == index + 1).First();
if (storeInfo != null)
{
#region WebSocket通知前台
var exceptionMessage = $"自检发现库位{storeInfo.StoreCode}存在物料未扫描上架,请拿下后点击【确认】消除报警";
var warningModel = new WebSocketMessageModel()
{
WarningType = WarningTypeEnum.,
StoreId = storeInfo.Id,
StoreCode = storeInfo.StoreCode,
ModuleId = storeInfo.ModuleId,
ModuleCode = storeInfo.ModuleCode,
ShelfCode = ShelfCode,
ShelfId = ShelfId,
WarningMessage = exceptionMessage,
ClientIp = WebSocketIpAddress
};
WarningManager.SendWarning(warningModel);
#endregion
IsWarning = true;
Logs.Write($"货架自检【{ShelfCode},库位{storeInfo.StoreCode}存在物料未扫描上架,开始发送红灯】", LogsType.Instore);
WarningLight.WaringLightAlwaysRed(TcpCleint);
Logs.Write($"货架自检【{ShelfCode},库位{storeInfo.StoreCode}存在物料未扫描上架,发送红灯完成】", LogsType.Instore);
}
else
{
Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!");
}
}
}
}
}
}
#endregion
}
/// <summary>
/// 过程中异常类型
/// </summary>
public class ProcessingExceptionType
{
public int BoardId { get; set; }
public int LightNumber { get; set; }
public string ExceptionMessage { get; set; }
}
}