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 { /// /// 永驻线程 /// 功能:检测传感器信号,判断箱子数 /// 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; } /// /// 功能:检测传感器信号,判断箱子数 /// /// /// private async Task ExecuteAsync(CancellationToken stoppingToken) { try { //int index = 1; //int indexMax = await DbScoped.SugarScope.CopyNew() // .Queryable().CountAsync(); while (!stoppingToken.IsCancellationRequested) { //读取PLC I/O状态 12个数组 Byte[] getPLCValueByteArray=pLCTool.ReadAllValue("VB100",12); //判断 每个料架每层的箱子数 //1. 获取所有料架层 合并的箱子 料架层翻倍 List storagelocationList = await DbScoped.SugarScope.CopyNew().Queryable().ToListAsync(); //2. 获取点位表 List pointPositionList = await DbScoped.SugarScope.CopyNew().Queryable().ToListAsync(); List updateStoragelocationList=new List(); List inventorylogs = new List(); if (storagelocationList.Count() > 0) { foreach (Storagelocation layerItem in storagelocationList) { //2 获取这个料架层的点位表 List 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 storagelocationList = await DbScoped.SugarScope.CopyNew() //.Queryable().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); } } } }