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 _ids = new ConcurrentDictionary(); 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 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 _logger; private readonly ZzTcpService _zTcpService = null; private ZzDataIdList _ycIds = new ZzDataIdList(); public ZzDataCmdService( ILogger 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 GetValidZzCmd(string cmdName, List ids) { const int maxLength = 25000; var cmds = new List(); // 开始构建 string prefix = cmdName + "|"; // 固定前缀 int prefixLength = prefix.Length; var currentIds = new List(); 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); } } }