2024-12-06 16:32:13 +08:00

259 lines
10 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.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
using ToolLibrary.LogHelper;
using Yunda.ISAS.DataMonitoringServer.DataAnalysis;
using Yunda.SOMS.DataMonitoringServer.TcpSocket.Server;
using YunDa.ISAS.Redis.Repositories;
using YunDa.SOMS.DataTransferObject.GeneralInformation.ProtectionDeviceInfoDto;
namespace Yunda.SOMS.DataMonitoringServer.ProtectionDeviceHandle
{
public class ProtectionDeviceDataCenter: ISingletonDependency
{
public static List<ProtectionDeviceCommInfoOutput> _devices;
WebApiRequest _webApiRequest;
ProtectionDeviceDZDataHandle _protectionDeviceDZDataHandle;
ProtectionDeviceVersionHandle _protectionDeviceVersionHandle;
ProtectionDeviceIOInfoHandle _protectionDeviceIOInfoHandle;
ProtectionDeviceRunInfoHandle _protectionDeviceRunInfoHandle;
ProtectionDeviceSelfCheckHandle _protectionDeviceSelfCheckHandle;
ProtectionDeviceBCodeHandle _protectionDeviceBCodeHandle;
IRedisRepository<int[], string> _deviceBoardStatesRedis;
DotNettyTcpServer _dotNettyTcpServer;
string deviceBoardStatesRedisKey = "deviceBoardStates";
ConcurrentBag<Process> _processes = new ConcurrentBag<Process>();
public ProtectionDeviceDataCenter(WebApiRequest webApiRequest
, ProtectionDeviceDZDataHandle protectionDeviceDZDataHandle
, ProtectionDeviceVersionHandle protectionDeviceVersionHandle
, ProtectionDeviceIOInfoHandle protectionDeviceIOInfoHandle
, DotNettyTcpServer dotNettyTcpServer
, ProtectionDeviceSelfCheckHandle protectionDeviceSelfCheckHandle
, ProtectionDeviceRunInfoHandle protectionDeviceRunInfoHandle
,ProtectionDeviceBCodeHandle protectionDeviceBCodeHandle
, IRedisRepository<int[], string> deviceBoardStatesRedis
)
{
_webApiRequest = webApiRequest;
_protectionDeviceDZDataHandle = protectionDeviceDZDataHandle;
_protectionDeviceVersionHandle = protectionDeviceVersionHandle;
_protectionDeviceIOInfoHandle = protectionDeviceIOInfoHandle;
_dotNettyTcpServer = dotNettyTcpServer;
_protectionDeviceRunInfoHandle = protectionDeviceRunInfoHandle;
_deviceBoardStatesRedis = deviceBoardStatesRedis;
_protectionDeviceSelfCheckHandle = protectionDeviceSelfCheckHandle;
}
public void InitDevices()
{
try
{
_devices = _webApiRequest.GetProtectionDeviceCommInfos("神池南");
}
catch (Exception ex)
{
Log4Helper.Error(this.GetType(), "初始化装置IO错误", ex);
}
}
public List<ProtectionDeviceCommInfoOutput> ProtectionDeviceComms { get; set; }
public async Task InitProtectionDeviceComms()
{
MonitoringEventBus.LogHandler("开始启动103客户端", "装置定值");
await Task.Run(async () =>
{
List<ProtectionDeviceCommInfoOutput> devices = _webApiRequest.GetProtectionDeviceCommInfos("神池南");
if (devices == null)
{
MonitoringEventBus.LogHandler("没有获取到装置数据", "获取信息");
return;
}
_protectionDeviceDZDataHandle.Init(devices);
MonitoringEventBus.LogHandler($"共获取{devices.Count}条装置数据", "装置定值");
string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;
string sourceDirectory = Path.Combine(currentDirectory, "DeviceComm");
string destDirectoryBase = Path.Combine(currentDirectory, "DeviceComms", "DeviceComm");
// 定义一个并行处理每个设备的过程
Parallel.ForEach(devices, device =>
{
try
{
var online = IsDeviceOnline(device.GatewayIP1);
if (online)
{
string destDirectory = $"{destDirectoryBase}_{device.DeviceAddr}";
CopyDirectory(sourceDirectory, destDirectory);
string configFilePath = Path.Combine(destDirectory, "cfg", "scmgateway.ini");
ModifyDeviceAddrInConfig(configFilePath, device.GatewayIP1, device.DeviceAddr);
string exePath = Path.Combine(destDirectory, "scmgateway.exe");
var process = StartExe(exePath);
if (process != null)
{
MonitoringEventBus.LogHandler($"装置地址:{device.DeviceAddr}ip:{device.GatewayIP1} 启动成功", "装置定值");
_processes.Add(process);
}
}
else
{
MonitoringEventBus.LogHandler($"装置地址:{device.DeviceAddr}ip:{device.GatewayIP1} {(online ? "线" : "线")}", "装置定值");
}
}
catch (Exception ex)
{
MonitoringEventBus.LogHandler($"{ex.Message}", "错误信息");
}
});
MonitoringEventBus.LogHandler("开始启动TCP服务端", "装置定值");
await _dotNettyTcpServer.RunServerAsync();
});
}
Process StartExe(string exePath)
{
try
{
var process = new Process
{
StartInfo = new ProcessStartInfo
{
WorkingDirectory = Path.GetDirectoryName(exePath), // 设置工作目录为exe所在目录
FileName = exePath,
CreateNoWindow = true,
UseShellExecute = false
}
};
process.Start();
return process;
}
catch (Exception ex)
{
MonitoringEventBus.LogHandler($"启动 {exePath} 失败: {ex.Message}", "错误信息");
return null;
}
}
public void StopAllProcesses()
{
foreach (var process in _processes)
{
try
{
if (!process.HasExited)
{
process.Kill();
process.WaitForExit();
}
}
catch (Exception ex)
{
MonitoringEventBus.LogHandler($"停止进程失败: {ex.Message}", "错误信息");
}
}
}
// 通过 Ping 判断设备是否在线
private bool IsDeviceOnline(string ipAddress)
{
try
{
if (ipAddress == "127.0.0.1"|| ipAddress == "localhost")
{
return false;
}
using (Ping ping = new Ping())
{
// 发送 Ping 请求,设置超时时间为 1000 毫秒 (1秒)
PingReply reply = ping.Send(ipAddress, 1000);
// 如果状态是成功,则设备在线
return reply.Status == IPStatus.Success;
}
}
catch (PingException)
{
// 如果发生异常,设备不可达(例如网络断开)
return false;
}
}
private void CopyDirectory(string sourceDir, string destDir)
{
var dir = new DirectoryInfo(sourceDir);
if (!dir.Exists)
{
throw new DirectoryNotFoundException($"源目录不存在或无法找到: {sourceDir}");
}
if (Directory.Exists(destDir))
{
//如果目标目录存在,则直接跳过复制
return;
}
DirectoryInfo[] dirs = dir.GetDirectories();
Directory.CreateDirectory(destDir);
foreach (FileInfo file in dir.GetFiles())
{
string targetFilePath = Path.Combine(destDir, file.Name);
file.CopyTo(targetFilePath, true);
}
foreach (DirectoryInfo subDir in dirs)
{
string newDestinationDir = Path.Combine(destDir, subDir.Name);
CopyDirectory(subDir.FullName, newDestinationDir);
}
}
private void ModifyDeviceAddrInConfig(string configFilePath, string gatewayIP1,int protectAddr)
{
if (File.Exists(configFilePath))
{
var lines = File.ReadAllLines(configFilePath);
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].StartsWith("[Device]"))
{
for (int j = i + 1; j < lines.Length; j++)
{
if (lines[j].StartsWith("deviceAddr="))
{
lines[j] = $"deviceAddr={gatewayIP1}";
}
if (lines[j].StartsWith("protectAddr="))
{
lines[j] = $"protectAddr={protectAddr}";
}
}
break;
}
}
File.WriteAllLines(configFilePath, lines);
}
else
{
Debug.WriteLine($"文件未找到: {configFilePath}");
}
}
}
}