289 lines
8.9 KiB
C#
289 lines
8.9 KiB
C#
|
|
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;
|
|||
|
|
using System.Text;
|
|||
|
|
using System.Threading;
|
|||
|
|
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;
|
|||
|
|
|
|||
|
|
namespace YunDa.Server.ISMSTcp.Services
|
|||
|
|
{
|
|||
|
|
public class WebApiSettings
|
|||
|
|
{
|
|||
|
|
public int Port { get; set; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class SecondaryCircuitInspectionPlanStateModel
|
|||
|
|
{
|
|||
|
|
//执行时间
|
|||
|
|
public DateTime ExecuteTime { get; set; } = DateTime.MinValue;
|
|||
|
|
|
|||
|
|
public SecondaryCircuitInspectionPlanOutput Plan { get; set; }
|
|||
|
|
|
|||
|
|
public SecondaryCircuitInspectionPlanStateModel()
|
|||
|
|
{
|
|||
|
|
Plan = new SecondaryCircuitInspectionPlanOutput();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//二次回路巡检计划
|
|||
|
|
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;
|
|||
|
|
|
|||
|
|
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>();
|
|||
|
|
|
|||
|
|
StartAsync();
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async Task StartAsync()
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
//更新计划
|
|||
|
|
_ = Task.Run(async () =>
|
|||
|
|
{
|
|||
|
|
while (true)
|
|||
|
|
{//每30秒更新一下配置
|
|||
|
|
|
|||
|
|
await UpdatePlans();
|
|||
|
|
|
|||
|
|
await Task.Delay(30000);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
|
|||
|
|
//执行计划
|
|||
|
|
_ = Task.Run(async () =>
|
|||
|
|
{
|
|||
|
|
while (true)
|
|||
|
|
{//每个小时,更新一下全体孪生状态
|
|||
|
|
|
|||
|
|
if (_updatedPlanOk)
|
|||
|
|
{
|
|||
|
|
await CheckPlan();
|
|||
|
|
|
|||
|
|
await Task.Delay(10 * 1000);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
await Task.Delay(10000);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
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)
|
|||
|
|
{
|
|||
|
|
var plan = oldPlan.FirstOrDefault(x => x.Plan.Name == item.Plan.Name && x.Plan.ScheduledTimeString == item.Plan.ScheduledTimeString);
|
|||
|
|
if (plan != null)
|
|||
|
|
{
|
|||
|
|
item.ExecuteTime = plan.ExecuteTime;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_planList.Enqueue(item);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//获取到绑定信息,可以更新全部状态了
|
|||
|
|
if (planlist.Count > 0)
|
|||
|
|
_updatedPlanOk = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
_updatedPlanOk = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
await Task.CompletedTask;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//检测计划,判断计划是否该执行
|
|||
|
|
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)
|
|||
|
|
{
|
|||
|
|
if (await ExecutePlan(item.Plan))
|
|||
|
|
{//执行成功
|
|||
|
|
lock (_planLock)
|
|||
|
|
{
|
|||
|
|
item.ExecuteTime = DateTime.Now;
|
|||
|
|
}
|
|||
|
|
ret = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
_logger.LogError(ex, "SecondaryCircuitInspectionPlanService - CheckPlan:发生错误");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return ret;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//执行计划
|
|||
|
|
private async Task<bool> ExecutePlan(SecondaryCircuitInspectionPlanOutput plan)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
bool ret = true;
|
|||
|
|
|
|||
|
|
var engine = new Jint.Engine();
|
|||
|
|
foreach (var item in plan.InspectionItems)
|
|||
|
|
{
|
|||
|
|
if(!string.IsNullOrWhiteSpace(item.CalculationExpression))
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
engine.Execute(item.CalculationExpression);
|
|||
|
|
|
|||
|
|
var result = engine.Invoke("calculate", new List<YCResultData>()).AsNumber();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return ret;
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
_logger.LogError(ex, "SecondaryCircuitInspectionPlanService - ExecutePlan:发生错误");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//获取遥测数据
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|