259 lines
10 KiB
C#
259 lines
10 KiB
C#
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}");
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|