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.

351 lines
12 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.Helper;
using Admin.Core.IService;
using Admin.Core.Model;
using Admin.Core.Model.Model_New;
using Admin.Core.Service;
using Admin.Core.Socket;
using Aucma.Core.Palletiz.config;
using Aucma.Core.PLc;
using log4net;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using TouchSocket.Sockets;
namespace Aucma.Core.Palletiz.Business
{
internal class InStoreBusiness
{
private static readonly log4net.ILog _logger = LogManager.GetLogger(typeof(InStoreBusiness));
private readonly IProductOffLineServices _offlineService;
private readonly IBaseSpaceInfoServices _spaceinfoService;
private readonly AppConfig _appConfig;
private const string BarcodeRef = "6933973114570;1621240AP0098E3D3497";
private readonly PlcModel plcCon = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("OldMelsecPlc1"));
public InStoreBusiness()
{
_appConfig = new AppConfig();
_spaceinfoService = App.ServiceProvider.GetService<IBaseSpaceInfoServices>();
_offlineService = App.ServiceProvider.GetService<IProductOffLineServices>();
}
public void Init()
{
TouchSocketService.ReceivedClientBufferEvent += ReceivedBuffer;
}
/// <summary>
/// Buffer缓冲
/// </summary>
/// <param name="buffer"></param>
private void ReceivedBuffer(SocketClient client, byte[] buffer)
{
try
{
//_logger.LogInformation($"接收客户端:{client.Id};原始报文:{_stringChange.bytesToHexStr(buffer, buffer.Length)}");
do
{
string asciiStr = Encoding.ASCII.GetString(buffer);
if (asciiStr.Contains("heartbeat"))
{
_logger.Info($"收到客户端:{client.Id};心跳指令:{asciiStr}");
continue;
}
if (asciiStr.Contains("NoRead"))
{
NoReadHandle(client.Id);
continue;
}
_logger.Info($"收到客户端:{client.Id}条码信息:{asciiStr}");
InStore(client.Id, asciiStr);
} while (false);
}
catch (Exception e)
{
_logger.Error($"Buffer缓冲异常:{e.Message}");
}
}
/// <summary>
/// 入库申请
/// </summary>
/// <param name="spaceArea">货道区域</param>
/// <param name="asciiStr"></param>
private void InStore(string spaceArea, string asciiStr)
{
try
{
if (string.IsNullOrEmpty(asciiStr))
{
throw new ArgumentException($"入库申请处理异常:条码信息为空");
}
if (string.IsNullOrEmpty(spaceArea))
{
throw new ArgumentException($"入库申请处理异常:货道区域为空");
}
if (asciiStr.Contains(";") && asciiStr.Length == BarcodeRef.Length)
{
string[] splitStr = asciiStr.Split(";");
if (splitStr.Length > 1)
{
asciiStr = splitStr[1];
}
}
_offlineService.GetProductInfosBySnCode(asciiStr, out ProductOffline prodInfo);
if (prodInfo == null)
{
throw new ArgumentException($"入库申请处理异常:根据成品码获取成品信息为空");
}
GetSpaceInfoByMaterialType(spaceArea, prodInfo, out BaseSpaceInfo laseSpaceinfo,
out BaseSpaceInfo spaceinfo);
bool result = false;
SendInStoreTask(spaceinfo, ref result);
if (!result)
{
throw new ArgumentException($"入库申请处理异常:入库任务下发至PLC失败");
}
else
{
List<BaseSpaceInfo> spaceinfos = new List<BaseSpaceInfo>();
if (laseSpaceinfo != null)
{
laseSpaceinfo.InStoreFlag = 1;
spaceinfos.Add(laseSpaceinfo);
}
spaceinfo.InStoreFlag = 3;
spaceinfos.Add(spaceinfo);
_spaceinfoService.UpdateSpaceInfo(spaceinfos);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
//异常处理,手动入库
}
}
/// <summary>
/// 通过物料型号获取货道信息
/// </summary>
/// <param name="spaceArea"></param>
/// <param name="prodInfo"></param>
/// <param name="laseSpaceinfo"></param>
/// <param name="spaceinfo"></param>
/// <param name="isBig"></param>
/// <exception cref="ArgumentException"></exception>
private void GetSpaceInfoByMaterialType(string spaceArea, ProductOffline prodInfo, out BaseSpaceInfo laseSpaceinfo, out BaseSpaceInfo spaceinfo, bool isBig = false)
{
List<BaseSpaceInfo> spaceinfos = null;
if (isBig)
{
_spaceinfoService.GetSpaceInfosByExpression(out spaceinfos, x => x.StoreCode == _appConfig.storeCode && x.SpaceArea == spaceArea && x.MaterialType == prodInfo.ProductCode && x.SpaceType == 1);
}
else
{
_spaceinfoService.GetSpaceInfosByExpression(out spaceinfos, x => x.StoreCode == _appConfig.storeCode && x.SpaceArea == spaceArea && x.MaterialType == prodInfo.ProductCode);
}
if (spaceinfos == null)
{
throw new ArgumentException($"通过物料型号获取货道信息异常:根据成品信息获取货道信息为空");
}
spaceinfos = spaceinfos.OrderBy(x => x.ObjId).ToList();
MatchSpaceInfoByPlc(ref spaceinfos);
if (spaceinfos == null)
{
throw new ArgumentException($"通过物料型号获取货道信息异常:通过PLC匹配可用货道信息为空");
}
FiltrateSpaceInfo(spaceinfos, out laseSpaceinfo, out spaceinfo);
if (spaceinfo == null)
{
throw new ArgumentException($"通过物料型号获取货道信息异常:未获取到匹配的货道信息");
}
}
/// <summary>
/// 通过PLC匹配获取去除已满的货道
/// </summary>
/// <param name="spaceinfos"></param>
private void MatchSpaceInfoByPlc(ref List<BaseSpaceInfo> spaceinfos)
{
if (plcCon == null)
{
throw new ArgumentException($"通过PLC匹配获取货道信息异常:Plc连接为空");
}
var _plc = plcCon.plc;
foreach (var item in spaceinfos)
{
item.SpaceCode = ExtractNumber(item.SpaceName);
var plcAddress = _appConfig.plcAddr.Where(x => x.spaceCode.ToString() == item.SpaceCode && x.spaceArea == item.SpaceArea).First();
int isFlag = _plc.ReadInt16(plcAddress.address);
if (isFlag == 1)
{
item.SpaceStatus = 3;
}
}
spaceinfos = spaceinfos.Where(x => x.SpaceStatus != 3).ToList();
}
/// <summary>
/// 筛选货道信息
/// </summary>
/// <param name="spaceinfos"></param>
/// <param name="spaceinfo"></param>
/// <exception cref="ArgumentException"></exception>
private void FiltrateSpaceInfo(List<BaseSpaceInfo> spaceinfos, out BaseSpaceInfo laseSpaceinfo, out BaseSpaceInfo spaceinfo)
{
if (spaceinfos == null)
{
throw new ArgumentException($"筛选货道信息异常:传入货道信息参数为空");
}
int count = spaceinfos.Where(x => x.InStoreFlag == 3).ToList().Count;
if (count > 0)
{
int index = spaceinfos.FindIndex(entity => entity.InStoreFlag == 3);
laseSpaceinfo = spaceinfos[index];
int nextIndex = (index + 1) % spaceinfos.Count;
spaceinfo = spaceinfos[nextIndex];
}
else
{
laseSpaceinfo = null;
spaceinfo = spaceinfos.First();
}
}
/// <summary>
/// 下发入库任务至PLC
/// </summary>
/// <param name="spaceinfo"></param>
/// <param name="result"></param>
/// <exception cref="ArgumentException"></exception>
private void SendInStoreTask(BaseSpaceInfo spaceinfo, ref bool result)
{
if (plcCon == null)
{
throw new ArgumentException($"下发入库任务至PLC逻辑异常:Plc连接为空");
}
var _plc = plcCon.plc;
bool isFlag = true;
while (isFlag)
{
bool answerFlag = _plc.ReadBool("X1000");
if (answerFlag)
{
isFlag = false;
}
Task.Delay(1000 * 2).Wait();
}
int spaceCode = StringChange.ParseToInt(spaceinfo.SpaceCode);
int spinFlag = 0;
if (spaceCode % 2 == 0) //偶数 转180°
{
spinFlag = 4;
}
if (spaceinfo.SpaceArea == "A")
{
if (!_plc.WriteInt16("D2", spinFlag.ToString()))
{
throw new ArgumentException($"旋转角度下发至PLC失败");
}
if (!_plc.WriteInt16("D29", spaceCode.ToString()))
{
throw new ArgumentException($"货道号下发至PLC失败");
}
result = true;
}
else if (spaceinfo.SpaceArea == "B")
{
result = false;
}
}
/// <summary>
/// 提取货道号
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private static string ExtractNumber(string input)
{
string pattern = @"\d+";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
return match.Value.TrimStart('0');
}
else
{
return null; // 或者返回默认值,如"0"
}
}
/// <summary>
/// 读取失败处理
/// </summary>
/// <param name="client"></param>
private void NoReadHandle(string client)
{
_logger.Error($"客户端:{client};读取失败!!!!!!");
}
/// <summary>
/// 获取成品库指定区域的货道信息
/// </summary>
/// <param name="spaceArea"></param>
/// <returns></returns>
public List<BaseSpaceInfo> GetBaseSpaceinfos(string spaceArea)
{
_spaceinfoService.GetSpaceInfosByExpression(out List<BaseSpaceInfo> spaceinfos, x => x.StoreCode == _appConfig.storeCode && x.SpaceArea == spaceArea);
return spaceinfos;
}
}
}