Files
wcs/WCS.BLL/HardWare/SmartShelf.cs
hehaibing-1996 a1199028b3 提交代码
2024-04-25 09:48:38 +08:00

701 lines
30 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 System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core;
using TouchSocket.Sockets;
using WCS.BLL.DbModels;
using WCS.BLL.Manager;
using WCS.DAL;
using WCS.DAL.Db;
using WCS.DAL.DbModels;
using WCS.Model;
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;
CurentMode = shelfInfo.CurrentMode;
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.CurentMode
});
}
ModulesStr = string.Join(";", Modules.Select(t => t.ModuleCode));
ModuleIds = Modules.Select(t => t.ModuleId).ToList();
});
////初始化TCPCleint
//TcpCleint = new TCPClient("192.168.0.11:20002", "192.168.0.154:20003");
//TcpCleint.tcpClient.Received += (client, e) =>
//{
// var data = e.ByteBlock.Buffer.Take((int)e.ByteBlock.Length).ToArray();
// e.ByteBlock.Clear();
// var len = data.Length;
// for (int index = 0; index < data.Length - TcpCleint.PreFixLength; index++)
// {
// //协议拆包 通过前缀校验是否为完整数据包
// var prefixInData = data.Skip(index).Take(TcpCleint.PreFixLength);
// var isEqual = prefixInData.SequenceEqual(TcpCleint.Prefix);
// if (isEqual)
// {
// var dataTemp = data.Skip(index).Take(TcpCleint.PreFixLength + TcpCleint.DataLength).ToArray();
// if (dataTemp.Length < TcpCleint.PreFixLength + TcpCleint.DataLength)//拆包后不满足一条指令的长度
// {
// continue;
// }
// index += (TcpCleint.PreFixLength + TcpCleint.DataLength - 1);//每次循环index会+1 所以这里-1
// //获取板子ID
// var boardId = (data[TcpCleint.PreFixLength + 0] << 8) + data[TcpCleint.PreFixLength + 1];
// var lightNumber = Convert.ToInt32(data[TcpCleint.PreFixLength + 3]);
// //协议处理 判断功能位
// switch (dataTemp[TcpCleint.PreFixLength + 2])
// {
// case 0x01://进入入库模式信号
// GoInInstoreProcess(dataTemp, boardId, lightNumber);
// break;
// case 0x03://正常入库信号
// InStoreReturnProcess(dataTemp);
// break;
// default:
// ;
// break;
// }
// }
// }
// return EasyTask.CompletedTask;
//};
//TcpCleint.Connect();
}
public int ShelfId { get; set; }
public string ShelfCode { get; set; }
public int RowCounts { get; set; }
public int ColumnCounts { get; set; }
public Mode CurentMode { 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 WarningLight WarningLight { get; set; }
public List<string> ExceptionMessages { get; set; } = new List<string>();
public string? InstoreIpAddress { get; set; } = string.Empty;
public MatInfoResponse InStoreData { get; set; }
public string OrderNumber { get; set; }
public List<int> ModuleIds { get; set; }
public string ClientIp { get; set; }
#region
public void GoInInstore(string? IPAddress)
{
//判断当前模式是否为待机模式
if (this.CurentMode != Mode.)
{
return;
}
else
{
this.CurentMode = Mode.;
}
//清空错误
ExceptionMessages.Clear();
//货架所有模组发送指令进入入库模式
foreach (var module in Modules.Where(t => t.IsEnable).ToList())
{
module.GoInInstoreMode(TcpCleint);
}
//延时获取异常
var timeOut = 3000;
var timeSpan = TimeSpan.FromMilliseconds(0);
var beginTime = DateTime.Now;
while (timeSpan <= TimeSpan.FromMilliseconds(timeOut))
{
timeSpan = DateTime.Now - beginTime;
//接收到第一个异常就不继续循环了
if (ExceptionMessages.Count() > 0)
{
var deficientTime = timeOut - (int)timeSpan.TotalMilliseconds;
if (deficientTime > 0)
Thread.Sleep(deficientTime);
//出现异常的未进入入库模式,有红灯进行指引
this.CurentMode = Mode.;
return;
}
//延时处理
Thread.Sleep(50);
}
//警示灯亮起
WarningLight.BlueLight(TcpCleint);
//绑定当前进入入库PDA/WCS前端的IP
InstoreIpAddress = IPAddress;
//返回成功
return;
}
public void GoOutInstore()
{
//看货架是否为入库模式
if (CurentMode != Mode.)
{
return;
}
else
{
this.CurentMode = Mode.;
}
//货架所有模组发送指令退出入库模式
foreach (var module in Modules.Where(t => t.IsEnable)
//.Where(t => t.CurrentMode == Mode.入库模式)
.ToList())
{
module.GoOutInstoreMode(TcpCleint);
}
//报警灯熄灭
WarningLight.CloseLight(TcpCleint);
}
public void GoInOutstore()
{
throw new NotImplementedException();
}
public void GoInStocktaking()
{
this.CurentMode = Mode.;
}
public void GoOutOutstore()
{
this.CurentMode = Mode.;
}
public void GoOutStocktaking()
{
this.CurentMode = Mode.;
}
void IShelfBase.Reset()
{
throw new NotImplementedException();
}
void IShelfBase.SetCurrentMode()
{
throw new NotImplementedException();
}
void IShelfBase.Warning()
{
throw new NotImplementedException();
}
public void ShelfCheck()
{
foreach (var module in Modules.Where(t => t.IsEnable).ToList())
{
module.ShelfCheck(TcpCleint);
}
}
#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 0x05://进入出库模式返回信号
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)
{
//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.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
Task.Run(() =>
{
try
{
DbHelp.db.BeginTran();
//库位表字段清空
storeInfo.CurrentMatSn = string.Empty;
DbHelp.db.Updateable(storeInfo).ExecuteCommand();
//库存表记录删除、插入出入记录
var inventoryDetail = DbHelp.db.Queryable<InventoryDetail>().Where(t => t.StoreId == storeInfo.Id).First();
if (inventoryDetail != null)
{
var inOutRecord = new InOutRecord()
{
StoreCode = storeInfo.StoreCode,
StoreId = storeInfo.Id,
StoreInfo = storeInfo,
MatSN = inventoryDetail.MatSN,
MatCode = inventoryDetail.MatCode,
MatName = inventoryDetail.MatName,
MatBatch = inventoryDetail.MatBatch,
MatQty = inventoryDetail.MatQty,
MatSpec = inventoryDetail.MatSpec,
MatCustomer = inventoryDetail.MatCustomer,
MatSupplier = inventoryDetail.MatSupplier,
Direction = DirectionEnum.,
};
DbHelp.db.Insertable(inOutRecord).ExecuteCommand();
DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand();
}
DbHelp.db.CommitTran();
}
catch (Exception e)
{
DbHelp.db.RollbackTran();
}
});
#endregion
WarningLight.WaringLightAlwaysRed(TcpCleint);
}
//库位未配置、返回数据异常
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
WarningLight.WaringLightAlwaysRed(TcpCleint);
}
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.BoardId == boardId
&& t.LightNumber == number).First();
if (storeInfo == null)
{
//TO DO 报错
return;
}
var module = this.Modules.Where(t => t.BoardId == boardId)
.FirstOrDefault();
if (module == null)
{
//TO DO 报错
return;
}
#region
//物料未扫码
if (this.InStoreData == null)
{
//重复给了多次信号
if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn))
{
module.ComfirmInstore(TcpCleint);
//TO DO Logs.Write($"[{guid}]CAN给了多次正常入库信号防止硬件异常返回了确认入库");
return;
}
else
{
module.ComfirmErrInstore(TcpCleint);
WarningLight.WaringLightBlueEnd(TcpCleint);
//WaringLightBlueEnd(shelfStatus.ClientIp, shelfStatus.LightId);
//TO DO Logs.Write($"[{guid}]当前物料信息不存在,请取出后重新扫码进行入库!");
return;
}
}
//该位置已放置物料
else if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn))
{
module.ComfirmErrInstore(TcpCleint);
WarningLight.WaringLightBlueEnd(TcpCleint);
//ComfirmErrInstoreByIp(shelfStatus.ClientIp, boardId);
//WaringLightBlueEnd(shelfStatus.ClientIp, shelfStatus.LightId);
//TO DO Logs.Write($"[{guid}]该位置已放置物料!");
return;
}
#endregion
#region
{
try
{
DbHelp.db.BeginTran();
//库存明细表
var inventoryDetail = new InventoryDetail
{
StoreCode = storeInfo.StoreCode,
StoreId = storeInfo.Id,
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 = ""
};
//出入库记录表
var inOutRecord = new InOutRecord()
{
StoreCode = storeInfo.StoreCode,
StoreId = storeInfo.Id,
StoreInfo = storeInfo,
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报警灯同时进行亮绿灯并鸣叫一次提示。
Thread.Sleep(20);
Task.Run(() =>
{
//确认入库硬件入库位置亮灯1秒
module.ComfirmInstore(TcpCleint);
//报警灯亮绿灯 鸣叫一次提示
WarningLight.SuccessLightBlueEnd(TcpCleint);
//SuccessLightBlueEnd(shelfStatus.ClientIp, shelfStatus.LightId);
});
}
catch (Exception ex)
{
DbHelp.db.RollbackTran();
Logs.Write($"入库保存数据异常,异常信息为{ex.Message}");
//报警灯报警
WarningLight.WaringLightBlueEnd(TcpCleint);
//WaringLightBlueEnd(shelfStatus.ClientIp, shelfStatus.LightId);
}
}
#endregion
}
/// <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.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
Task.Run(() =>
{
try
{
DbHelp.db.BeginTran();
//库位表字段清空
storeInfo.CurrentMatSn = string.Empty;
DbHelp.db.Updateable(storeInfo).ExecuteCommand();
//库存表记录删除、插入出入记录
var inventoryDetail = DbHelp.db.Queryable<InventoryDetail>().Where(t => t.StoreId == storeInfo.Id).First();
if (inventoryDetail != null)
{
var inOutRecord = new InOutRecord()
{
StoreCode = storeInfo.StoreCode,
StoreId = storeInfo.Id,
StoreInfo = storeInfo,
MatSN = inventoryDetail.MatSN,
MatCode = inventoryDetail.MatCode,
MatName = inventoryDetail.MatName,
MatBatch = inventoryDetail.MatBatch,
MatQty = inventoryDetail.MatQty,
MatSpec = inventoryDetail.MatSpec,
MatCustomer = inventoryDetail.MatCustomer,
MatSupplier = inventoryDetail.MatSupplier,
Direction = DirectionEnum.,
};
DbHelp.db.Insertable(inOutRecord).ExecuteCommand();
DbHelp.db.Deleteable(inventoryDetail).ExecuteCommand();
}
DbHelp.db.CommitTran();
}
catch (Exception e)
{
DbHelp.db.RollbackTran();
}
});
#endregion
WarningLight.WaringLightAlwaysRed(TcpCleint);
}
//库位未配置、返回数据异常
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
WarningLight.WaringLightAlwaysRed(TcpCleint);
}
else
{
Logs.Write($"[进入入库模式异常]板Id{boardId},库位号{index + 1}找不到对应库位!");
}
}
}
}
}
}
#endregion
}
}