You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

404 lines
15 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Admin.Core.Common;
using Admin.Core.IService;
using Admin.Core.Model;
using Admin.Core.Service;
using Aucma.Core.HwPLc;
using Aucma.Core.Scanner;
using log4net;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Aucma.Core.Palletiz.Business
{
/// <summary>
///分垛入库业务处理
/// </summary>
public class InstoreBusiness
{
#region 单例实现
private static readonly InstoreBusiness lazy = new InstoreBusiness();
public static InstoreBusiness Instance
{
get
{
return lazy;
}
}
#endregion
#region 变量定义
public readonly List<ScannerModel> allScanners = Appsettings.app<ScannerModel>("ScannerServer").ToList();
public readonly string storeCodeA = Appsettings.app("StoreInfo", "PalletizStoreCodeA");//分垛库A
public readonly string storeCodeB = Appsettings.app("StoreInfo", "PalletizStoreCodeB");//分垛库B
#endregion
#region 接口引用
private static readonly log4net.ILog logHelper = LogManager.GetLogger(typeof(InstoreBusiness));
private readonly IBaseSpaceInfoServices? _baseSpaceInfoServices = App.ServiceProvider.GetService<IBaseSpaceInfoServices>();
private readonly ICodeBindingRecordServices? _codeBindingServices = App.ServiceProvider.GetService<ICodeBindingRecordServices>();
private readonly IRecordInStoreServices? _recordInstoreServices = App.ServiceProvider.GetService<IRecordInStoreServices>();
#endregion
public void test()
{
// B240101 8302501416 0001 SN:16160030000000910999
Task.Run(async () =>
{
Thread.Sleep(3000);
await InStore("16160030000000910999", "192.168.1.19");
});
}
#region 扫码入库处理
/// <summary>
///
/// </summary>
/// <param name="SNCode">成品码</param>
/// <param name="scannerIp">扫码器ip</param>
/// <returns></returns>
public async Task InStore(string SNCode,string scannerIp)
{
try
{
// 刷新页面
List<ScannerModel> allScanners = Appsettings.app<ScannerModel>("ScannerServer").ToList();
ScannerModel model = allScanners.FirstOrDefault(x => x.Ip == scannerIp);
// plc下发结果
bool plcResult = false;
// 下发plc的货道号
List<int> spaceNumList = new List<int>();
// 入库记录
RecordInStore recordInstore = new RecordInStore();
//1.根据成品码找货道
List<BaseSpaceInfo> spaceList = getSpaceBySNCode(SNCode,recordInstore);
// 根据货道信息判断下发plc信号
if (spaceList == null || spaceList.Count==0)
{
logHelper.Error("未找到匹配货道,请手动入库!");
// 刷新页面提示信息
Console.WriteLine("未找到匹配货道,请手动入库!");
return;
}
// 过滤货道,找到最终需要下发的货道
BaseSpaceInfo finalSpace = FilterSpace(spaceList);
// 大产品占两道
if (finalSpace.IsTwoSpace == 1)
{
spaceNumList.Add(int.Parse(finalSpace.SpaceCode.Substring(5, 3)));
spaceNumList.Add(int.Parse(getOtherSpace(finalSpace, spaceList).SpaceCode.Substring(5, 3)));
plcResult = sendAndAnswerPlc(scannerIp, spaceList[0].RotationRange, spaceNumList);
recordInstore.SpaceCode = finalSpace.SpaceCode;
recordInstore.StoreCode = finalSpace.StoreCode;
// 更新货道信息,大产品last存objId大的储存上一个货道的主键 如货道7,8存8
BaseSpaceInfo otherSpace = getOtherSpace(finalSpace, spaceList);
if (otherSpace != null)
{
updateSapceList(otherSpace.ObjId,spaceList);
Console.WriteLine("更新货道信息成功!");
}
}
else
{
// last不等于自己可以先入自己否则入另一条货道
if (isOddNumber(finalSpace))
{
spaceNumList.Add(int.Parse(finalSpace.SpaceCode.Substring(5, 3)));
spaceNumList.Add(0);
plcResult = sendAndAnswerPlc(scannerIp, finalSpace.RotationRange, spaceNumList);
updateSapceList(finalSpace.ObjId, spaceList);
Console.WriteLine("更新货道信息成功!");
}
else
{
spaceNumList.Add(0);
spaceNumList.Add(int.Parse(finalSpace.SpaceCode.Substring(5, 3)));
plcResult = sendAndAnswerPlc(scannerIp, finalSpace.RotationRange, spaceNumList);
updateSapceList(finalSpace.ObjId, spaceList);
Console.WriteLine("更新货道信息成功!");
}
}
if (plcResult==true)
{
// 更新入库记录,刷新界面
#region 添加入库记录
recordInstore.SpaceCode = finalSpace.SpaceCode;
recordInstore.StoreCode = finalSpace.StoreCode;
recordInstore.InStoreAmount = 1;
recordInstore.InStoreTime = DateTime.Now;
recordInstore.CreatedTime = DateTime.Now;
recordInstore.UpdateTime = DateTime.Now;
_ = _recordInstoreServices.AddAsync(recordInstore).Result;
#endregion
}
else
{
// 界面提示手动入库
}
}
catch (Exception ex)
{
logHelper.Error(ex.Message.ToString());
return;
}
}
/// <summary>
/// 根据成品码找货道
/// </summary>
/// <param name="SNCode"></param>
/// <returns></returns>
private List<BaseSpaceInfo> getSpaceBySNCode(string SNCode, RecordInStore recordInstore)
{
try
{
CodeBindingRecord bindingRecord = _codeBindingServices.Query(c => c.ProductCode.Equals(SNCode)).FirstOrDefault();
if (bindingRecord == null) return null;
recordInstore.BarCodeCode = bindingRecord.BoxCode;
recordInstore.MaterialCode = bindingRecord.BoxCode;
recordInstore.MaterialType = bindingRecord.BoxCode.Substring(7, 10);
recordInstore.MaterialName = bindingRecord.BoxName;
return _baseSpaceInfoServices.Query(s => s.MaterialType.Equals(bindingRecord.BoxCode.Substring(7, 10)) && (s.StoreCode.Equals(storeCodeA) || s.StoreCode.Equals(storeCodeB)) ).OrderBy(x=>x.ObjId).ToList();
}
catch (Exception ex)
{
logHelper.Error(ex.Message.ToString());
return null;
}
}
private BaseSpaceInfo FilterSpace(List<BaseSpaceInfo> spaceInfos)
{
if (spaceInfos.Count == 1 || string.IsNullOrEmpty(spaceInfos[0].LastSpace))
{
return spaceInfos[0];
}
List<BaseSpaceInfo> spaceList = spaceInfos.Where(s=>s.ObjId> int.Parse(spaceInfos[0].LastSpace)).ToList();
if(spaceList==null|| spaceList.Count == 0)
{
return spaceInfos[0];
}
else
{
return spaceList[0];
}
}
/// <summary>
/// 大产品占据两条货道,根据一条货道找到另一条货道
/// </summary>
/// <param name="spaceInfo"></param>
private BaseSpaceInfo getOtherSpace(BaseSpaceInfo spaceInfo,List<BaseSpaceInfo> spaceList)
{
try
{
// 找到当前货道匹配的另一条货道
int num = int.Parse(spaceInfo.SpaceCode.Substring(5, 3));
string otherSpaceCode = string.Empty;
if (num % 2 == 0) // 偶数如7,8当前8找7
{
otherSpaceCode = spaceInfo.SpaceCode.Substring(0, 5) + (num - 1).ToString("D3");
}
else
{
otherSpaceCode = spaceInfo.SpaceCode.Substring(0, 5) + (num + 1).ToString("D3");
}
spaceList = spaceList.Where(s => s.SpaceCode.Equals(otherSpaceCode)).ToList();
if (spaceList.Count > 0)
{
return spaceList[0];
}
else
{
return null;
}
}
catch (Exception ex)
{
logHelper.Error(ex.Message.ToString());
return null;
}
}
/// <summary>
/// 判断货道编号是否为奇数
/// </summary>
/// <param name="space"></param>
/// <returns></returns>
private bool isOddNumber(BaseSpaceInfo space)
{
int num = int.Parse(space.SpaceCode.Substring(5, 3));
if(num % 2 == 0)
{
return false;
}
else
{
return true;
}
}
/// <summary>
/// 将该物料的所有货道列表的last修改为上次入库货道objId
/// </summary>
/// <param name="objId"></param>
/// <param name="spaceList"></param>
/// <returns></returns>
private bool updateSapceList(int objId,List<BaseSpaceInfo> spaceList)
{
foreach(BaseSpaceInfo space in spaceList)
{
space.LastSpace = objId.ToString();
}
return _baseSpaceInfoServices.UpdateAsync(spaceList).Result;
}
#endregion
#region plc信号下发
/// <summary>
/// 下发plc入库信号
/// </summary>
/// <param name="scannerIp">扫码器ip</param>
/// <param name="range">转向角度</param>
/// <param name="spaceNum">货道号int集合</param>
/// <returns></returns>
private bool sendAndAnswerPlc(string scannerIp,int range,List<int> spaceNum)
{
bool result = false;
try
{
PlcModel obj = getPlcByScanner(scannerIp);
if (obj != null)
{
if (sendPlc(obj, range, spaceNum))
{
result = waitAnswerPlc(obj);
}
}
else
{
logHelper.Error("plc未连接");
return false;
}
return result;
}
catch (Exception ex)
{
logHelper.Error(ex.Message.ToString());
return result;
}
}
/// <summary>
/// 下发plc信号
/// </summary>
/// <param name="obj"></param>
/// <param name="range"></param>
/// <param name="spaceNum"></param>
/// <returns></returns>
private bool sendPlc(PlcModel obj, int range, List<int> spaceNum)
{
try
{
bool result = false;
DateTime targetTime = DateTime.Now.AddSeconds(8);
while (true)
{
if (DateTime.Now > targetTime) // plc超最大时限无反馈
{
logHelper.Error("等待plc放行反馈信号超时");
return false;
}
// 应答字允许下发
if (obj.plc.ReadInt32("D102") == 1)
{
//旋转角度
obj.plc.WriteInt32("D110", range);
//货道号
obj.plc.WriteInt32("D112", spaceNum[0]);
obj.plc.WriteInt32("D114", spaceNum[1]);
result = true;
break;
}
Thread.Sleep(500);
}
return result;
}
catch (Exception ex)
{
logHelper.Error(ex.Message);
return false;
}
}
/// <summary>
/// 等待plc信号反馈
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private bool waitAnswerPlc(PlcModel obj)
{
try
{
bool result = false;
DateTime targetTime = DateTime.Now.AddSeconds(8);
while (true)
{
if (DateTime.Now > targetTime) // plc超最大时限无反馈
{
logHelper.Error("等待plc放行反馈信号超时");
Console.WriteLine("等待plc放行反馈信号超时");
return false;
}
// 应答字允许下发
if (obj.plc.ReadInt32("D102") == 2)
{
result = true;
Console.WriteLine("下发成功!");
break;
}
Thread.Sleep(500);
}
return result;
}
catch (Exception ex)
{
logHelper.Error(ex.Message.ToString());
return false;
}
}
/// <summary>
/// 根据扫码器ip确定是属于哪个plc
/// </summary>
/// <param name="scannerIp"></param>
/// <returns></returns>
private PlcModel getPlcByScanner(string scannerIp)
{
PlcModel obj = null;
ScannerModel model = allScanners.FirstOrDefault(x => x.Ip == scannerIp);
if (model.Id < 3)
{
obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("A库Plc"));
}
else
{
obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("B库Plc"));
}
return obj;
}
#endregion
}
}