//using CMS.Extensions.Variable; //using CMS.Plugin.FlowManagement.Abstractions.FlowBusiness; //using CMS.Plugin.PipeLineLems.Apis; //using CMS.Plugin.PipeLineLems.Application.Contracts.Dtos.MyTestEntityNames; //using CMS.Plugin.PipeLineLems.Domain.MyTestEntityNames; //using CMS.Plugin.PipeLineLems.Jobs; //using CMS.Plugin.ProcessManagement.Abstractions; //using CMS.Plugin.TraceManagement.Abstractions.Models.Traces; //using CMS.Plugin.TraceManagement.Abstractions; //using CMS.Project; //using CMS.Project.Abstractions; //using CMS.Unit.RuntimeValue.Abstractions; //using KissUtil.Extensions; //using Microsoft.Extensions.DependencyInjection; //using Microsoft.Extensions.Logging; //using System; //using Volo.Abp.BackgroundJobs; //using Volo.Abp.Uow; //namespace CMS.Plugin.PipeLineLems.ProjectService //{ // /// // /// 工程服务,和工程关联的后台服务,当以当前Key调用时会被执行 // /// // public class PipeLineLemsProjectService : BaseProjectService // { // private IServiceProvider _serviceProvider; // private readonly ILogger _logger; // private readonly IVariableDataCache _variableDataCache; // /// // /// 变量服务 // /// // private readonly VariableService _variableService; // private FlowVariableChannelListener _channelListener; // private Dictionary _monitorVariableNames; // /// // /// 服务的Key,唯一,供使用 // /// // public override string Key => "PipeLineLems"; // /// // /// 服务描述,显示在服务列表UI上的名称 // /// // public override string Description => "PipeLineLems服务"; // /// // /// 启用授权 // /// // public override bool AuthRequired => true; // /// // /// Initializes a new instance of the class. // /// // /// The logger. // /// The variable data cache. // public PipeLineLemsProjectService( // VariableService variableService, // IServiceProvider serviceProvider, ILogger logger, IVariableDataCache variableDataCache) // { // _serviceProvider = serviceProvider; // _logger = logger; // _variableDataCache = variableDataCache; // _variableService = variableService; // } // /// // /// 开启服务 // /// // /// 具有工程上下文的实例 // public override async Task StartAsync(IServiceProvider serviceProvider) // { // if (State == ProjectServiceState.Started) // { // return; // } // // 监听变量 // _monitorVariableNames = new Dictionary // { // { "打码进站信号", "打码进站信号(描述)" }, // { "切割进站信号", "切割进站信号(描述)" }, // }; // // 创建通道监听 // _channelListener?.Token?.Dispose(); // _channelListener = new FlowVariableChannelListener(_logger, _variableDataCache); // _channelListener.CreateChannel(Key, waitListener: false, timeout: TimeSpan.FromSeconds(30), variableFilter: _monitorVariableNames.Keys.ToHashSet()); // _channelListener.TagChanged += OnTagValueChanged; // await base.StartAsync(serviceProvider); // } // /// // /// 停止服务 // /// // /// 具有工程上下文的实例 // public override async Task StopAsync(IServiceProvider serviceProvider) // { // if (_channelListener != null) // { // // 释放监听 // _channelListener.TagChanged -= OnTagValueChanged; // _channelListener.Token.Dispose(); // _channelListener = null; // } // // 使用后台作业异步处理 // //await _serviceProvider.GetRequiredService().EnqueueAsync(new PipeLineLemsArgs // //{ // // Subject = "PipeLineLems_Subject", // // Body = "PipeLineLems_Body", // //}); // await base.StopAsync(serviceProvider); // } // /// // /// Called when [tag value changed]. // /// // /// The sender. // /// The instance containing the event data. // private async void OnTagValueChanged(object sender, TagChangedEventArgs e) // { // var changeds = e.Changeds.Where(x => _monitorVariableNames != null && _monitorVariableNames.ContainsKey(x.Name)); // if (!changeds.Any()) // { // return; // } // foreach (var changed in changeds) // { // var oldValue = changed.Old?.Value; // var newValue = changed.New?.Value; // var traceId = e.TraceId; // _logger.LogInformation($"{changed.Name} 变量值发生变化,旧值{oldValue}=新值{newValue},TraceId={traceId}"); // if (changed.Name == "打码进站信号" && changed.New?.Value.SafeString().ToBool() == true) // { // // TODO: 处理变量值变化 // // Tips:https://cms-docs.shengyc.com/cms/api/%E5%90%8E%E7%AB%AF#3-%E5%8F%98%E9%87%8F%E6%A8%A1%E5%9D%97 // /* 说明:通过订阅 IVariableDataCache.TagChanged 事件,您可以实时监控变量的变化。此事件会传递所有变量至事件处理函数,因此,业务层需在函数中筛选关注的变量。 // 注意事项: // (1)性能影响: 发布事件时,事件的发送者将阻塞流程。因此,强烈建议避免在事件处理函数中执行 I/ O 操作、HTTP 接口访问或其他耗时操作,以防止对系统性能产生严重影响,导致整个系统响应延迟。 // (2)高频率触发: 由于事件订阅了全量变量,触发频率可能非常高。 // (3)异步处理: 鉴于事件触发频率很高,建议业务层在筛选关注变量后,使用 Task 启动新线程处理业务逻辑,以避免阻塞核心的变量监听功能,实现业务层与平台基座的解耦。 // (4)并发管理: 如果业务层并发量大,必须优化代码设计和实施,以减少在高并发情况下的系统资源消耗,防止系统性能问题。 // (5)代码安全: 安装并使用 CMS.CodeAnalysis 分析器来分析 IVariableDataCache.TagChanged 的使用情况。该工具能在使用不当时提供编译错误,帮助您提高代码质量。*/ // _ = Task.Run(async () => // { // await HanlderForPringBarCodeAsync(); // // 例1:同步处理 // //await ProcessAsync(); // // 例2:调用外部API // //await ExecuteExternalApiAsync(); // }); // } // if (changed.Name == "切割进站信号" && changed.New?.Value.SafeString().ToBool() == true) // { // // TODO: 处理变量值变化 // // Tips:https://cms-docs.shengyc.com/cms/api/%E5%90%8E%E7%AB%AF#3-%E5%8F%98%E9%87%8F%E6%A8%A1%E5%9D%97 // /* 说明:通过订阅 IVariableDataCache.TagChanged 事件,您可以实时监控变量的变化。此事件会传递所有变量至事件处理函数,因此,业务层需在函数中筛选关注的变量。 // 注意事项: // (1)性能影响: 发布事件时,事件的发送者将阻塞流程。因此,强烈建议避免在事件处理函数中执行 I/ O 操作、HTTP 接口访问或其他耗时操作,以防止对系统性能产生严重影响,导致整个系统响应延迟。 // (2)高频率触发: 由于事件订阅了全量变量,触发频率可能非常高。 // (3)异步处理: 鉴于事件触发频率很高,建议业务层在筛选关注变量后,使用 Task 启动新线程处理业务逻辑,以避免阻塞核心的变量监听功能,实现业务层与平台基座的解耦。 // (4)并发管理: 如果业务层并发量大,必须优化代码设计和实施,以减少在高并发情况下的系统资源消耗,防止系统性能问题。 // (5)代码安全: 安装并使用 CMS.CodeAnalysis 分析器来分析 IVariableDataCache.TagChanged 的使用情况。该工具能在使用不当时提供编译错误,帮助您提高代码质量。*/ // _ = Task.Run(async () => // { // await HanlderForCutAsync(); // // 例1:同步处理 // //await ProcessAsync(); // // 例2:调用外部API // //await ExecuteExternalApiAsync(); // }); // } // } // } // /// // /// Processes the asynchronous. // /// // private async Task ProcessAsync() // { // using var scope = _serviceProvider.CreateScope(); // var unitOfWorkManager = scope.ServiceProvider.GetRequiredService(); // using var uow = unitOfWorkManager.Begin(requiresNew: true); // var mytestentitynameRepository = scope.ServiceProvider.GetRequiredService(); // var count = await mytestentitynameRepository.GetCountAsync(); // // 如果有更新数据库操作,需提交保存 // // await uow.SaveChangesAsync(); // _logger.LogInformation($"ProcessAsync,Count={count}"); // } // /// // /// Executes the external API. // /// // private async Task ExecuteExternalApiAsync() // { // try // { // await _serviceProvider.GetRequiredService().CreateAsync(new MyTestEntityNameCreateDto // { // Name = "MyTestEntityName_Name", // Code = "MyTestEntityName_Code", // }); // } // catch (Exception e) // { // _logger.LogException(e); // } // } // /// // /// 打码 // /// // /// // private async Task HanlderForPringBarCodeAsync() // { // var plcTaskNo = await _variableService.ReadValueAsync("打码进站PLC任务号"); // if (string.IsNullOrEmpty(plcTaskNo?.Content?.Value.SafeString().ToString())) // { // } // else // { // var myTaskNo = plcTaskNo.Content.Value.SafeString().ToString(); // //TODO:暂时先写入 内部变量 // Dictionary keyValuePairs = new Dictionary // { // { "打码工件1", "11111111" }, // { "打码工件2", "22222222" }, // { "打码工件3", "33333333" } // }; // _variableService.WriteValueAsync(keyValuePairs); // //TODO:模拟采集参数 // keyValuePairs = new Dictionary // { // { "打码速度", 100}, // { "打码质量", 2}, // }; // var ret2 = _variableService.WriteValueAsync(keyValuePairs); // //TODO:暂时生成产品ID // //var productID = Guid.NewGuid().ToString(); // var productID = DateTime.Now.ToString("yyyyMMddHHmmssfff"); // keyValuePairs = new Dictionary // { // { "打码_ProductID", productID}, // }; // var ret = _variableService.WriteValueAsync(keyValuePairs); // } // } // /// // /// 切割 // /// // /// // private async Task HanlderForCutAsync() // { // var plcTaskNo = await _variableService.ReadValueAsync("切割进站PLC任务号"); // if (string.IsNullOrEmpty(plcTaskNo?.Content?.Value.SafeString().ToString())) // { // } // else // { // var myTaskNo = plcTaskNo.Content.Value.SafeString().ToString(); // //TODO:暂时先写入 内部变量 // Dictionary keyValuePairs = new Dictionary // { // { "切割1", "555555" }, // { "切割2", "66666" }, // { "切割3", "77777" } // }; // _variableService.WriteValueAsync(keyValuePairs); // //TODO:模拟采集参数 // keyValuePairs = new Dictionary // { // { "切割速度", 99}, // { "切割质量", 1}, // }; // var ret2 = _variableService.WriteValueAsync(keyValuePairs); // //TODO:暂时生成产品ID // //获取上一个工序的产品ID // //根据工序名获取工序对象 // var _workSectionManager = _serviceProvider.GetRequiredService(); // var lastWorkSection = "打码工序"; // var workSection = await _workSectionManager.GetByNameAsync(lastWorkSection); // //获取工单数据(从末工序查询3个产品) // //读取scms_productions表,根据当前时间查询最近3条记录 // var traceManager = _serviceProvider.GetRequiredService(); // GetTracesRequest request = new GetTracesRequest() // { // WorkSectionId = workSection.Id, // }; // TraceModel traceModel = null; // var list = await traceManager.GetTracesAsync(request); // if (list?.Count > 0) // { // //重新排序 // list = list.OrderByDescending(x => x.FinishTime).ToList(); // traceModel = list.First(); // } // //var productID = Guid.NewGuid().ToString(); // var productID = DateTime.Now.ToString("yyyyMMddHHmmssfff"); // if (traceModel != null) // { // productID = traceModel.SerialNumber; // } // keyValuePairs = new Dictionary // { // { "切割_ProductID", productID}, // }; // var ret = _variableService.WriteValueAsync(keyValuePairs); // } // } // } //}