2024-12-09 11:05:15 +08:00

244 lines
11 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 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<DeviceBoardStates, string> _deviceBoardStatesRedis;
public ProtectionDeviceRunInfoHandle(
FtpFile ftpFile,
DotNettyTcpServer dotNettyTcpServer,
IRedisRepository<DeviceBoardStates, string> redisRepository,
WebApiRequest webApiRequest,
RedisDataRepository redisDataRepository
)
{
_webApiRequest = webApiRequest;
_ftpFile = ftpFile;
_dotNettyTcpServer = dotNettyTcpServer;
_redisDataRepository = redisDataRepository;
_dotNettyTcpServer.MessageReceived += OnMessageReceived; // 订阅事件
_deviceBoardStatesRedis = redisRepository;
}
//Dictionary<byte, DeviceInfo> _deviceRunStates = new Dictionary<byte, DeviceInfo>();
//private ConcurrentDictionary<byte, int> _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)
{
}
}
/// <summary>
/// 格式化FTP数据
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private DeviceStatus ParseDeviceStatusFromBytes(byte[] data)
{
var deviceStatus = new DeviceStatus();
try
{
var networkInterfaces = new List<NetworkInterfaceStatus>();
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<byte, List<NameIntValueProperty>> _deviceBoardStates = new();
List<NameIntValueProperty> iopositions = new List<NameIntValueProperty>
{
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; } // 连续离线计数
}
}