using Abp.Dependency; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ToolLibrary.LogHelper; using YunDa.ISAS.Redis.Repositories; using YunDa.SOMS.Commdb.Models; using Yunda.SOMS.DataMonitoringServer.FTPHandle; using Yunda.SOMS.DataMonitoringServer.TcpSocket.Server; using YunDa.SOMS.DataTransferObject.GeneralInformation.ProtectionDeviceInfoDto; using Yunda.ISAS.DataMonitoringServer.DataAnalysis; using System.IO; using StackExchange.Redis; using Yunda.ISAS.DataMonitoringServer.DataCenter; using YunDa.SOMS.DataTransferObject.MainStationMaintenanceInfo.OperationReport; using System.Windows.Interop; using FluentFTP; using System.Collections; using System.Collections.Concurrent; using Yunda.SOMS.DataMonitoringServer.SQLiteData; using Abp; using YunDa.SOMS.DataTransferObject.CommonDto; namespace Yunda.SOMS.DataMonitoringServer.ProtectionDeviceHandle { public class ProtectionDeviceRunInfoHandle : ISingletonDependency { WebApiRequest _webApiRequest; FtpFile _ftpFile; DotNettyTcpServer _dotNettyTcpServer; private readonly RedisDataRepository _redisDataRepository; private readonly IRedisRepository _deviceBoardStatesRedis; public ProtectionDeviceRunInfoHandle( FtpFile ftpFile, DotNettyTcpServer dotNettyTcpServer, IRedisRepository redisRepository, WebApiRequest webApiRequest, RedisDataRepository redisDataRepository ) { _webApiRequest = webApiRequest; _ftpFile = ftpFile; _dotNettyTcpServer = dotNettyTcpServer; _redisDataRepository = redisDataRepository; _dotNettyTcpServer.MessageReceived += OnMessageReceived; // 订阅事件 _deviceBoardStatesRedis = redisRepository; } //Dictionary _deviceRunStates = new Dictionary(); //private ConcurrentDictionary _communicationStateCounts = new(); int _commCount = 0; private void OnMessageReceived(byte address, byte[] message, byte functionType) { try { if (functionType == 6) //通信状态 { var device = ProtectionDeviceDataCenter._devices.FirstOrDefault(t => t.DeviceAddr == address); if (device != null) { UpdateDeviceBoardState(address, message, device); if (_commCount == 0) { SendEquipmentInfoRemainingLifeAssessment(device); var bytes = _ftpFile.GetFileFromFtpToMem(device.GatewayIP1, "/nor/root/status/", "status.txt"); if (bytes != null) { var data = ParseDeviceStatusFromBytes(bytes); if (data != null) { data.ProtectionDeviceId = device.ProtectionDeviceId; data.EquipmentInfoId = device.EquipmentInfoId; data.EquipmentInfoName = device.EquipmentInfoName; string redisKey = _redisDataRepository.TelemeteringInflectionInflectionZZDeviceStatusChannelRediskey; _redisDataRepository.DeviceStatusRedis.PublishAsync(redisKey, data); } } } } _commCount++; if (_commCount == 10) { _commCount = 0; } } } catch (Exception ex) { Log4Helper.Error(this.GetType(), "初始化装置IO错误", ex); } } private async Task SendEquipmentInfoRemainingLifeAssessment(ProtectionDeviceCommInfoOutput device) { try { var data = _webApiRequest.GetEquipmentInfoRemainingLifeAssessment(device.EquipmentInfoId); string redisChannel = "equipmentInfoRemainingLifeAssessmentChannel"; await _redisDataRepository.EquipmentInfoRemainingLifeAssessmentRedis.PublishAsync(redisChannel, data); } catch (Exception ex) { } } /// /// 格式化FTP数据 /// /// /// private DeviceStatus ParseDeviceStatusFromBytes(byte[] data) { var deviceStatus = new DeviceStatus(); try { var networkInterfaces = new List(); string content = System.Text.Encoding.UTF8.GetString(data); string[] lines = content.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); NetworkInterfaceStatus currentInterface = null; foreach (var line in lines) { var parts = line.Split(':', 2); if (parts.Length < 2) continue; string key = parts[0].Trim(); string value = parts[1].Trim(); switch (key) { case "使用内存": deviceStatus.UsedMemory = value; break; case "空闲内存": deviceStatus.FreeMemory = value; break; case "总磁盘": deviceStatus.TotalDisk = value; break; case "使用磁盘": deviceStatus.UsedDisk = value; break; case "104连接状态": deviceStatus.ConnectionStatus104 = int.Parse(value); break; case "液晶操作密码": deviceStatus.LcdOperationPassword = value; break; default: if (key.StartsWith("网口")) { string[] netParts = key.Split(new[] { "网口", "IP", "状态", "速率", "累计时间", "起始时间", "发生帧数", "发送错误帧数", "接收帧数", "接收错误帧数" }, StringSplitOptions.RemoveEmptyEntries); if (netParts.Length > 0) { string interfaceName = netParts[0]; if (currentInterface == null || currentInterface.InterfaceName != interfaceName) { currentInterface = new NetworkInterfaceStatus { InterfaceName = interfaceName }; networkInterfaces.Add(currentInterface); } if (key.EndsWith("IP")) currentInterface.IpAddress = value; if (key.EndsWith("状态")) currentInterface.Status = value; if (key.EndsWith("速率")) currentInterface.Speed = value; if (key.EndsWith("累计时间")) currentInterface.CumulativeTime = int.Parse(value.Replace("s", "").Trim()); if (key.EndsWith("起始时间")) currentInterface.StartTime = value; if (key.EndsWith("发生帧数")) currentInterface.SentFrames = int.Parse(value); if (key.EndsWith("发送错误帧数")) currentInterface.SentErrorFrames = int.Parse(value); if (key.EndsWith("接收帧数")) currentInterface.ReceivedFrames = int.Parse(value); if (key.EndsWith("接收错误帧数")) currentInterface.ReceivedErrorFrames = int.Parse(value); } } break; } } deviceStatus.NetworkInterfaces = networkInterfaces; } catch (Exception ex) { MonitoringEventBus.LogHandler(ex.Message, "格式化FTP数据"); } return deviceStatus; } private void UpdateDeviceBoardState(byte address, byte[] data, ProtectionDeviceCommInfoOutput device) { if (!_deviceBoardStates.TryGetValue(address, out var boardStates)) { boardStates = iopositions.Select(item => new NameIntValueProperty(item.Name, item.Value)).ToList(); _deviceBoardStates[address] = boardStates; } boardStates[0].Value = new BitArray(new byte[] { data[0] })[0] ? 0 : 1;//运行状态 boardStates[1].Value = new BitArray(new byte[] { data[0] })[1] ? 0 : 1;//报警状态 boardStates[7].Value = new BitArray(new byte[] { data[1] })[7] ? 0 : 1; // 液晶状态 BitArray bit2 = new BitArray(new byte[] { data[2] }); boardStates[2].Value = bit2[0] ? 0 : 1; boardStates[3].Value = bit2[1] ? 0 : 1; boardStates[4].Value = bit2[2] ? 0 : 1; boardStates[5].Value = bit2[3] ? 0 : 1; boardStates[6].Value = bit2[4] ? 0 : 1; DeviceBoardStates deviceBoardStates = new DeviceBoardStates() { EquipmentInfoId = device.EquipmentInfoId, EquipmentInfoName = device.EquipmentInfoName, States = boardStates, Time = DateTime.Now, }; _deviceBoardStatesRedis.HashSetUpdateOneAsync(deviceBoardStatesRedisKey, address.ToString(), deviceBoardStates); _deviceBoardStatesRedis.PublishAsync(deviceBoardStatesRedisChannelKey, deviceBoardStates); } string deviceBoardStatesRedisKey = "deviceBoardStates"; string deviceBoardStatesRedisChannelKey = "deviceBoardStatesChannel"; ConcurrentDictionary> _deviceBoardStates = new(); List iopositions = new List { new NameIntValueProperty("运行", 0), new NameIntValueProperty("告警", 0), new NameIntValueProperty("IO插件1", 0), new NameIntValueProperty("IO插件2", 0), new NameIntValueProperty("IO插件3", 0), new NameIntValueProperty("IO插件4", 0), new NameIntValueProperty("电源插件(IO5)", 0), new NameIntValueProperty("液晶", 0) }; } // 定义设备信息类 class DeviceInfo { public bool Status { get; set; } // 设备状态(运行或离线) public DateTime LastUpdate { get; set; } // 最后更新时间 public int OfflineCount { get; set; } // 连续离线计数 } }