2025-10-26 15:12:32 +08:00
|
|
|
|
using Jint;
|
|
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Net.Http;
|
|
|
|
|
|
using System.Net.Http.Json;
|
|
|
|
|
|
using System.Numerics;
|
2025-10-30 12:24:29 +08:00
|
|
|
|
using System.Security.Cryptography;
|
2025-10-26 15:12:32 +08:00
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading;
|
2025-10-30 12:24:29 +08:00
|
|
|
|
using System.Threading.Channels;
|
2025-10-26 15:12:32 +08:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using YunDa.Server.ISMSTcp.Domain;
|
|
|
|
|
|
using YunDa.Server.ISMSTcp.Interfaces;
|
|
|
|
|
|
using YunDa.Server.ISMSTcp.Models;
|
|
|
|
|
|
using YunDa.SOMS.DataTransferObject.DataMonitoring.SecondaryCircuitInspection;
|
2025-10-30 12:24:29 +08:00
|
|
|
|
using YunDa.SOMS.DataTransferObject.DataMonitoring.SecondaryCircuitInspection.Configurations;
|
|
|
|
|
|
using YunDa.SOMS.DataTransferObject.MaintenanceAndOperations.SecondaryEquipment;
|
2025-10-26 15:12:32 +08:00
|
|
|
|
|
|
|
|
|
|
namespace YunDa.Server.ISMSTcp.Services
|
|
|
|
|
|
{
|
2025-10-30 12:24:29 +08:00
|
|
|
|
//Web服务器设置
|
2025-10-26 15:12:32 +08:00
|
|
|
|
public class WebApiSettings
|
|
|
|
|
|
{
|
|
|
|
|
|
public int Port { get; set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-30 12:24:29 +08:00
|
|
|
|
//带执行状态的巡检计划结构体
|
2025-10-26 15:12:32 +08:00
|
|
|
|
public class SecondaryCircuitInspectionPlanStateModel
|
|
|
|
|
|
{
|
|
|
|
|
|
//执行时间
|
|
|
|
|
|
public DateTime ExecuteTime { get; set; } = DateTime.MinValue;
|
|
|
|
|
|
|
|
|
|
|
|
public SecondaryCircuitInspectionPlanOutput Plan { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public SecondaryCircuitInspectionPlanStateModel()
|
|
|
|
|
|
{
|
|
|
|
|
|
Plan = new SecondaryCircuitInspectionPlanOutput();
|
|
|
|
|
|
}
|
2025-10-30 12:24:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class DeviceDzData
|
|
|
|
|
|
{
|
|
|
|
|
|
public List<DzInfo> UserDz { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public List<DzInfo> SysDz { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public string DeviceName { get; set; } = string.Empty;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class InspectionResultData
|
|
|
|
|
|
{
|
|
|
|
|
|
public string PresetName { get; set; } = string.Empty;
|
|
|
|
|
|
|
|
|
|
|
|
public int PresetCode { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public string TimeStamp { get; set; } = string.Empty;
|
|
|
|
|
|
|
|
|
|
|
|
public string Value { get; set; } = string.Empty;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//巡检结果
|
|
|
|
|
|
public class SecondaryCircuitInspectionResultModel
|
|
|
|
|
|
{
|
|
|
|
|
|
//遥测数据
|
|
|
|
|
|
public List<YCResultData> TelemetryInfoData { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
//遥信数据
|
|
|
|
|
|
public List<YXResultData> TeleSignalData { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
//定值
|
|
|
|
|
|
public List<DeviceDzData> DeviceDzData { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
//预置位的巡检结果
|
|
|
|
|
|
public List<InspectionResultData> InspectionResultData { get; set; }
|
2025-10-26 15:12:32 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//二次回路巡检计划
|
|
|
|
|
|
public class SecondaryCircuitInspectionPlanService
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly ILogger<SecondaryCircuitInspectionPlanService> _logger;
|
|
|
|
|
|
private readonly IApiEndpoints _apiEndpoints;
|
|
|
|
|
|
private readonly WebApiRequest _webApiRequest;
|
|
|
|
|
|
private readonly WebApiSettings _webApiSettings;
|
|
|
|
|
|
|
|
|
|
|
|
private bool _updatedPlanOk = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Queue<SecondaryCircuitInspectionPlanStateModel> _planList;
|
|
|
|
|
|
private readonly object _planLock = new object();
|
|
|
|
|
|
private int _planCheckDay = 0;
|
2025-10-30 12:24:29 +08:00
|
|
|
|
private readonly Channel<SecondaryCircuitInspectionItemOutput> _singlePlanChannel;
|
|
|
|
|
|
|
|
|
|
|
|
//巡检事件
|
|
|
|
|
|
private Queue<SecondaryCircuitEventDrivenConfigOutput> _eventPlanList;
|
|
|
|
|
|
private readonly object _eventPlanLock = new object();
|
|
|
|
|
|
private bool _getEventPlanListOk = false;
|
2025-10-26 15:12:32 +08:00
|
|
|
|
|
|
|
|
|
|
public SecondaryCircuitInspectionPlanService(
|
|
|
|
|
|
ILogger<SecondaryCircuitInspectionPlanService> logger,
|
|
|
|
|
|
IApiEndpoints apiEndpoints,
|
|
|
|
|
|
WebApiRequest webApiRequest,
|
|
|
|
|
|
IOptions<WebApiSettings> webApiOptions
|
|
|
|
|
|
)
|
|
|
|
|
|
{
|
|
|
|
|
|
_apiEndpoints = apiEndpoints ?? throw new ArgumentNullException(nameof(apiEndpoints));
|
|
|
|
|
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
|
|
|
|
|
_webApiRequest = webApiRequest ?? throw new ArgumentNullException(nameof(webApiRequest));
|
|
|
|
|
|
|
|
|
|
|
|
_webApiSettings = webApiOptions.Value;
|
|
|
|
|
|
|
|
|
|
|
|
_planList = new Queue<SecondaryCircuitInspectionPlanStateModel>();
|
|
|
|
|
|
|
2025-10-30 12:24:29 +08:00
|
|
|
|
_singlePlanChannel = Channel.CreateUnbounded<SecondaryCircuitInspectionItemOutput>();
|
|
|
|
|
|
|
|
|
|
|
|
_eventPlanList = new Queue<SecondaryCircuitEventDrivenConfigOutput>();
|
|
|
|
|
|
|
2025-10-26 15:12:32 +08:00
|
|
|
|
StartAsync();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task StartAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
//更新计划
|
|
|
|
|
|
_ = Task.Run(async () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
while (true)
|
|
|
|
|
|
{//每30秒更新一下配置
|
|
|
|
|
|
|
|
|
|
|
|
await UpdatePlans();
|
|
|
|
|
|
|
2025-10-30 12:24:29 +08:00
|
|
|
|
await UpdateEventPlans();
|
|
|
|
|
|
|
2025-10-26 15:12:32 +08:00
|
|
|
|
await Task.Delay(30000);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-10-30 12:24:29 +08:00
|
|
|
|
//检测计划
|
2025-10-26 15:12:32 +08:00
|
|
|
|
_ = Task.Run(async () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
while (true)
|
2025-10-30 12:24:29 +08:00
|
|
|
|
{//每10秒检测一下计划
|
2025-10-26 15:12:32 +08:00
|
|
|
|
|
|
|
|
|
|
if (_updatedPlanOk)
|
|
|
|
|
|
{
|
|
|
|
|
|
await CheckPlan();
|
|
|
|
|
|
|
2025-10-30 12:24:29 +08:00
|
|
|
|
await Task.Delay(10000);
|
2025-10-26 15:12:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
await Task.Delay(10000);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-10-30 12:24:29 +08:00
|
|
|
|
|
|
|
|
|
|
//事件计划
|
|
|
|
|
|
_ = Task.Run(async () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
while (true)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_getEventPlanListOk)
|
|
|
|
|
|
{
|
|
|
|
|
|
await CheckEventPlan();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
await Task.Delay(10000);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
//执行计划(两个线程同时执行)
|
|
|
|
|
|
int threadNumber = 3;
|
|
|
|
|
|
for (int i = 0; i < threadNumber; ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
_ = Task.Run(async () => {
|
|
|
|
|
|
|
|
|
|
|
|
var rand = new Random(Guid.NewGuid().GetHashCode());
|
|
|
|
|
|
|
|
|
|
|
|
await foreach (var item in _singlePlanChannel.Reader.ReadAllAsync())
|
|
|
|
|
|
{
|
|
|
|
|
|
// 让每个线程在执行之间有不同的节奏
|
|
|
|
|
|
await Task.Delay(rand.Next(0, 300));
|
|
|
|
|
|
|
|
|
|
|
|
await ExecutePlan(item);
|
|
|
|
|
|
|
|
|
|
|
|
await Task.Delay(500);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-26 15:12:32 +08:00
|
|
|
|
await Task.CompletedTask;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//更新计划
|
|
|
|
|
|
private async Task UpdatePlans()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var list = await _webApiRequest.GetSecondaryCircuitInspectionPlanListAsync();
|
|
|
|
|
|
if (list != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
lock (_planLock)
|
|
|
|
|
|
{
|
|
|
|
|
|
var oldPlan = _planList.ToArray();
|
|
|
|
|
|
|
|
|
|
|
|
_planList.Clear();
|
|
|
|
|
|
|
|
|
|
|
|
List<SecondaryCircuitInspectionPlanStateModel> planlist = new List<SecondaryCircuitInspectionPlanStateModel>();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var item in list)
|
|
|
|
|
|
{
|
|
|
|
|
|
planlist.Add(new SecondaryCircuitInspectionPlanStateModel() { Plan = item });
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var item in planlist)
|
|
|
|
|
|
{
|
2025-10-30 12:24:29 +08:00
|
|
|
|
var plan = oldPlan.FirstOrDefault(x => x.Plan.Id == item.Plan.Id && x.Plan.ScheduledTimeString == item.Plan.ScheduledTimeString);
|
2025-10-26 15:12:32 +08:00
|
|
|
|
if (plan != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
item.ExecuteTime = plan.ExecuteTime;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_planList.Enqueue(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//获取到绑定信息,可以更新全部状态了
|
|
|
|
|
|
if (planlist.Count > 0)
|
|
|
|
|
|
_updatedPlanOk = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_updatedPlanOk = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await Task.CompletedTask;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-30 12:24:29 +08:00
|
|
|
|
//更新事件计划
|
|
|
|
|
|
private async Task UpdateEventPlans()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var list = await _webApiRequest.GetCircuitEventDrivenConfigAsync();
|
|
|
|
|
|
if (list != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
lock (_eventPlanLock)
|
|
|
|
|
|
{
|
|
|
|
|
|
_eventPlanList.Clear();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var item in list)
|
|
|
|
|
|
_eventPlanList.Enqueue(item);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//获取到绑定信息,可以更新全部状态了
|
|
|
|
|
|
if (_eventPlanList.Count > 0)
|
|
|
|
|
|
_getEventPlanListOk = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_getEventPlanListOk = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await Task.CompletedTask;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-26 15:12:32 +08:00
|
|
|
|
//检测计划,判断计划是否该执行
|
|
|
|
|
|
private async Task<bool> CheckPlan()
|
|
|
|
|
|
{
|
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (_planList == null)
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
SecondaryCircuitInspectionPlanStateModel[] planList;
|
|
|
|
|
|
lock (_planLock)
|
|
|
|
|
|
{
|
|
|
|
|
|
planList = _planList.ToArray();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DateTime now = DateTime.Now;
|
|
|
|
|
|
int week = DateTime.Now.DayOfWeek == DayOfWeek.Sunday ? 7 : (int)DateTime.Now.DayOfWeek;
|
|
|
|
|
|
|
|
|
|
|
|
if (now.Day != _planCheckDay)
|
|
|
|
|
|
{//翻天,清空已执行标记
|
|
|
|
|
|
lock (_planLock)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var item in _planList)
|
|
|
|
|
|
item.ExecuteTime = DateTime.MinValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_planCheckDay = now.Day;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var item in planList)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (item.ExecuteTime == DateTime.MinValue && item.Plan.IsActive)
|
|
|
|
|
|
{//当天未执行
|
|
|
|
|
|
if (now.Hour == item.Plan.ScheduledHour && now.Minute == item.Plan.ScheduledMinute)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (item.Plan.ScheduledWeekDaysList.IndexOf(week) != -1)
|
|
|
|
|
|
{
|
2025-10-30 12:24:29 +08:00
|
|
|
|
await PushPlanToChannel(item.Plan);
|
|
|
|
|
|
|
|
|
|
|
|
lock (_planLock)
|
|
|
|
|
|
{
|
|
|
|
|
|
item.ExecuteTime = DateTime.Now;
|
2025-10-26 15:12:32 +08:00
|
|
|
|
}
|
2025-10-30 12:24:29 +08:00
|
|
|
|
|
|
|
|
|
|
ret = true;
|
2025-10-26 15:12:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, "SecondaryCircuitInspectionPlanService - CheckPlan:发生错误");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-30 12:24:29 +08:00
|
|
|
|
//将需要执行的计划写到队列里
|
|
|
|
|
|
private async Task<bool> PushPlanToChannel(SecondaryCircuitInspectionPlanOutput plan)
|
2025-10-26 15:12:32 +08:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
bool ret = true;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var item in plan.InspectionItems)
|
|
|
|
|
|
{
|
2025-10-30 12:24:29 +08:00
|
|
|
|
string id = item.Id.ToString();
|
2025-10-26 15:12:32 +08:00
|
|
|
|
|
2025-10-30 12:24:29 +08:00
|
|
|
|
if(item.IsActive && !string.IsNullOrWhiteSpace(item.CalculationExpression) && !string.IsNullOrWhiteSpace(id))
|
|
|
|
|
|
{
|
|
|
|
|
|
//写到队列里,由队列控制执行频率
|
|
|
|
|
|
await _singlePlanChannel.Writer.WriteAsync(item);
|
2025-10-26 15:12:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, "SecondaryCircuitInspectionPlanService - ExecutePlan:发生错误");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-30 12:24:29 +08:00
|
|
|
|
//执行计划
|
|
|
|
|
|
private async Task ExecutePlan(SecondaryCircuitInspectionItemOutput item)
|
2025-10-26 15:12:32 +08:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2025-10-30 12:24:29 +08:00
|
|
|
|
string id = item.Id.ToString();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(id))
|
2025-10-26 15:12:32 +08:00
|
|
|
|
{
|
2025-10-30 12:24:29 +08:00
|
|
|
|
var engine = new Jint.Engine();
|
2025-10-26 15:12:32 +08:00
|
|
|
|
|
2025-10-30 12:24:29 +08:00
|
|
|
|
SecondaryCircuitInspectionResultModel resultModel = new SecondaryCircuitInspectionResultModel();
|
|
|
|
|
|
|
|
|
|
|
|
var task1 = GetSourceDataAsync<List<YCResultData>>(id, 1);
|
|
|
|
|
|
var task2 = GetSourceDataAsync<List<YXResultData>>(id, 2);
|
|
|
|
|
|
var task3 = GetSourceDataAsync<List<DeviceDzData>>(id, 3);
|
|
|
|
|
|
var task4 = GetSourceDataAsync<List<InspectionResultData>>(id, 4);
|
|
|
|
|
|
|
|
|
|
|
|
// 等待全部完成
|
|
|
|
|
|
await Task.WhenAll(task1, task2, task3, task4);
|
|
|
|
|
|
|
|
|
|
|
|
resultModel.TelemetryInfoData = await task1;
|
|
|
|
|
|
resultModel.TeleSignalData = await task2;
|
|
|
|
|
|
resultModel.DeviceDzData = await task3;
|
|
|
|
|
|
resultModel.InspectionResultData = await task4;
|
|
|
|
|
|
|
|
|
|
|
|
engine.Execute(item.CalculationExpression);
|
|
|
|
|
|
|
|
|
|
|
|
var result = engine.Invoke("calculate", resultModel).AsObject();
|
2025-10-26 15:12:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch(Exception ex)
|
|
|
|
|
|
{
|
2025-10-30 12:24:29 +08:00
|
|
|
|
_logger.LogError(ex, $"SecondaryCircuitInspectionPlanService 执行巡检项失败:{item.Id.ToString()}");
|
2025-10-26 15:12:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-30 12:24:29 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//获取计划数据
|
|
|
|
|
|
private async Task<T> GetSourceDataAsync<T>(string id, int type, int retryCount = 3)
|
|
|
|
|
|
{
|
|
|
|
|
|
object result = null;
|
|
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < retryCount; ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (type)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
result = await _webApiRequest.GetTelemetryInfoData(id);
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
result = await _webApiRequest.GetTeleSignalData(id);
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
result = await _webApiRequest.GetDeviceDzData(id);
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
|
|
result = await _webApiRequest.GetInspectionResultData(id);
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
throw new ArgumentException("Invalid type");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(result != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
await Task.Delay(200);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-26 15:12:32 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-10-30 12:24:29 +08:00
|
|
|
|
|
|
|
|
|
|
return (T)result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//执行事件计划
|
|
|
|
|
|
private async Task<bool> CheckEventPlan()
|
|
|
|
|
|
{
|
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (_eventPlanList == null)
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
SecondaryCircuitEventDrivenConfigOutput[] planList;
|
|
|
|
|
|
lock (_planLock)
|
|
|
|
|
|
{
|
|
|
|
|
|
planList = _eventPlanList.ToArray();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var item in planList)
|
|
|
|
|
|
{
|
|
|
|
|
|
await Task.Delay(item.DelayTriggerSeconds * 1000);
|
|
|
|
|
|
|
|
|
|
|
|
if (item.IsActive && item.SecondaryCircuitInspectionEventItems?.Count > 0 && !string.IsNullOrWhiteSpace(item.TriggerExpression))
|
|
|
|
|
|
{
|
|
|
|
|
|
string id = item.Id.ToString() ?? "";
|
|
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(id))
|
|
|
|
|
|
{
|
|
|
|
|
|
var engine = new Jint.Engine();
|
|
|
|
|
|
|
|
|
|
|
|
SecondaryCircuitInspectionResultModel resultModel = new SecondaryCircuitInspectionResultModel();
|
|
|
|
|
|
|
|
|
|
|
|
var task1 = GetSourceDataAsync<List<YCResultData>>(id, 1);
|
|
|
|
|
|
var task2 = GetSourceDataAsync<List<YXResultData>>(id, 2);
|
|
|
|
|
|
|
|
|
|
|
|
// 等待全部完成
|
|
|
|
|
|
await Task.WhenAll(task1, task2);
|
|
|
|
|
|
|
|
|
|
|
|
resultModel.TelemetryInfoData = await task1;
|
|
|
|
|
|
resultModel.TeleSignalData = await task2;
|
|
|
|
|
|
|
|
|
|
|
|
engine.Execute(item.TriggerExpression);
|
|
|
|
|
|
|
|
|
|
|
|
var canCheck = engine.Invoke("calculate", resultModel).AsBoolean();
|
|
|
|
|
|
|
|
|
|
|
|
if(canCheck)
|
|
|
|
|
|
{
|
|
|
|
|
|
await Task.Delay(item.MandatoryWaitSeconds * 1000);
|
|
|
|
|
|
|
|
|
|
|
|
CheckPlanFormIds(item.SecondaryCircuitInspectionEventItems);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, "SecondaryCircuitInspectionPlanService - CheckEventPlan:发生错误");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
2025-10-26 15:12:32 +08:00
|
|
|
|
}
|
2025-10-30 12:24:29 +08:00
|
|
|
|
|
|
|
|
|
|
//检测巡检计划中的计划
|
|
|
|
|
|
private async Task CheckPlanFormIds(List<Guid> planIds)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_planList == null)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
SecondaryCircuitInspectionPlanStateModel[] planList;
|
|
|
|
|
|
lock (_planLock)
|
|
|
|
|
|
{
|
|
|
|
|
|
planList = _planList.ToArray();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var plan in planList)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(plan.Plan.IsActive)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var item in plan.Plan.InspectionItems)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (planIds.IndexOf(item.Id) > -1 && item.IsActive)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(item.CalculationExpression) && !string.IsNullOrWhiteSpace(item.Id.ToString()))
|
|
|
|
|
|
{
|
|
|
|
|
|
//写到队列里,由队列控制执行频率
|
|
|
|
|
|
await _singlePlanChannel.Writer.WriteAsync(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, "SecondaryCircuitInspectionPlanService - CheckPlanFormIds :发生错误");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
////获取遥测数据
|
|
|
|
|
|
//public async Task<List<YCResultData>> CallYCByDataIdAsync(CallYCByDataIdRequest request, CancellationToken cancellationToken = default)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// try
|
|
|
|
|
|
// {
|
|
|
|
|
|
// using var httpClient = new HttpClient();
|
|
|
|
|
|
// string url = $"http://127.0.0.1:{_webApiSettings.Port}/api/CallYCByDataId";
|
|
|
|
|
|
// var response = await httpClient.PostAsJsonAsync(url, request);
|
|
|
|
|
|
// response.EnsureSuccessStatusCode();
|
|
|
|
|
|
// var result = await response.Content.ReadAsStringAsync();
|
|
|
|
|
|
|
|
|
|
|
|
// JObject obj = JObject.Parse(result);
|
|
|
|
|
|
// if (obj.ContainsKey("data"))
|
|
|
|
|
|
// {
|
|
|
|
|
|
// JArray jArray = obj.Value<JArray>("data");
|
|
|
|
|
|
// if (jArray != null)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// List<YCResultData> list = jArray.ToObject<List<YCResultData>>();
|
|
|
|
|
|
|
|
|
|
|
|
// return list;
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// catch(Exception ex)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// _logger.LogError(ex, "SecondaryCircuitInspectionPlanService - CallYCByDataIdAsync:发生错误");
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return null;
|
|
|
|
|
|
//}
|
2025-10-26 15:12:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|