251 lines
7.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
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.Configurations;
namespace YunDa.Server.ISMSTcp.Services
{
public class YcIdExInfo
{
public string Id { get; set; } = string.Empty;
public string DeviceId { get; set; } = string.Empty;
public bool DeviceCommState { get; set; } = true;
public YcIdExInfo(string id)
{
Id = id;
}
}
public class ZzDataIdList
{
private ConcurrentDictionary<string, YcIdExInfo> _ids = new ConcurrentDictionary<string, YcIdExInfo>();
public void Clear()
{
_ids.Clear();
}
public bool AddId(string id)
{
return _ids.TryAdd(id, new YcIdExInfo(id));
}
public void AddIds(string ids, string keyword, string separator)
{
if (string.IsNullOrWhiteSpace(ids))
return;
string[] list = ids.Trim().Split(separator);
foreach (string id in list)
{
if(string.IsNullOrWhiteSpace(id))
continue;
if(id.Contains(keyword))
_ids.TryAdd(id, new YcIdExInfo(id));
}
}
public void UpdateDeviceCommState(string deviceId, bool commState)
{
foreach (var yc in _ids.Values)
{
if (yc.Id.Contains(deviceId))
{
yc.DeviceCommState = commState;
}
}
}
public List<string> GetIds(bool? commState)
{
if(commState.HasValue)
return _ids.Where(kvp => kvp.Value.DeviceCommState == commState)
.Select(kvp => kvp.Key)
.ToList();
else
return _ids.Keys.ToList();
}
}
public class ZzDataCmdService
{
private readonly ILogger<ZzDataCmdService> _logger;
private readonly ZzTcpService _zTcpService = null;
private ZzDataIdList _ycIds = new ZzDataIdList();
public ZzDataCmdService(
ILogger<ZzDataCmdService> logger,
ZzTcpService zTcpService)
{
_logger = logger;
_zTcpService = zTcpService;
StartAsync();
}
private async Task StartAsync()
{
await AppInit.WaitAsync(AppInit.DefaultTimeOut);
_ = Task.Run(async () =>
{
while (true)
{//每秒发送一次遥测命令只发送用到的id
await SendYcCmd();
await Task.Delay(TimeSpan.FromSeconds(1));
}
});
//暂时屏蔽发送虚点命令,不然李老师那边会卡
//_ = Task.Run(async () =>
//{
// while (true)
// {//每30秒发送一次虚点命令全体
// await SendVaCmd();
// await Task.Delay(TimeSpan.FromSeconds(30));
// }
//});
}
private List<string> GetValidZzCmd(string cmdName, List<string> ids)
{
const int maxLength = 25000;
var cmds = new List<string>();
// 开始构建
string prefix = cmdName + "|"; // 固定前缀
int prefixLength = prefix.Length;
var currentIds = new List<string>();
int currentLength = prefixLength; // 当前命令的长度(含前缀)
foreach (var id in ids)
{
// 如果添加这个ID会超长则先生成一个命令
int idLength = (currentIds.Count == 0 ? id.Length : (1 + id.Length)); // 第一个ID不需要 '#'
if (currentLength + idLength > maxLength)
{
// 将当前批次加入 cmds
cmds.Add(prefix + string.Join("#", currentIds));
// 清空并重建
currentIds.Clear();
currentLength = prefixLength;
}
// 添加新的 ID
currentIds.Add(id);
currentLength += idLength;
}
// 收尾:如果还有剩余 IDs生成最后一个命令
if (currentIds.Count > 0)
{
cmds.Add(prefix + string.Join("#", currentIds));
}
return cmds;
}
//更新装置状态
public void UpdateDeviceCommState(string deviceId, bool commState)
{
_ycIds.UpdateDeviceCommState(deviceId, commState);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////遥测
public void ClearYcIds()
{
_ycIds.Clear();
}
//计划巡检配置
public void AddCircuitPlanYcIds(SecondaryCircuitInspectionPlanStateModel[] planList)
{
foreach (var plan in planList)
{
foreach(var inspection in plan.Plan.InspectionItems)
{
foreach (var item in inspection.TelemetryConfigs)
{
if(!string.IsNullOrWhiteSpace(item.TelemetryConfigurationIsmsId) && item.TelemetryConfigurationIsmsId.StartsWith("YC"))
_ycIds.AddId(item.TelemetryConfigurationIsmsId);
}
}
}
}
//事件巡检配置
public void AddEventPlanYcIds(SecondaryCircuitEventDrivenConfigOutput[] planList)
{
foreach (var plan in planList)
{
foreach(var item in plan.TelemetryConfigs)
{
if (!string.IsNullOrWhiteSpace(item.TelemetryConfigurationIsmsId) && item.TelemetryConfigurationIsmsId.StartsWith("YC"))
_ycIds.AddId(item.TelemetryConfigurationIsmsId);
}
foreach (var inspection in plan.SecondaryCircuitInspectionEventItems)
{
foreach (var item in inspection.TelemetryConfigs)
{
if (!string.IsNullOrWhiteSpace(item.TelemetryConfigurationIsmsId) && item.TelemetryConfigurationIsmsId.StartsWith("YC"))
_ycIds.AddId(item.TelemetryConfigurationIsmsId);
}
}
}
}
private int _sendCnt = 0;
private async Task SendYcCmd()
{
var ids = _ycIds.GetIds(null);
var cmds = GetValidZzCmd("CallYCByDataID", ids);
foreach (var cmd in cmds)
{
await _zTcpService.SendTcpMessageAsync(cmd, CancellationToken.None);
if(_sendCnt % 60 == 0)
_logger.LogWarning($"发送命令:{ids.Count}个id");
_sendCnt++;
}
}
private async Task SendVaCmd()
{
string cmd = "CallVAByStat|B001";
await _zTcpService.SendTcpMessageAsync(cmd, CancellationToken.None);
}
}
}