251 lines
7.5 KiB
C#
Raw Normal View History

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);
}
}
}