diff --git a/src/YunDa.Application/YunDa.ISAS.DataTransferObject/GeneralInformation/SecondaryCircuitDto/LogicExpressionTelesignalisation.cs b/src/YunDa.Application/YunDa.ISAS.DataTransferObject/GeneralInformation/SecondaryCircuitDto/LogicExpressionTelesignalisation.cs new file mode 100644 index 0000000..2e0c823 --- /dev/null +++ b/src/YunDa.Application/YunDa.ISAS.DataTransferObject/GeneralInformation/SecondaryCircuitDto/LogicExpressionTelesignalisation.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace YunDa.SOMS.DataTransferObject.GeneralInformation.SecondaryCircuitDto +{ + /// + /// 逻辑表达式与遥信地址 + /// + public class LogicExpressionTelesignalisation + { + public string LogicExpression { get; set; } + public string TelesignalisationAddr { get; set; } + } +} diff --git a/src/YunDa.Application/YunDa.ISAS.DataTransferObject/YunDa.ISAS.DataTransferObject.xml b/src/YunDa.Application/YunDa.ISAS.DataTransferObject/YunDa.ISAS.DataTransferObject.xml index 11ab200..36d0d09 100644 --- a/src/YunDa.Application/YunDa.ISAS.DataTransferObject/YunDa.ISAS.DataTransferObject.xml +++ b/src/YunDa.Application/YunDa.ISAS.DataTransferObject/YunDa.ISAS.DataTransferObject.xml @@ -15415,6 +15415,11 @@ 是否在用 + + + 逻辑表达式与遥信地址 + + 二次回路逻辑运算式 diff --git a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/DataCollection/DataCollectionTask.cs b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/DataCollection/DataCollectionTask.cs index 2c8597c..a88d130 100644 --- a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/DataCollection/DataCollectionTask.cs +++ b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/DataCollection/DataCollectionTask.cs @@ -3,6 +3,7 @@ using MongoDB.Driver; using MongoDB.Driver.Linq; using System; using System.Collections; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -215,9 +216,9 @@ namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis.DataCollection Dictionary TelesignalisationModelDic = new Dictionary(); - - List yxList = new List(); - List ycList = new List(); + + ConcurrentBag yxList = new ConcurrentBag(); + ConcurrentBag ycList = new ConcurrentBag(); /// /// 仅更新遥信数据字典 diff --git a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/DataCollection/DataSendTask.cs b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/DataCollection/DataSendTask.cs index 1c35dfd..33e5df8 100644 --- a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/DataCollection/DataSendTask.cs +++ b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/DataCollection/DataSendTask.cs @@ -2,6 +2,7 @@ using Google.Protobuf.WellKnownTypes; using MongoDB.Driver.Linq; using Newtonsoft.Json; +using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; @@ -24,6 +25,7 @@ using YunDa.ISAS.Entities.DataMonitoring; using YunDa.ISAS.Redis.Entities.DataMonitorCategory; using YunDa.ISAS.Redis.Repositories; using YunDa.SOMS.DataTransferObject.MainStationMaintenanceInfo.OperationReport; +using Z.Expressions; namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis.DataCollection { @@ -151,76 +153,25 @@ namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis.DataCollection string redisKey = _redisDataRepository.TelemeteringModelListRediskey + "_" + _settingModel.GetDatacatgoryName(_settingModel.DataSourceCategoryName); string redisChannel = _redisDataRepository.TelemeteringInflectionInflectionZZChannelRediskey + "_" + _settingModel.GetDatacatgoryName(_settingModel.DataSourceCategoryName); ; // 批量获取 Redis 数据以减少读取次数 - string hashKey = $"{yc.addr}_{0}_{yc.inf}_{categoriyValue}"; - var ycData = _redisDataRepository.TelemeteringModelListRedis.HashSetGetOne(redisKey, hashKey); + string haskey = $"{yc.addr}_{0}_{yc.inf}_{categoriyValue}"; + var ycData = _redisDataRepository.TelemeteringModelListRedis.HashSetGetOne(redisKey, haskey); if (ycData == null) { - Log4Helper.Error(this.GetType(), $"更新数据失败: 地址:{yc.inf} 类型:{categoriyValue} 键:{hashKey}"); + Log4Helper.Error(this.GetType(), $"更新数据失败: 地址:{yc.inf} 类型:{categoriyValue} 键:{haskey}"); return; } // 更新对象的数据 ycData.ResultTime = yc.time; ycData.ResultValue = yc.val; - // 并行处理多个任务以提高性能 var tasks = new List(); - - if (_runningDataCache.SecondaryCircuitLogicExpressionDic.ContainsKey(hashKey)) - { - var listLogics = _runningDataCache.SecondaryCircuitLogicExpressionDic[hashKey]; - foreach (var listLogic in listLogics) - { - // 示例字符串 - - // 正则表达式匹配花括号中的内容 - string pattern = @"\{([^}]*)\}"; - Regex regex = new Regex(pattern); - - // 提取匹配内容 - MatchCollection matches = regex.Matches(listLogic); - List extractedStrings = new List(); - foreach (Match match in matches) - { - var logichasKey = match.Groups[1].Value; - var ycLiveData = _redisDataRepository.TelemeteringModelListRedis.HashSetGetOne(redisKey, logichasKey); - if (ycLiveData!=null) - { - listLogic.Replace(logichasKey, ycLiveData.ResultValue.ToString()); - } - } - } - } - // 更新到内存数据库中 - tasks.Add(_redisDataRepository.TelemeteringModelListRedis.HashSetUpdateOneAsync(redisKey, hashKey, ycData)); - //Log4Helper.Info(this.GetType(), $"更新数据成功: 地址:{yc.inf} 类型:{categoriyValue}"); + tasks.Add(_redisDataRepository.TelemeteringModelListRedis.HashSetUpdateOneAsync(redisKey, haskey, ycData)); + tasks.Add(CheckSecondCuirtAlarm(haskey)); // 将变更的数据添加到变位库 订阅 tasks.Add(Task.Run(() => _redisDataRepository.TelemeteringModelInflectionListRedis.PublishAsync(redisChannel, ycData))); - // 异步任务处理数据保存、告警分析和缓存环境温度 - tasks.Add(Task.Run(async () => - { - var rst = new TelemeteringResult - { - ResultTime = ycData.ResultTime, - ResultValue = ycData.ResultValue, - TelemeteringConfigurationId = ycData.Id, - SaveMethod = 2 - }; - - // 保存变更数据 - _telemeteringResultSaveTask.SaveTelemeteringResultActionBlock?.Post(rst); - - // 缓存环境温度(如果适用) - if (ycData.IsEnvironmentTemp) - { - var environmentTempValue = new EnvironmentTempValue(yc.val); - await _redisDataRepository.EnvironmentTempValueRedis.HashSetUpdateOneAsync(nameof(EnvironmentTempValue), ycData.Id.ToString(), environmentTempValue); - } - - // 处理告警分析 - await _alarmAnalysis.HandleTelemeteringAlarmAsync(ycData); - })); + tasks.Add(SetEnvirmentTemp(ycData)); // 执行所有任务并等待完成 await Task.WhenAll(tasks); @@ -231,7 +182,28 @@ namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis.DataCollection MonitoringEventBus.LogHandler(ex.Message, "错误信息"); } } + public async Task SetEnvirmentTemp(TelemeteringModel ycData) + { + var rst = new TelemeteringResult + { + ResultTime = ycData.ResultTime, + ResultValue = ycData.ResultValue, + TelemeteringConfigurationId = ycData.Id, + SaveMethod = 2 + }; + // 保存变更数据 + _telemeteringResultSaveTask.SaveTelemeteringResultActionBlock?.Post(rst); + + // 缓存环境温度(如果适用) + if (ycData.IsEnvironmentTemp) + { + var environmentTempValue = new EnvironmentTempValue(ycData.ResultValue); + await _redisDataRepository.EnvironmentTempValueRedis.HashSetUpdateOneAsync(nameof(EnvironmentTempValue), ycData.Id.ToString(), environmentTempValue); + } + // 处理告警分析 + await _alarmAnalysis.HandleTelemeteringAlarmAsync(ycData); + } public async Task UpdateTelesignalDataAsync(RECORDYXBURST_New yx) { try @@ -256,7 +228,7 @@ namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis.DataCollection // 1. 更新 Redis 中的数据 tasks.Add(_redisDataRepository.TelesignalisationModelListRedis.HashSetUpdateOneAsync(redisKey, haskey, yxData)); - //Log4Helper.Info(this.GetType(), $"更新数据成功: 地址:{yx.dev_inf} 类型:{categoriyValue}"); + tasks.Add(CheckSecondCuirtAlarm(haskey)); // 2. 将更新的数据加入到变位库中 tasks.Add(Task.Run(() => _redisDataRepository.TelesignalisationModelInflectionListRedis.PublishAsync(redisChannel, yxData))); @@ -283,7 +255,58 @@ namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis.DataCollection MonitoringEventBus.LogHandler(ex.Message, "错误信息"); } } - + private async Task CheckSecondCuirtAlarm(string haskey) + { + if (_runningDataCache.SecondaryCircuitLogicExpressionDic.ContainsKey(haskey)) + { + var listLogics = _runningDataCache.SecondaryCircuitLogicExpressionDic[haskey]; + foreach (var listLogic in listLogics) + { + // 示例字符串 + + // 正则表达式匹配花括号中的内容 + string pattern = @"\{([^}]*)\}"; + Regex regex = new Regex(pattern); + + // 提取匹配内容 + MatchCollection matches = regex.Matches(listLogic.LogicExpression); + List extractedStrings = new List(); + foreach (Match match in matches) + { + var logichasKey = match.Groups[1].Value; + string telemeteringredisKey = _redisDataRepository.TelemeteringModelListRediskey + "_" + _settingModel.GetDatacatgoryName(_settingModel.DataSourceCategoryName); + + var ycLiveData = _redisDataRepository.TelemeteringModelListRedis.HashSetGetOne(telemeteringredisKey, logichasKey); + if (ycLiveData != null) + { + listLogic.LogicExpression.Replace(logichasKey, ycLiveData.ResultValue.ToString()); + } + string telesignalisationredisKey = _redisDataRepository.TelesignalisationModelListRediskey + "_" + _settingModel.GetDatacatgoryName(_settingModel.DataSourceCategoryName); + + var yxLiveData = _redisDataRepository.TelesignalisationModelListRedis.HashSetGetOne(telesignalisationredisKey, logichasKey); + if (yxLiveData != null) + { + listLogic.LogicExpression.Replace(logichasKey, yxLiveData.ResultValue.ToString()); + } + } + try + { + var result = Eval.Execute(listLogic.LogicExpression); + if (result) + { + string telesignalisationredisKey = _redisDataRepository.TelesignalisationModelListRediskey + "_" + _settingModel.GetDatacatgoryName("无"); + var yxData = _redisDataRepository.TelesignalisationModelListRedis.HashSetGetOne(telesignalisationredisKey, listLogic.TelesignalisationAddr); + yxData.ResultValue = yxData.RemoteType == RemoteTypeEnum.DoublePoint ? 2 : 1; + _webApiRequest.SendVisualYx(yxData); + } + } + catch (Exception ex) + { + MonitoringEventBus.LogHandler(ex.Message, "错误信息"); + } + } + } + } private Dictionary TelesignaleAlarmTempBuffDic = new Dictionary(); /// /// 发送装置自检信息 diff --git a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/LinkageAnalysis/LinkageAnalysisTask.cs b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/LinkageAnalysis/LinkageAnalysisTask.cs index 8cff390..b373870 100644 --- a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/LinkageAnalysis/LinkageAnalysisTask.cs +++ b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/LinkageAnalysis/LinkageAnalysisTask.cs @@ -1,6 +1,5 @@ using Abp.Dependency; using Castle.MicroKernel.Util; -using Microsoft.ClearScript.V8; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -18,6 +17,7 @@ using Yunda.ISAS.DataMonitoringServer.WebSocket.Model; using YunDa.ISAS.DataTransferObject.DataMonitoring.LinkageConditionDto; using YunDa.ISAS.DataTransferObject.EquipmentLiveData; using YunDa.ISAS.Entities.MySQL.DataMonitoring; +using Z.Expressions; using ConstantModel = Yunda.ISAS.DataMonitoringServer.DataAnalysis.Model.ConstantModel; namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis.LinkageAnalysis @@ -245,11 +245,14 @@ namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis.LinkageAnalysis } string ruleStr = string.Format(linkageStrategy.Rule, conditionStrs.ToArray()); - - using (var engine = new V8ScriptEngine()) + try { - object isLinkageObj = engine.Evaluate(ruleStr); - bool.TryParse(isLinkageObj.ToString(), out isNeedLinkage); + isNeedLinkage = ruleStr.Execute(); + } + catch (Exception ex) + { + Log4Helper.Error(this.GetType(), "解析联动表达式",ex); + isNeedLinkage = false; } } } diff --git a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/MonitoringDataService.cs b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/MonitoringDataService.cs index d543619..0e5f6fb 100644 --- a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/MonitoringDataService.cs +++ b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/MonitoringDataService.cs @@ -1,4 +1,6 @@ using Abp.Dependency; +using Amazon.Runtime.Internal.Transform; +using MongoDB.Driver.Linq; using System; using System.Collections.Generic; using System.Diagnostics; @@ -16,6 +18,7 @@ using Yunda.ISAS.DataMonitoringServer.WebApi; using Yunda.ISAS.DataMonitoringServer.WebSocket; using Yunda.SOMS.DataMonitoringServer.ProtectionDeviceHandle; using Yunda.SOMS.DataMonitoringServer.TcpSocket.Server; +using YunDa.SOMS.DataTransferObject.GeneralInformation.SecondaryCircuitDto; namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis { @@ -163,18 +166,22 @@ namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis var yxlist =await _redisDataRepository.GetTelesignalisationModels(); var yclist =await _redisDataRepository.GetTelemeteringModels(); var ycCheckList =( await _redisDataRepository.GetCheckTelemeteringModels()).ToDictionary(t => t.Id); + var yxSendList =( await _redisDataRepository.GetSendTelesignalisationModels()).ToDictionary(t => t.Id); + var yxDic = yxlist.ToDictionary(t => t.Id); var ycDic = yclist.ToDictionary(t => t.Id); var list = _webApiRequest.GetSecondaryCircuitLogicExpressionList(); foreach (var item in list) { - if (!ycCheckList.ContainsKey(item.TelemeteringConfigurationId.Value)) + if (!ycCheckList.ContainsKey(item.TelemeteringConfigurationId.Value)|| yxSendList.ContainsKey(item.TelesignalisationConfigurationId.Value)) { - Debug.WriteLine("错误,没有找到遥测"); + Debug.WriteLine("错误,没有找到遥测/遥信"); continue; } var checktelemeteringConfiguration = ycCheckList[item.TelemeteringConfigurationId.Value]; - + var sendtelesignalConfiguration = yxSendList[item.TelesignalisationConfigurationId.Value]; + + float? upperLimit = checktelemeteringConfiguration.UpperLimit; float? lowerLimit = checktelemeteringConfiguration.LowerLimit; // 正则表达式匹配花括号中的内容,包括 GUID @@ -213,13 +220,18 @@ namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis foreach (Match match in matches) { string key = match.Groups[1].Value; + var logicExpressionTelesignalisation = new LogicExpressionTelesignalisation + { + LogicExpression = logicalExpression, + TelesignalisationAddr = $"{sendtelesignalConfiguration.DeviceAddress}_{sendtelesignalConfiguration.CPUSector}_{sendtelesignalConfiguration.DispatcherAddress}_{(int)sendtelesignalConfiguration.DataSourceCategory}" + }; if (_runningDataCache.SecondaryCircuitLogicExpressionDic.ContainsKey(key)) { - _runningDataCache.SecondaryCircuitLogicExpressionDic[key].Add(logicalExpression); + _runningDataCache.SecondaryCircuitLogicExpressionDic[key].Add(logicExpressionTelesignalisation); } else { - _runningDataCache.SecondaryCircuitLogicExpressionDic.Add(key, new List { logicalExpression }); + _runningDataCache.SecondaryCircuitLogicExpressionDic.Add(key, new List { logicExpressionTelesignalisation }); } } } diff --git a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/WebApiRequest.cs b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/WebApiRequest.cs index 3bb5c09..959c776 100644 --- a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/WebApiRequest.cs +++ b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataAnalysis/WebApiRequest.cs @@ -546,6 +546,12 @@ namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis (ConstantModel .RequestInitYCRedisListUri + "?dataSourceCategory=" + (int)DataSourceCategoryEnum.None ); + var resObj3 = ToolLibrary + .HttpHelper + .HttpGetRequest + (ConstantModel + .RequestInitYXRedisListUri + "?dataSourceCategory=" + (int)DataSourceCategoryEnum.None + ); } catch (Exception ex) @@ -798,7 +804,27 @@ namespace Yunda.ISAS.DataMonitoringServer.DataAnalysis } } + public async Task SendVisualYx(TelesignalisationModel telesign) + { + if (telesign != null) + { + var iecdata = new IecServerData(); + iecdata.devAddr = (byte)telesign.InfoDeviceAddress; + iecdata.dateTime = DateTime.Now; + iecdata.devCpu = (byte)telesign.InfoCPUSector; + iecdata.inf = telesign.InfoAddress; + iecdata.dataType = 2; + iecdata.devName = "test"; + iecdata.yxValue = telesign.ResultValue; + MonitoringEventBus.LogHandler($"装置地址:{telesign.InfoDeviceAddress} cpu扇区:{telesign.InfoCPUSector} 信息体地址:{telesign.InfoAddress} 遥信值:{telesign.ResultValue}", "发送虚遥信"); + await Task.Run( + + () => ToolLibrary.HttpHelper + .HttpPostRequest(_runningDataCache._transformerSubstation.Iec104ServerUrl + "SendData", iecdata) + ); + } + } /// /// 获取设备缓存 /// diff --git a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataCenter/RedisRepository.cs b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataCenter/RedisRepository.cs index c61036b..e9740cc 100644 --- a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataCenter/RedisRepository.cs +++ b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataCenter/RedisRepository.cs @@ -117,5 +117,12 @@ namespace Yunda.ISAS.DataMonitoringServer.DataCenter var ycDatas = await TelemeteringModelListRedis.HashSetGetAllAsync(redisKey); return ycDatas; } + public async Task> GetSendTelesignalisationModels() + { + string redisKey = TelesignalisationModelListRediskey + "_" + _settingModel.GetDatacatgoryName("无"); ; + // 从 Redis 中批量获取所有遥测数据 + var yxDatas = await TelesignalisationModelListRedis.HashSetGetAllAsync(redisKey); + return yxDatas; + } } } diff --git a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataCenter/RunningDataCache.cs b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataCenter/RunningDataCache.cs index 4591a8e..c76eead 100644 --- a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataCenter/RunningDataCache.cs +++ b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/DataCenter/RunningDataCache.cs @@ -133,7 +133,7 @@ namespace Yunda.ISAS.DataMonitoringServer.DataCenter /// /// 逻辑表达式策略缓存 /// - public Dictionary> SecondaryCircuitLogicExpressionDic { get; set; } = new (); + public Dictionary> SecondaryCircuitLogicExpressionDic { get; set; } = new (); diff --git a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/Yunda.SOMS.DataMonitoringServer.csproj b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/Yunda.SOMS.DataMonitoringServer.csproj index 2dea165..f1accc0 100644 --- a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/Yunda.SOMS.DataMonitoringServer.csproj +++ b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/Yunda.SOMS.DataMonitoringServer.csproj @@ -103,10 +103,10 @@ - + diff --git a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/appsettings.development.json b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/appsettings.development.json index 87467bf..ce45428 100644 --- a/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/appsettings.development.json +++ b/src/YunDa.Server/Yunda.ISAS.DataMonitoringServer/appsettings.development.json @@ -31,7 +31,7 @@ "FunctionName": "综自(配电)" }, "SysBaseConfig": { - "WebAddrUrl": "http://192.168.81.229:38091", + "WebAddrUrl": "http://192.168.81.143:38091", "WebExternBaseUrl": "https://127.0.0.1:4431", "OpenVideoLog": false, "LinkAgingSecond": 60 //联动防抖时间,例如设置60,表示60秒内只联动一次