Files
sy_hx_pbl_backend/DOAN.ServiceCore/DoanBackgroundService.cs
2025-01-16 10:39:57 +08:00

287 lines
12 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.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using DOAN.Infrastructure.PLC;
using DOAN.Model.PBL;
using DOAN.Model.System;
using Microsoft.Extensions.Hosting;
using SqlSugar;
using SqlSugar.IOC;
namespace DOAN.ServiceCore
{
/// <summary>
/// 永驻线程
/// 功能:检测传感器信号,判断箱子数
/// </summary>
public class DoanBackgroundService : IHostedService, IDisposable
{
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
private Task _executingTask;
private PLCTool pLCTool;
public Task StartAsync(CancellationToken cancellationToken)
{
pLCTool = new PLCTool();
pLCTool.ConnectPLC();
// 当服务开始时,启动后台任务
_executingTask = ExecuteAsync(_cancellationTokenSource.Token);
return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
}
public async Task StopAsync(CancellationToken cancellationToken)
{
// 请求取消后台任务
_cancellationTokenSource.Cancel();
// 等待后台任务完成
await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken));
}
private static bool GetInvertedBit(byte b, int position)
{
if (position < 0 || position > 7)
{
throw new ArgumentOutOfRangeException(nameof(position), "Position must be between 0 and 7.");
}
// 创建一个掩码其中只有要检查的那一位是1
byte mask = (byte)(1 << position);
// 使用按位与运算符(&)来检查该位是否为1
bool isSet = (b & mask) != 0;
// 返回取反后的值
return !isSet;
}
/// <summary>
/// 功能:检测传感器信号,判断箱子数
/// </summary>
/// <param name="stoppingToken"></param>
/// <returns></returns>
private async Task ExecuteAsync(CancellationToken stoppingToken)
{
try {
//int index = 1;
//int indexMax = await DbScoped.SugarScope.CopyNew()
// .Queryable<Storagelocation>().CountAsync();
while (!stoppingToken.IsCancellationRequested)
{
//读取PLC I/O状态 12个数组
Byte[] getPLCValueByteArray=pLCTool.ReadAllValue("VB100",12);
//判断 每个料架每层的箱子数
//1. 获取所有料架层 合并的箱子 料架层翻倍
List<Storagelocation> storagelocationList = await DbScoped.SugarScope.CopyNew().Queryable<Storagelocation>().ToListAsync();
//2. 获取点位表
List<PlcAddressTable> pointPositionList = await DbScoped.SugarScope.CopyNew().Queryable<PlcAddressTable>().ToListAsync();
List<Storagelocation> updateStoragelocationList=new List<Storagelocation>();
List<Inventorylog> inventorylogs = new List<Inventorylog>();
if (storagelocationList.Count() > 0) {
foreach (Storagelocation layerItem in storagelocationList)
{
//2 获取这个料架层的点位表
List<PlcAddressTable> thisLayItemPointPositionList= pointPositionList.Where(it => it.FkStorageId == layerItem.Id).ToList();
//3 判断这个料架层箱子的个数
if(thisLayItemPointPositionList!=null&& thisLayItemPointPositionList.Count()>0)
{
// 这一层箱子数 默认最小值为1
int packNum = 1;
foreach(PlcAddressTable i in thisLayItemPointPositionList)
{
int row = i.ByteNum-100;
int col = i.BitNum - 1;
// Console.WriteLine($"row={row},col={col},PLCValueByteArray[row]={getPLCValueByteArray.Length}");
// packNum= packNum+( GetInvertedBit(getPLCValueByteArray[row], col) ? 1 : 0);
//Console.WriteLine($"row:{row}-col:{col} packNum:{packNum} ");
}
// 记录日志
if(packNum> layerItem.PackageNum)
{
Storagelocation storagelocation = layerItem;
storagelocation.PackageNum = packNum;
storagelocation.UpdatedBy = "补料";
storagelocation.UpdatedTime = DateTime.Now;
updateStoragelocationList.Add(storagelocation);
Inventorylog inventorylog = new Inventorylog();
//入库
inventorylog.Id= SnowFlakeSingle.Instance.NextId().ToString();
inventorylog.Operation = 2;
inventorylog.PackageNum = packNum- layerItem.PackageNum;
inventorylog.CreatedBy = "补料";
inventorylog.CreatedTime = DateTime.Now.ToLocalTime();
inventorylogs.Add(inventorylog);
}
else if(packNum < layerItem.PackageNum)
{
Storagelocation storagelocation = layerItem;
storagelocation.PackageNum = packNum;
storagelocation.UpdatedBy = "出料";
storagelocation.UpdatedTime = DateTime.Now;
updateStoragelocationList.Add(storagelocation);
//出库
Inventorylog inventorylog = new Inventorylog();
inventorylog.Id = SnowFlakeSingle.Instance.NextId().ToString();
inventorylog.Operation = 1;
inventorylog.PackageNum =layerItem.PackageNum - packNum ;
inventorylog.CreatedBy = "出料";
inventorylog.CreatedTime = DateTime.Now.ToLocalTime();
inventorylogs.Add(inventorylog);
}
}
}
//修正库存
if (updateStoragelocationList.Count() > 0)
{
await DbScoped.SugarScope.CopyNew().Updateable(updateStoragelocationList).ExecuteCommandAsync();
}
//增加库存变更日志
if(inventorylogs.Count()>0)
{
await DbScoped.SugarScope.CopyNew().Insertable(inventorylogs).ExecuteCommandAsync();
}
}
//List <Storagelocation> storagelocationList = await DbScoped.SugarScope.CopyNew()
//.Queryable<Storagelocation>().Where(it => it.Id == index).ToListAsync();
//if (storagelocationList.Count > 0)
//{
// foreach (var storagelocation in storagelocationList)
// {
// //遮挡不亮 false
// bool result = pLCTool.ReadBit(storagelocation.PlcAddress2);
// // 写补料日志
// Inventorylog inventorylog = new Inventorylog();
// inventorylog.Id = SnowFlakeSingle.Instance.NextId().ToString();
// inventorylog.RackCode = storagelocation.RackCode;
// // 合并货架的id
// //int[] ids = {1,2,3,4,19,20,21,22 };
// int PackageLine = 2;
// //if (ids.Contains(storagelocation.Id))
// //{
// // PackageLine = 1;
// //}
// if (result)
// {
// //缺料,需要补料
// // 仓库库存修正
// if (storagelocation.PackageNum > PackageLine)
// {
// storagelocation.PackageNum = PackageLine;
// /*inventorylog.Operation = 1;
// inventorylog.PackageNum = 1;
// inventorylog.CreatedBy = "PLC";
// inventorylog.CreatedTime = DateTime.Now.ToLocalTime();*/
// await DbScoped.SugarScope.CopyNew().Updateable(storagelocation).ExecuteCommandAsync();
// //await DbScoped.SugarScope.CopyNew().Insertable(inventorylog).ExecuteCommandAsync();
// }
// }
// else
// {
// // 仓库库存修正
// if (storagelocation.PackageNum <= PackageLine)
// {
// //不需要补料 补料成功
// storagelocation.PackageNum = storagelocation.MaxCapacity;
// inventorylog.Operation = 2;
// inventorylog.PackageNum = storagelocation.MaxCapacity;
// inventorylog.CreatedBy = "PLC";
// inventorylog.CreatedTime = DateTime.Now.ToLocalTime();
// await DbScoped.SugarScope.CopyNew().Updateable(storagelocation).ExecuteCommandAsync();
// await DbScoped.SugarScope.CopyNew().Insertable(inventorylog).ExecuteCommandAsync();
// }
// }
// //Console.WriteLine("永驻线程正在读取对射传感器plc值 " + result + "地址:" + storagelocation.PlcAddress2);
// }
//}
//// await Task.Delay(500, stoppingToken);
//index++;
//if (index > indexMax)
//{
// index = 1;
//}
}
} catch (Exception ex) {
Console.WriteLine("DoanBackGround线程ExecuteAsync异常:" + ex.Message);
}
}
public void Dispose()
{
try
{
pLCTool.ConnectClose();
_cancellationTokenSource.Cancel();
_executingTask.Wait();
_cancellationTokenSource.Dispose();
}
catch (Exception ex)
{
Console.WriteLine("DoanBackGround线程Dispose异常:" + ex.Message);
}
}
}
}