#region << 版 本 注 释 >>
|
/*----------------------------------------------------------------
|
* 命名空间:WIDESEAWCS_TaskInfoService
|
* 创建者:胡童庆
|
* 创建时间:2024/8/2 16:13:36
|
* 版本:V1.0.0
|
* 描述:
|
*
|
* ----------------------------------------------------------------
|
* 修改人:
|
* 修改时间:
|
* 版本:V1.0.1
|
* 修改说明:
|
*
|
*----------------------------------------------------------------*/
|
#endregion << 版 本 注 释 >>
|
|
using Autofac.Core;
|
using AutoMapper;
|
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.Extensions.DependencyInjection;
|
using NetTaste;
|
using Newtonsoft.Json;
|
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
|
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
|
using Quartz.Util;
|
using SqlSugar;
|
using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.Diagnostics;
|
using System.Diagnostics.CodeAnalysis;
|
using System.Linq;
|
using System.Linq.Expressions;
|
using System.Net;
|
using System.Reflection;
|
using System.Reflection.Metadata;
|
using System.Security.Claims;
|
using System.Text;
|
using System.Threading.Tasks;
|
using WIDESEA_Comm.Http;
|
using WIDESEA_Common.Log;
|
using WIDESEAWCS_Core;
|
using WIDESEAWCS_Core.BaseRepository;
|
using WIDESEAWCS_Core.BaseServices;
|
using WIDESEAWCS_Core.Enums;
|
using WIDESEAWCS_DTO.Enum;
|
using WIDESEAWCS_DTO.TaskInfo;
|
using WIDESEAWCS_ISystemServices;
|
using WIDESEAWCS_ITaskInfoRepository;
|
using WIDESEAWCS_ITaskInfoService;
|
using WIDESEAWCS_Model.Models;
|
using WIDESEAWCS_QuartzJob;
|
using WIDESEAWCS_QuartzJob.DTO;
|
using WIDESEAWCS_QuartzJob.Models;
|
using WIDESEAWCS_QuartzJob.Service;
|
|
namespace WIDESEAWCS_TaskInfoService
|
{
|
public class RgvoperainformService : ServiceBase<Dt_Task_hty, ITask_HtyRepository>, IRgvoperainformService
|
{
|
private readonly IAgvStationService _agvStationService;
|
private readonly IServiceProvider _serviceProvider;
|
private static bool _isMonitoring = false;
|
private readonly IRepository<DeviceAlarmLog> _deviceAlarmLog;
|
//private static CancellationTokenSource _cancellationTokenSource;
|
|
// 在类级别添加独立的监控状态
|
private bool _isOutboundMonitoring = false;
|
private bool _isInboundMonitoring = false;
|
private bool _isSafetyDoorMonitoring = false;
|
private bool _isPlatformMonitoring = false;
|
|
// 在类的字段区
|
private CancellationTokenSource? _platformCancellationTokenSource;
|
private CancellationTokenSource _outboundCancellationTokenSource;
|
private CancellationTokenSource _inboundCancellationTokenSource;
|
private CancellationTokenSource _safetyDoorCancellationTokenSource;
|
public RgvoperainformService(ITask_HtyRepository BaseDal, IAgvStationService agvStationService, IServiceProvider serviceProvider, IRepository<DeviceAlarmLog> deviceAlarmLog) : base(BaseDal)
|
{
|
_agvStationService = agvStationService;
|
_serviceProvider = serviceProvider;
|
_deviceAlarmLog = deviceAlarmLog;
|
}
|
|
|
//=================================================读取设备信息==========================================================
|
|
/// <summary>
|
/// 获取设备状态(支持出库、入库、安全门和站台独立监控)
|
/// </summary>
|
/// <param name="off">0:停止 1:启动 2:仅查询</param>
|
/// <param name="monitorType">监控类型:outbound-出库 inbound-入库 safetydoor-安全门 platform-站台 all-全部</param>
|
/// <returns></returns>
|
public WebResponseContent GetDeviceStatusDto(int off, string monitorType = "outbound")
|
{
|
bool isOutbound = monitorType == "outbound" || monitorType == "all";//出库
|
bool isInbound = monitorType == "inbound" || monitorType == "all";//入库
|
bool isSafetyDoor = monitorType == "safetydoor" || monitorType == "all";//安全门
|
bool isPlatform = monitorType == "platform" || monitorType == "all";//站台
|
|
if (off == 1)
|
{
|
// 启动监控
|
if (isOutbound && !_isOutboundMonitoring)
|
{
|
_isOutboundMonitoring = true;
|
_outboundCancellationTokenSource = new CancellationTokenSource();
|
_ = Task.Run(async () => await StartDeviceMonitoring(_outboundCancellationTokenSource.Token, "outbound"));
|
}
|
|
if (isInbound && !_isInboundMonitoring)
|
{
|
_isInboundMonitoring = true;
|
_inboundCancellationTokenSource = new CancellationTokenSource();
|
_ = Task.Run(async () => await StartDeviceMonitoring(_inboundCancellationTokenSource.Token, "inbound"));
|
}
|
|
if (isSafetyDoor && !_isSafetyDoorMonitoring)
|
{
|
_isSafetyDoorMonitoring = true;
|
_safetyDoorCancellationTokenSource = new CancellationTokenSource();
|
_ = Task.Run(async () => await StartDeviceMonitoring(_safetyDoorCancellationTokenSource.Token, "safetydoor"));
|
}
|
|
if (isPlatform && !_isPlatformMonitoring)
|
{
|
_isPlatformMonitoring = true;
|
_platformCancellationTokenSource = new CancellationTokenSource();
|
_ = Task.Run(async () => await StartDeviceMonitoring(_platformCancellationTokenSource.Token, "platform"));
|
}
|
|
var immediateData = GetImmediateDeviceData(monitorType);
|
string message = GetMonitorStatusMessage(monitorType);
|
return WebResponseContent.Instance.OK($"设备状态监控已启动 - {message}", immediateData);
|
}
|
else if (off == 0)
|
{
|
// 停止监控
|
if (isOutbound && _isOutboundMonitoring)
|
{
|
_isOutboundMonitoring = false;
|
_outboundCancellationTokenSource?.Cancel();
|
}
|
|
if (isInbound && _isInboundMonitoring)
|
{
|
_isInboundMonitoring = false;
|
_inboundCancellationTokenSource?.Cancel();
|
}
|
|
if (isSafetyDoor && _isSafetyDoorMonitoring)
|
{
|
_isSafetyDoorMonitoring = false;
|
_safetyDoorCancellationTokenSource?.Cancel();
|
}
|
|
if (isPlatform && _isPlatformMonitoring)
|
{
|
_isPlatformMonitoring = false;
|
_platformCancellationTokenSource?.Cancel();
|
}
|
|
var finalData = GetImmediateDeviceData(monitorType);
|
string message = GetMonitorStatusMessage(monitorType);
|
return WebResponseContent.Instance.OK($"设备状态监控已停止 - {message}", finalData);
|
}
|
else
|
{
|
// 返回当前数据
|
var currentData = GetImmediateDeviceData(monitorType);
|
string message = GetMonitorStatusMessage(monitorType);
|
return WebResponseContent.Instance.OK($"设备状态监控当前状态 - {message}", currentData);
|
}
|
}
|
|
/// <summary>
|
/// 启动设备监控
|
/// </summary>
|
/// <param name="cancellationToken"></param>
|
/// <param name="monitorType">监控类型</param>
|
/// <returns></returns>
|
private async Task StartDeviceMonitoring(CancellationToken cancellationToken, string monitorType)
|
{
|
using (var scope = _serviceProvider.CreateScope())
|
{
|
var hubContext = scope.ServiceProvider.GetRequiredService<IHubContext<DeviceStatusHub>>();
|
|
while (!cancellationToken.IsCancellationRequested)
|
{
|
try
|
{
|
// 获取指定类型的设备数据
|
var deviceData = GetImmediateDeviceData(monitorType);
|
|
// 推送数据给所有连接的客户端,带上监控类型标识
|
await hubContext.Clients.All.SendAsync("ReceiveDeviceStatusUpdate",
|
new { MonitorType = monitorType, Data = deviceData }, cancellationToken);
|
|
Console.WriteLine($"✅ {GetMonitorTypeDisplayName(monitorType)}设备数据推送完成,时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
|
// 等待30秒
|
await Task.Delay(30000, cancellationToken);
|
}
|
catch (OperationCanceledException)
|
{
|
// 监控被取消,正常退出
|
Console.WriteLine($"{GetMonitorTypeDisplayName(monitorType)}设备监控已停止");
|
break;
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine($"❌ {GetMonitorTypeDisplayName(monitorType)}设备监控异常: {ex.Message}");
|
await Task.Delay(5000, cancellationToken);
|
}
|
}
|
}
|
|
// 更新监控状态
|
switch (monitorType)
|
{
|
case "outbound":
|
_isOutboundMonitoring = false;
|
break;
|
case "inbound":
|
_isInboundMonitoring = false;
|
break;
|
case "safetydoor":
|
_isSafetyDoorMonitoring = false;
|
break;
|
case "platform":
|
_isPlatformMonitoring = false;
|
break;
|
}
|
}
|
|
/// <summary>
|
/// 获取设备数据
|
/// </summary>
|
/// <param name="monitorType">监控类型</param>
|
/// <returns></returns>
|
private Dictionary<string, Dictionary<string, int>> GetImmediateDeviceData(string monitorType = "all")
|
{
|
// 定义设备分组
|
var deviceGroups = new Dictionary<string, List<string>>
|
{
|
// 出库设备
|
["MotherCar"] = new List<string> { "RGV112", "RGV110", "RGV114", "RGV115" },
|
["TransferCar"] = new List<string> { "RGV116", "RGV111" },
|
["MaterialOut"] = new List<string> { "RGV118" },
|
|
// 入库设备
|
["InboundMotherCar"] = new List<string> { "RGV103", "RGV105", "RGV108", "RGV109" },
|
["InboundTransferCar"] = new List<string> { "RGV104", "RGV107" },
|
["MaterialIn"] = new List<string> { "RGV101" },
|
|
// 安全门设备
|
["SafetyDoor"] = new List<string> { "HCJ2000" },
|
|
// 站台设备 - 根据您提供的协议添加所有站台
|
// ["Platform"] = new List<string> {
|
// "1001", "1002", "2016", "2017", "2018", "2019", "1021", "1061", "1131", "1171"
|
//}
|
["Platform"] = new List<string> { "HCJ2000" },
|
|
};
|
|
// 设备类型对应的参数配置
|
var paramConfigs = new Dictionary<string, List<(string DeviceProParamName, string DeviceProParamType, string DeviceProRemark)>>
|
{
|
// 出库设备参数配置
|
["TransferCar"] = new List<(string, string, string)>
|
{
|
("RgvCraneAutoStatus", "RgvCraneAutoStatus", "工作模式"),
|
("RGVCurrentlocation", "RGVCurrentlocation", "当前位置"),
|
("RgvEquipmentStatus", "RgvEquipmentStatus", "有货状态"),
|
("RGV_Targetaddress", "ReadDeviceCommand", "目标地址"),
|
("RGV_Rgvtaskstutas", "RGV_Rgvtaskstutas", "任务状态"),
|
("RGV_Rgvtaskid", "ReadDeviceCommand", "RGV任务编号"),
|
("RGV_Faultcode", "ReadDeviceCommand", "故障代码"),
|
("RGV_Risingsignalplace", "ReadDeviceCommand", "上升信号到位"),
|
("RGV_Descentsignal", "ReadDeviceCommand", "下降信号到位"),
|
("RGVInitialize", "RGVInitialize", "初始化未完成标志位")
|
},
|
["MotherCar"] = new List<(string, string, string)>
|
{
|
("RgvCraneAutoStatus", "RgvCraneAutoStatus", "工作模式"),
|
("RGVCurrentlocation", "RGVCurrentlocation", "当前位置"),
|
("RgvEquipmentStatus", "RgvEquipmentStatus", "有货状态"),
|
("RGV_Targetaddress", "ReadDeviceCommand", "目标地址"),
|
("RGV_Rgvtaskstutas", "RGV_Rgvtaskstutas", "任务状态"),
|
("RGV_Rgvtaskid", "ReadDeviceCommand", "RGV任务编号"),
|
("RGV_Faultcode", "ReadDeviceCommand", "故障代码"),
|
("RGVInitialize", "RGVInitialize", "初始化未完成标志位")
|
},
|
["MaterialOut"] = new List<(string, string, string)>
|
{
|
("RgvCraneAutoStatus", "RgvCraneAutoStatus", "工作模式"),
|
("RGVCurrentlocation", "RGVCurrentlocation", "当前位置"),
|
("RgvEquipmentStatus", "RgvEquipmentStatus", "有货状态"),
|
("RGV_Targetaddress", "ReadDeviceCommand", "目标地址"),
|
("RGV_Rgvtaskstutas", "RGV_Rgvtaskstutas", "任务状态"),
|
("RGV_Rgvtaskid", "ReadDeviceCommand", "RGV任务编号"),
|
("RGV_Faultcode", "ReadDeviceCommand", "故障代码"),
|
("RGV_Risingsignalplace", "ReadDeviceCommand", "上升信号到位"),
|
("RGV_Descentsignal", "ReadDeviceCommand", "下降信号到位"),
|
("RGV_Telescopicfork", "ReadDeviceCommand", "伸缩叉伸出信号"),
|
("RGV_Retractionsignal", "ReadDeviceCommand", "伸缩叉缩回信号"),
|
("RGV_Telescopicfork", "DeviceCommand", "伸出操作"),
|
("RGVForkCurrentPosition", "RGVForkCurrentPosition", "当前位置(货叉)"),
|
("RGVInitialize", "RGVInitialize", "初始化未完成标志位")
|
},
|
|
// 入库设备参数配置
|
["MaterialIn"] = new List<(string, string, string)>
|
{
|
("RgvCraneAutoStatus", "RgvCraneAutoStatus", "工作模式"),
|
("RGVCurrentlocation", "RGVCurrentlocation", "当前位置"),
|
("RgvEquipmentStatus", "RgvEquipmentStatus", "有货状态"),
|
("RGV_Targetaddress", "ReadDeviceCommand", "目标地址"),
|
("RGV_Rgvtaskstutas", "RGV_Rgvtaskstutas", "任务状态"),
|
("RGV_Rgvtaskid", "ReadDeviceCommand", "RGV任务编号"),
|
("RGV_Faultcode", "ReadDeviceCommand", "故障代码"),
|
("RGV_Risingsignalplace", "ReadDeviceCommand", "上升信号到位"),
|
("RGV_Descentsignal", "ReadDeviceCommand", "下降信号到位"),
|
("RGV_Telescopicfork", "ReadDeviceCommand", "伸缩叉伸出信号"),
|
("RGV_Retractionsignal", "ReadDeviceCommand", "伸缩叉缩回信号"),
|
("RGV_Telescopicfork", "DeviceCommand", "伸出操作"),
|
("RGVForkCurrentPosition", "RGVForkCurrentPosition", "当前位置(货叉)"),
|
("RGVInitialize", "RGVInitialize", "初始化未完成标志位")
|
},
|
["InboundMotherCar"] = new List<(string, string, string)>
|
{
|
("RgvCraneAutoStatus", "RgvCraneAutoStatus", "工作模式"),
|
("RGVCurrentlocation", "RGVCurrentlocation", "当前位置"),
|
("RgvEquipmentStatus", "RgvEquipmentStatus", "有货状态"),
|
("RGV_Targetaddress", "ReadDeviceCommand", "目标地址"),
|
("RGV_Rgvtaskstutas", "RGV_Rgvtaskstutas", "任务状态"),
|
("RGV_Rgvtaskid", "ReadDeviceCommand", "RGV任务编号"),
|
("RGV_Faultcode", "ReadDeviceCommand", "故障代码"),
|
("RGVInitialize", "RGVInitialize", "初始化未完成标志位")
|
},
|
["InboundTransferCar"] = new List<(string, string, string)>
|
{
|
("RgvCraneAutoStatus", "RgvCraneAutoStatus", "工作模式"),
|
("RGVCurrentlocation", "RGVCurrentlocation", "当前位置"),
|
("RgvEquipmentStatus", "RgvEquipmentStatus", "有货状态"),
|
("RGV_Targetaddress", "ReadDeviceCommand", "目标地址"),
|
("RGV_Rgvtaskstutas", "RGV_Rgvtaskstutas", "任务状态"),
|
("RGV_Rgvtaskid", "ReadDeviceCommand", "RGV任务编号"),
|
("RGV_Faultcode", "ReadDeviceCommand", "故障代码"),
|
("RGV_Risingsignalplace", "ReadDeviceCommand", "上升信号到位"),
|
("RGV_Descentsignal", "ReadDeviceCommand", "下降信号到位"),
|
("RGVInitialize", "RGVInitialize", "初始化未完成标志位")
|
},
|
|
// 安全门设备参数配置
|
["SafetyDoor"] = new List<(string, string, string)>
|
{
|
("IndicatorStatus", "ReadDeviceCommand", "安全门指示灯状态"),
|
("DoorRequest", "ReadDeviceCommand", "安全门请求开门"),
|
("PowerOffStatus", "ReadDeviceCommand", "安全门断电状态"),
|
("EmergencyStopStatus", "ReadDeviceCommand", "安全门急停状态"),
|
("SafetyLockStatus", "ReadDeviceCommand", "安全门锁状态"),
|
("ResetStatus", "ReadDeviceCommand", "安全门复位状态"),
|
("AlarmSummary", "DeviceCommand", "报警信息"),
|
("OpenDoor", "DeviceCommand", "开门信息")
|
},
|
|
// 站台设备参数配置 - 根据您提供的协议添加
|
["Platform"] = new List<(string, string, string)>
|
{
|
("HCJ_GoodsStatus", "ReadDeviceCommand", "光电信号"),
|
("DoorRequest", "DeviceCommand", "任务id")
|
}
|
};
|
|
// 创建最终结果字典
|
var finalResult = new Dictionary<string, Dictionary<string, int>>();
|
|
// 根据监控类型筛选设备组
|
var filteredDeviceGroups = deviceGroups.Where(group =>
|
{
|
return monitorType switch
|
{
|
"outbound" => group.Key == "MotherCar" || group.Key == "TransferCar" || group.Key == "MaterialOut",
|
"inbound" => group.Key == "MaterialIn" || group.Key == "InboundMotherCar" || group.Key == "InboundTransferCar",
|
"safetydoor" => group.Key == "SafetyDoor",
|
"platform" => group.Key == "Platform", // 站台监控类型
|
"all" => true,
|
_ => group.Key == "MotherCar" || group.Key == "TransferCar" || group.Key == "MaterialOut"
|
};
|
}).ToDictionary(x => x.Key, x => x.Value);
|
|
// 遍历筛选后的设备组
|
foreach (var deviceGroup in filteredDeviceGroups)
|
{
|
string deviceType = deviceGroup.Key;
|
List<string> deviceCodes = deviceGroup.Value;
|
|
// 获取该设备类型的参数配置
|
if (!paramConfigs.ContainsKey(deviceType))
|
continue;
|
|
var deviceParams = paramConfigs[deviceType];
|
|
// 遍历该类型下的所有设备
|
foreach (string deviceChildCode in deviceCodes)
|
{
|
IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == deviceChildCode);
|
|
// 处理不同类型的设备
|
if (device is SpeStackerCrane commonStacker)
|
{
|
// 为当前设备创建一个字典,用于保存 DeviceProRemark 和对应的值
|
var deviceData = new Dictionary<string, int>();
|
|
// 遍历该设备的所有参数
|
foreach (var param in deviceParams)
|
{
|
try
|
{
|
DeviceProDTO? rgvResetOperation = RgvOperationService.GetRGVDeviceProDTO(
|
commonStacker, deviceChildCode, param.DeviceProParamName, param.DeviceProParamType);
|
|
if (rgvResetOperation != null)
|
{
|
int res = RgvOperationService.GetLine(commonStacker, rgvResetOperation.DeviceProAddress);
|
|
// 确保每个 DeviceProRemark 都对应正确的查询结果
|
deviceData[param.DeviceProRemark] = res;
|
}
|
else
|
{
|
deviceData[param.DeviceProRemark] = -1; // 使用 -1 表示查询失败
|
}
|
}
|
catch (Exception)
|
{
|
deviceData[param.DeviceProRemark] = -1; // 使用 -1 表示查询异常
|
}
|
}
|
|
// 将当前设备的数据添加到最终结果中
|
finalResult[deviceChildCode] = deviceData;
|
}
|
else if (device is CommonConveyorLine conveyorLine)
|
{
|
// 处理安全门设备和站台设备(CommonConveyorLine 类型)
|
if (deviceType == "SafetyDoor")
|
{
|
// 安全门设备处理逻辑(保持不变)
|
List<string> safetyDoorList = new List<string> { "AQM001", "AQM002", "AQM003" };
|
|
foreach (string safetyDoorCode in safetyDoorList)
|
{
|
var deviceData = new Dictionary<string, int>();
|
|
foreach (var param in deviceParams)
|
{
|
try
|
{
|
DeviceProDTO? devicePro = GetSafetyDoorDeviceProDTO(
|
conveyorLine, safetyDoorCode, param.DeviceProParamName, param.DeviceProParamType);
|
|
if (devicePro != null)
|
{
|
int res = ReadCommonConveyorLineData(conveyorLine, devicePro.DeviceProAddress);
|
deviceData[param.DeviceProRemark] = res;
|
}
|
else
|
{
|
deviceData[param.DeviceProRemark] = -1;
|
}
|
}
|
catch (Exception)
|
{
|
deviceData[param.DeviceProRemark] = -1;
|
}
|
}
|
|
finalResult[safetyDoorCode] = deviceData;
|
}
|
}
|
|
if (deviceType == "Platform")
|
{
|
// 安全门设备处理逻辑(保持不变)
|
List<string> PlatformList = new List<string> { "1001", "1002", "2016", "2017", "2018", "2019", "1021", "1061", "1131", "1171" };
|
|
foreach (string Platform in PlatformList)
|
{
|
var deviceData = new Dictionary<string, int>();
|
|
foreach (var param in deviceParams)
|
{
|
try
|
{
|
DeviceProDTO? devicePro = GetSafetyDoorDeviceProDTO(
|
conveyorLine, Platform, param.DeviceProParamName, param.DeviceProParamType);
|
|
if (devicePro != null)
|
{
|
int res = ReadCommonConveyorLineData(conveyorLine, devicePro.DeviceProAddress);
|
deviceData[param.DeviceProRemark] = res;
|
}
|
else
|
{
|
deviceData[param.DeviceProRemark] = -1;
|
}
|
}
|
catch (Exception)
|
{
|
deviceData[param.DeviceProRemark] = -1;
|
}
|
}
|
|
finalResult[Platform] = deviceData;
|
}
|
}
|
}
|
else
|
{
|
// 即使设备不存在或不是支持的类型,也创建一个空字典
|
finalResult[deviceChildCode] = new Dictionary<string, int>();
|
}
|
}
|
}
|
|
return finalResult;
|
}
|
|
/// <summary>
|
/// 获取监控状态消息
|
/// </summary>
|
/// <param name="monitorType"></param>
|
/// <returns></returns>
|
private string GetMonitorStatusMessage(string monitorType)
|
{
|
return monitorType switch
|
{
|
"outbound" => $"出库监控: {(_isOutboundMonitoring ? "运行中" : "已停止")}",
|
"inbound" => $"入库监控: {(_isInboundMonitoring ? "运行中" : "已停止")}",
|
"safetydoor" => $"安全门监控: {(_isSafetyDoorMonitoring ? "运行中" : "已停止")}",
|
"platform" => $"站台监控: {(_isPlatformMonitoring ? "运行中" : "已停止")}", // 站台监控状态
|
"all" => $"出库监控: {(_isOutboundMonitoring ? "运行中" : "已停止")}, 入库监控: {(_isInboundMonitoring ? "运行中" : "已停止")}, 安全门监控: {(_isSafetyDoorMonitoring ? "运行中" : "已停止")}, 站台监控: {(_isPlatformMonitoring ? "运行中" : "已停止")}",
|
_ => $"出库监控: {(_isOutboundMonitoring ? "运行中" : "已停止")}"
|
};
|
}
|
|
/// <summary>
|
/// 获取监控类型显示名称
|
/// </summary>
|
/// <param name="monitorType"></param>
|
/// <returns></returns>
|
private string GetMonitorTypeDisplayName(string monitorType)
|
{
|
return monitorType switch
|
{
|
"outbound" => "出库",
|
"inbound" => "入库",
|
"safetydoor" => "安全门",
|
"platform" => "站台", // 站台显示名称
|
"all" => "全部",
|
_ => "出库"
|
};
|
}
|
|
/// <summary>
|
/// 读取设备信息
|
/// </summary>
|
/// <param name="conveyorLine"></param>
|
/// <param name="DeviceProDataBlock"></param>
|
/// <returns></returns>
|
public static int ReadCommonConveyorLineData(CommonConveyorLine Commonstacker, string DeviceProDataBlock)
|
{
|
return Commonstacker.Communicator.Read<short>(DeviceProDataBlock);
|
}
|
|
/// <summary>
|
/// 查询安全门设备
|
/// </summary>
|
/// <param name="Commonstacker"></param>
|
/// <param name="SCAddress"></param>
|
/// <param name="Interactivet"></param>
|
/// <returns></returns>
|
public static DeviceProDTO? GetSafetyDoorDeviceProDTO(CommonConveyorLine Commonstacker, string SCAddress, string DeviceProParamName, string DeviceProParamType)
|
{
|
return Commonstacker.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == SCAddress && x.DeviceProParamName == DeviceProParamName && x.DeviceProParamType == DeviceProParamType);
|
}
|
|
/// <summary>
|
/// 查询站台设备
|
/// </summary>
|
/// <param name="Commonstacker"></param>
|
/// <param name="PlatformCode">站台编号</param>
|
/// <param name="DeviceProParamName">参数名称</param>
|
/// <param name="DeviceProParamType">参数类型</param>
|
/// <returns></returns>
|
public static DeviceProDTO? GetPlatformDeviceProDTO(CommonConveyorLine Commonstacker, string PlatformCode, string DeviceProParamName, string DeviceProParamType)
|
{
|
return Commonstacker.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == PlatformCode && x.DeviceProParamName == DeviceProParamName && x.DeviceProParamType == DeviceProParamType);
|
}
|
|
//=================================================读取设备信息==========================================================
|
|
|
#region 设备信息
|
/***
|
/// <summary>
|
/// 查询RGV设备
|
/// </summary>
|
/// <param name="Commonstacker"></param>
|
/// <param name="SCAddress"></param>
|
/// <param name="Interactivet"></param>
|
/// <returns></returns>
|
public static DeviceProDTO? GetRGVDeviceProDTO(SpeStackerCrane Commonstacker, string SCAddress, string DeviceProParamName, string DeviceProParamType)
|
{
|
return Commonstacker.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == SCAddress && x.DeviceProParamName == DeviceProParamName && x.DeviceProParamType == DeviceProParamType);
|
}
|
/// <summary>
|
/// 读取设备信息
|
/// </summary>
|
/// <param name="conveyorLine"></param>
|
/// <param name="DeviceProDataBlock"></param>
|
/// <returns></returns>
|
public static int GetLine(SpeStackerCrane Commonstacker, string DeviceProDataBlock)
|
{
|
return Commonstacker.Communicator.Read<short>(DeviceProDataBlock);
|
}
|
|
/// <summary>
|
/// 写入设备信息
|
/// </summary>
|
/// <param name="conveyorLine"></param>
|
/// <param name="DeviceProDataBlock"></param>
|
/// <returns></returns>
|
public static bool RgvSetLine(SpeStackerCrane Commonstacker, string DeviceProDataBlock, short rgvvalues)
|
{
|
return Commonstacker.Communicator.Write<short>(DeviceProDataBlock, rgvvalues);
|
}
|
*/
|
#endregion
|
|
|
/// <summary>
|
/// 设备操作
|
/// </summary>
|
/// <param name="deviceName"></param>
|
/// <param name="operationType"></param>
|
/// <param name="parameter"></param>
|
/// <returns></returns>
|
/// <exception cref="NotImplementedException"></exception>
|
public WebResponseContent DeviceOperation(string deviceName, string operationType, int parameter)
|
{
|
WebResponseContent webResponse = new WebResponseContent();
|
IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == deviceName);
|
if (device == null) return webResponse.Error("未找到此设备");
|
SpeStackerCrane Commonstacker = (SpeStackerCrane)device;
|
string DeviceProParamName = null;
|
string DeviceProParamType = null;
|
int zhi = 1002011;
|
try
|
{
|
|
switch (operationType)
|
{
|
case "cs": //初始化
|
//获取实例
|
DeviceProDTO? RGV_RGVtasktypetcs = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, deviceName, "RGV_RGVtasktypet", "DeviceCommand"); //任务类型 //第一步写入任务
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_RGVtasktypetcs.DeviceProAddress, (short)3);
|
//写入自动
|
DeviceProDTO? RGV_DWorkingmodecs = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, deviceName, "RGV_DWorkingmode", "DeviceCommand"); //任务id
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_DWorkingmodecs.DeviceProAddress, (short)1);
|
//写入清除任务
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_RGVtasktypetcs.DeviceProAddress, (short)4);
|
|
//反馈确认任务
|
DeviceProDTO? RGV_taskcompletecs = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, deviceName, "RGV_taskcomplete", "RGV_taskcomplete"); //任务id
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_taskcompletecs.DeviceProAddress, (short)1);
|
DeviceProParamName = "RGV_Resetoperation";
|
DeviceProParamType = "DeviceCommand";
|
zhi = 1;
|
break;
|
case "sd": //手动
|
DeviceProParamName = "RGV_DWorkingmode";
|
DeviceProParamType = "DeviceCommand";
|
zhi = 0;
|
break;
|
case "zd": //自动
|
DeviceProParamName = "RGV_DWorkingmode";
|
DeviceProParamType = "DeviceCommand";
|
zhi = 1;
|
break;
|
case "ss": //上升
|
DeviceProParamName = "RGV_Risingsignalplace";
|
DeviceProParamType = "DeviceCommand";
|
zhi = parameter;
|
DeviceProDTO? RGV_Resetoperationss1 = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, deviceName, DeviceProParamName, DeviceProParamType); //上升
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_Resetoperationss1.DeviceProAddress, (short)zhi);
|
//DeviceProDTO? RGV_Resetoperationss2 = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, deviceName, "RGV_Risingsignalplace", "ReadDeviceCommand"); //上升到位信号
|
// int resss = 0;
|
// while (resss == 0)
|
// {
|
// Thread.Sleep(2000);
|
// resss = RgvOperationService.GetLine(Commonstacker, RGV_Resetoperationss2.DeviceProAddress);
|
// }
|
// DeviceProDTO? RGV_Resetoperationss3 = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, deviceName, DeviceProParamName, DeviceProParamType); //上升
|
// RgvOperationService.RgvSetLine(Commonstacker, RGV_Resetoperationss3.DeviceProAddress, 0);
|
return webResponse.OK();
|
|
case "xj": //下降
|
DeviceProParamName = "RGV_Descentsignal";
|
DeviceProParamType = "DeviceCommand";
|
zhi = parameter;
|
DeviceProDTO? RGV_Resetoperationxj1 = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, deviceName, DeviceProParamName, DeviceProParamType); //下降
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_Resetoperationxj1.DeviceProAddress, (short)zhi);
|
//DeviceProDTO? RGV_Resetoperationxj2 = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, deviceName, "RGV_Descentsignal", "ReadDeviceCommand"); //下降到位信号
|
//int resxj = 0;
|
//while (resxj == 0)
|
//{
|
// Thread.Sleep(2000);
|
// resxj = RgvOperationService.GetLine(Commonstacker, RGV_Resetoperationxj2.DeviceProAddress);
|
//}
|
//DeviceProDTO? RGV_Resetoperationxj3 = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, deviceName, DeviceProParamName, DeviceProParamType); //上升
|
//RgvOperationService.RgvSetLine(Commonstacker, RGV_Resetoperationxj3.DeviceProAddress, 0);
|
return webResponse.OK();
|
case "dz": //地址
|
|
if (!YiDongPD(Commonstacker, parameter)) { return webResponse.Error("目标地址被占用或条件不满足,禁止移动"); }
|
DeviceProParamName = "RGV_RGVTasklocationt";
|
DeviceProParamType = "DeviceCommand";
|
zhi = parameter;
|
//获取实例
|
DeviceProDTO? RGV_RGVtasktypet = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, deviceName, "RGV_RGVtasktypet", "DeviceCommand"); //任务类型
|
//第一步写入任务
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_RGVtasktypet.DeviceProAddress, (short)3);
|
|
//写入自动
|
DeviceProDTO? RGV_DWorkingmode = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, deviceName, "RGV_Rgvtaskidt", "DeviceCommand"); //任务id
|
//任务id
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_DWorkingmode.DeviceProAddress, (short)30001);
|
|
//任务id
|
DeviceProDTO? RGV_taskcomplete = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, deviceName, "RGV_Lanjiantaskidt", "DeviceCommand"); //任务id
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_taskcomplete.DeviceProAddress, (short)30001);
|
break;
|
case "sc": //伸出
|
//DeviceProParamName = "RGV_DWorkingmode";
|
//DeviceProParamType = "DeviceCommand";
|
//zhi = 1;
|
break;
|
case "sh": //缩回
|
//DeviceProParamName = "RGV_Retractionsignal";
|
//DeviceProParamType = "DeviceCommand";
|
//zhi = 1;
|
break;
|
case "kld": //开雷达
|
DeviceProParamName = "RGV_Shieldradar";
|
DeviceProParamType = "DeviceCommand";
|
zhi = 1;
|
break;
|
case "gld": //关雷达
|
DeviceProParamName = "RGV_Shieldradar";
|
DeviceProParamType = "DeviceCommand";
|
zhi = 0;
|
break;
|
case "fw":
|
DeviceProParamName = "RGV_Resetoperation";
|
DeviceProParamType = "DeviceCommand";
|
zhi = 1;
|
break;
|
}
|
|
//获取需要复位的设备
|
DeviceProDTO? RGV_Resetoperation = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, deviceName, DeviceProParamName, DeviceProParamType); //复位报警信息
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_Resetoperation.DeviceProAddress,(short)zhi);
|
return webResponse.OK("设备操作成功");
|
}catch(Exception)
|
{
|
return webResponse.Error("设备操作失败");
|
}
|
|
}
|
|
/// <summary>
|
/// 1、判断子车区域
|
/// 2、判断子车当前位置
|
/// 3、判断子车要去的位置
|
/// 4、根据子车要去的为获取母车位置
|
///
|
/// </summary>
|
/// <param name="device">要移动的设备</param>
|
/// <param name="parameter">要去的目标地址</param>
|
/// <returns></returns>
|
|
private bool YiDongPD(SpeStackerCrane Commonstacker, int parameter)
|
{
|
|
//入库设备
|
List<string> InDevices = new List<string> { "RGV104", "RGV107" };
|
//出库设备
|
List<string> OutDevices = new List<string> {"RGV116", "RGV111"};
|
|
Dictionary<int, string> HCJ = new Dictionary<int, string>
|
{
|
{ 1061, "HCJ106" },
|
{ 1021, "HCJ102" },
|
{ 1131, "HCJ113" },
|
{ 1171, "HCJ117" },
|
};
|
|
AGVStation RGVTaskdevice = _agvStationService.Corridorequipment(Commonstacker.DeviceCode); //根据设备获取到内容
|
|
//根据子车获取到母车设备
|
// 根据子车获取到母车设备
|
AGVStation Mu1 = _agvStationService.GetMothervehicle(RGVTaskdevice.MotherCarDeviceCode);
|
AGVStation Mu2 = _agvStationService.GetMothervehicle(RGVTaskdevice.MotherCardeputy);
|
|
// 获取子车位置
|
int zhicheWZ = GetzicheWZ(Commonstacker, Commonstacker.DeviceCode);
|
|
// 统一目标占用检查(扫描其它 RGV 是否在同一目标地址)
|
bool IsAddressOccupied(int addr)
|
{
|
var allCodes = InDevices.Concat(OutDevices).Where(code => code != Commonstacker.DeviceCode).ToList();
|
foreach (var code in allCodes)
|
{
|
var dev = Storage.Devices.FirstOrDefault(x => x.DeviceCode == code) as SpeStackerCrane;
|
if (dev == null) continue;
|
try
|
{
|
DeviceProDTO? locDto = RgvOperationService.GetRGVDeviceProDTO(dev, code, "RGVCurrentlocation", "RGVCurrentlocation");
|
if (locDto == null) continue;
|
int loc = RgvOperationService.GetLine(dev, locDto.DeviceProAddress);
|
if (loc == addr) return true; // 目标被占用
|
}
|
catch
|
{
|
// 读取异常不当作占用,避免误拒
|
}
|
}
|
return false;
|
}
|
|
// 目标被其他 RGV 占用则禁止
|
if (IsAddressOccupied(parameter)) return false;
|
|
if (RGVTaskdevice.Station_Area == 6) // 外侧
|
{
|
if (zhicheWZ == RGVTaskdevice.WaitmomentOne) // 等待点1
|
{
|
// 判断外侧小车是否在 HCJ 上
|
var zichestation = _agvStationService.OutGetZicheDeepHCJ(RGVTaskdevice.HCJStorageaddress);
|
int waiziche = GetEquipmentlocation(zichestation.ChildPosiDeviceCode);
|
|
//判断传进来设备是否是入库
|
if (InDevices.Contains(Commonstacker.DeviceCode))
|
{
|
if (!((waiziche == zichestation.WaitmomentOne || waiziche == zichestation.WaitmomentTwo || waiziche == zichestation.MotherCardeputy || waiziche == zichestation.MotherCarDeviceCode || waiziche == 1021) && waiziche != zichestation.HCJStorageaddress))
|
{
|
return false;
|
}
|
}
|
else
|
{
|
if (!((waiziche == zichestation.WaitmomentOne || waiziche == zichestation.WaitmomentTwo || waiziche == zichestation.MotherCardeputy || waiziche == zichestation.MotherCarDeviceCode || waiziche == 1171) && waiziche != zichestation.HCJStorageaddress))
|
{
|
return false;
|
}
|
}
|
|
if (parameter == Mu1.ZicheMotherinlaw) //母1
|
{
|
int taraddress = parameter;
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode))//判断是否有货
|
{
|
if (mu1 == Mu1.ZicheMotherinlaw && mu1 != Mu1.Motherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else if (parameter == Mu2.ZicheMotherinlaw) // 母2
|
{
|
int taraddress = parameter;
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
int mu2 = GetEquipmentlocation(Mu2.ChildPosiDeviceCode);
|
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode) && Mucheywhaddres(Mu2.ChildPosiDeviceCode))//判断是否有货
|
{
|
if (mu1 == Mu1.Motherinlaw && mu1 != Mu1.ZicheMotherinlaw && mu2 == Mu2.ZicheMotherinlaw && mu2 != Mu2.Motherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else if (parameter == RGVTaskdevice.HCJStorageaddress)
|
{
|
string hcj = HCJ[RGVTaskdevice.HCJStorageaddress];
|
int mu2 = GetEquipmentlocation(Mu2.ChildPosiDeviceCode);
|
|
if (Mucheywhaddres(Mu2.ChildPosiDeviceCode) && Mucheywhaddres(hcj))//判断是否有货
|
{
|
if (mu2 != Mu2.ZicheMotherinlaw && mu2 == Mu2.Motherinlaw && !IsAddressOccupied(Mu2.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}else if(parameter == 1021 || parameter == 1171)
|
{
|
if (RGVTaskdevice.ChildPosiDeviceCode == "RGV116" && Mucheywhaddres("HCJ102"))
|
{
|
return true;
|
}
|
string hcj = HCJ[parameter];
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode) && Mucheywhaddres(hcj))//判断是否有货
|
{
|
if (mu1 != Mu1.ZicheMotherinlaw && mu1 == Mu1.Motherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
int taraddress = parameter;
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
int mu2 = GetEquipmentlocation(Mu2.ChildPosiDeviceCode);
|
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode) && Mucheywhaddres(Mu2.ChildPosiDeviceCode))//判断是否有货
|
{
|
if (mu1 == Mu1.Motherinlaw && mu1 != Mu1.ZicheMotherinlaw && mu2 == Mu2.Motherinlaw && mu2 != Mu2.ZicheMotherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
|
}
|
}
|
}
|
else if (zhicheWZ == RGVTaskdevice.WaitmomentTwo) // 等待点2
|
{
|
// 判断外侧小车是否在 HCJ 上
|
var zichestation = _agvStationService.OutGetZicheDeepHCJ(RGVTaskdevice.HCJStorageaddress);
|
int waiziche = GetEquipmentlocation(zichestation.ChildPosiDeviceCode);
|
|
//判断传进来设备是否是入库
|
if (InDevices.Contains(Commonstacker.DeviceCode))
|
{
|
if (!((waiziche == zichestation.WaitmomentOne || waiziche == zichestation.WaitmomentTwo || waiziche == zichestation.MotherCardeputy || waiziche == zichestation.MotherCarDeviceCode || waiziche == 1021) && waiziche != zichestation.HCJStorageaddress))
|
{
|
return false;
|
}
|
}
|
else
|
{
|
if (!((waiziche == zichestation.WaitmomentOne || waiziche == zichestation.WaitmomentTwo || waiziche == zichestation.MotherCardeputy || waiziche == zichestation.MotherCarDeviceCode || waiziche == 1171) && waiziche != zichestation.HCJStorageaddress))
|
{
|
return false;
|
}
|
}
|
|
if (parameter == Mu1.ZicheMotherinlaw)
|
{
|
int taraddress = parameter;
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode))//判断是否有货
|
{
|
if (mu1 == Mu1.ZicheMotherinlaw && mu1 != Mu1.Motherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else if (parameter == Mu2.ZicheMotherinlaw)
|
{
|
int taraddress = parameter;
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
int mu2 = GetEquipmentlocation(Mu2.ChildPosiDeviceCode);
|
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode) && Mucheywhaddres(Mu2.ChildPosiDeviceCode))//判断是否有货
|
{
|
if (mu1 == Mu1.Motherinlaw && mu1 != Mu1.ZicheMotherinlaw && mu2 == Mu2.ZicheMotherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else if (parameter == RGVTaskdevice.HCJStorageaddress)
|
{
|
string hcj = HCJ[RGVTaskdevice.HCJStorageaddress];
|
int mu2 = GetEquipmentlocation(Mu2.ChildPosiDeviceCode);
|
|
if (Mucheywhaddres(Mu2.ChildPosiDeviceCode) && Mucheywhaddres(hcj))//判断是否有货
|
{
|
if (mu2 != Mu2.ZicheMotherinlaw && mu2 == Mu2.Motherinlaw && !IsAddressOccupied(Mu2.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else if (parameter == 1021 || parameter == 1171)
|
{
|
string hcj = HCJ[parameter];
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
int mu2 = GetEquipmentlocation(Mu2.ChildPosiDeviceCode);
|
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode) && Mucheywhaddres(Mu2.ChildPosiDeviceCode) && Mucheywhaddres(hcj))//判断是否有货
|
{
|
if (mu1 != Mu1.ZicheMotherinlaw && mu1 == Mu1.Motherinlaw && mu2 != Mu2.ZicheMotherinlaw && mu2 == Mu2.Motherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
int taraddress = parameter;
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
int mu2 = GetEquipmentlocation(Mu2.ChildPosiDeviceCode);
|
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode) && Mucheywhaddres(Mu2.ChildPosiDeviceCode))//判断是否有货
|
{
|
if (mu1 == Mu1.Motherinlaw && mu1 != Mu1.ZicheMotherinlaw && mu2 == Mu2.Motherinlaw && mu2 != Mu2.ZicheMotherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
|
}
|
}
|
}
|
}
|
else if (RGVTaskdevice.Station_Area == 5) // 内侧
|
{
|
if (zhicheWZ == RGVTaskdevice.WaitmomentOne) // 等待点1
|
{
|
// 判断外侧小车是否在 HCJ 上
|
var zichestation = _agvStationService.OutGetZicheDeepHCJ(RGVTaskdevice.HCJStorageaddress);
|
int waiziche = GetEquipmentlocation(zichestation.ChildPosiDeviceCode);
|
|
//判断传进来设备是否是入库
|
if (InDevices.Contains(Commonstacker.DeviceCode))
|
{
|
if (!((waiziche == zichestation.WaitmomentOne || waiziche == zichestation.WaitmomentTwo || waiziche == zichestation.MotherCardeputy || waiziche == zichestation.MotherCarDeviceCode || waiziche == 1021) && waiziche != zichestation.HCJStorageaddress))
|
{
|
return false;
|
}
|
}
|
else
|
{
|
if (!((waiziche == zichestation.WaitmomentOne || waiziche == zichestation.WaitmomentTwo || waiziche == zichestation.MotherCardeputy || waiziche == zichestation.MotherCarDeviceCode || waiziche == 1171) && waiziche != zichestation.HCJStorageaddress))
|
{
|
return false;
|
}
|
}
|
|
if (parameter == Mu1.ZicheMotherinlaw) //母1
|
{
|
int taraddress = parameter;
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode))//判断是否有货
|
{
|
if (mu1 == Mu1.ZicheMotherinlaw && mu1 != Mu1.Motherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else if (parameter == Mu2.ZicheMotherinlaw) // 母2
|
{
|
int taraddress = parameter;
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
int mu2 = GetEquipmentlocation(Mu2.ChildPosiDeviceCode);
|
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode) && Mucheywhaddres(Mu2.ChildPosiDeviceCode))//判断是否有货
|
{
|
if (mu1 == Mu1.Motherinlaw && mu1 != Mu1.ZicheMotherinlaw && mu2 == Mu2.ZicheMotherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}else if (parameter == RGVTaskdevice.HCJStorageaddress)
|
{
|
string hcj = HCJ[RGVTaskdevice.HCJStorageaddress];
|
if (Mucheywhaddres(hcj))
|
{
|
return true;
|
}
|
}
|
else
|
{
|
int taraddress = parameter;
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
int mu2 = GetEquipmentlocation(Mu2.ChildPosiDeviceCode);
|
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode) && Mucheywhaddres(Mu2.ChildPosiDeviceCode))//判断是否有货
|
{
|
if (mu1 == Mu1.Motherinlaw && mu1 != Mu1.ZicheMotherinlaw && mu2 == Mu2.Motherinlaw && mu2 != Mu2.ZicheMotherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
|
}
|
}
|
}
|
else if (zhicheWZ == RGVTaskdevice.WaitmomentTwo) // 等待点2
|
{
|
// 判断外侧小车是否在 HCJ 上
|
var zichestation = _agvStationService.OutGetZicheDeepHCJ(RGVTaskdevice.HCJStorageaddress);
|
int waiziche = GetEquipmentlocation(zichestation.ChildPosiDeviceCode);
|
|
//判断传进来设备是否是入库
|
if (InDevices.Contains(Commonstacker.DeviceCode))
|
{
|
if (!((waiziche == zichestation.WaitmomentOne || waiziche == zichestation.WaitmomentTwo || waiziche == zichestation.MotherCardeputy || waiziche == zichestation.MotherCarDeviceCode || waiziche == 1021) && waiziche != zichestation.HCJStorageaddress))
|
{
|
return false;
|
}
|
}
|
else
|
{
|
if (!((waiziche == zichestation.WaitmomentOne || waiziche == zichestation.WaitmomentTwo || waiziche == zichestation.MotherCardeputy || waiziche == zichestation.MotherCarDeviceCode || waiziche == 1171) && waiziche != zichestation.HCJStorageaddress))
|
{
|
return false;
|
}
|
}
|
|
if (parameter == Mu1.ZicheMotherinlaw)
|
{
|
int taraddress = parameter;
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode))//判断是否有货
|
{
|
if (mu1 == Mu1.ZicheMotherinlaw && mu1 != Mu1.Motherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else if (parameter == Mu2.ZicheMotherinlaw)
|
{
|
int taraddress = parameter;
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
int mu2 = GetEquipmentlocation(Mu2.ChildPosiDeviceCode);
|
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode) && Mucheywhaddres(Mu2.ChildPosiDeviceCode))//判断是否有货
|
{
|
if (mu1 == Mu1.Motherinlaw && mu1 != Mu1.ZicheMotherinlaw && mu2 == Mu2.ZicheMotherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else if (parameter == RGVTaskdevice.HCJStorageaddress)
|
{
|
string hcj = HCJ[RGVTaskdevice.HCJStorageaddress];
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode)&&Mucheywhaddres(hcj))//判断是否有货
|
{
|
if (mu1 != Mu1.ZicheMotherinlaw && mu1 == Mu1.Motherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
int taraddress = parameter;
|
int mu1 = GetEquipmentlocation(Mu1.ChildPosiDeviceCode);
|
int mu2 = GetEquipmentlocation(Mu2.ChildPosiDeviceCode);
|
|
if (Mucheywhaddres(Mu1.ChildPosiDeviceCode) && Mucheywhaddres(Mu2.ChildPosiDeviceCode))//判断是否有货
|
{
|
if (mu1 == Mu1.Motherinlaw && mu1 != Mu1.ZicheMotherinlaw && mu2 == Mu2.Motherinlaw && mu2 != Mu2.ZicheMotherinlaw && !IsAddressOccupied(Mu1.ZicheMotherinlaw))
|
{
|
return true;
|
}
|
else
|
{
|
return false;
|
}
|
}
|
else
|
{
|
return false;
|
|
}
|
}
|
}
|
}
|
|
// 默认:未被拦截且目标未占用 -> 放行
|
return true;
|
|
}
|
|
/// <summary>
|
/// 传入设备,返回当前设备信息
|
/// </summary>
|
/// <param name="ChildPosiDeviceCode">设备</param>
|
/// <returns></returns>
|
public static int GetEquipmentInformation(string ChildPosiDeviceCode)
|
{
|
IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == ChildPosiDeviceCode);
|
SpeStackerCrane speStackerCrane = (SpeStackerCrane)device;
|
if (speStackerCrane == null)
|
{
|
Console.WriteLine($"读取到设备为空,设备编号:{ChildPosiDeviceCode},003");
|
return 0;
|
}
|
DeviceProDTO? deviceProDTOGZMS = speStackerCrane.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == ChildPosiDeviceCode && x.DeviceProParamName == "RgvCraneAutoStatus" && x.DeviceProParamType == "RgvCraneAutoStatus");
|
int GZMS = RGVGetLine(speStackerCrane, deviceProDTOGZMS.DeviceProAddress);
|
|
DeviceProDTO? deviceProDTORWZT = speStackerCrane.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == ChildPosiDeviceCode && x.DeviceProParamName == "RGV_Rgvtaskstutas" && x.DeviceProParamType == "RGV_Rgvtaskstutas");
|
int RWZT = RGVGetLine(speStackerCrane, deviceProDTORWZT.DeviceProAddress);
|
|
DeviceProDTO? deviceProDTOBJGC = speStackerCrane.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == ChildPosiDeviceCode && x.DeviceProParamName == "RGVStepprocess" && x.DeviceProParamType == "RGVStepprocess");
|
int BJGC = RGVGetLine(speStackerCrane, deviceProDTOBJGC.DeviceProAddress);
|
|
DeviceProDTO? deviceProDTOWZ = speStackerCrane.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == ChildPosiDeviceCode && x.DeviceProParamName == "RGVCurrentlocation" && x.DeviceProParamType == "RGVCurrentlocation");
|
int WZ = RGVGetLine(speStackerCrane, deviceProDTOWZ.DeviceProAddress);
|
|
|
if (GZMS == 1 && RWZT == 0 && BJGC == 0)
|
{
|
return WZ;
|
}
|
else
|
{
|
return 0;
|
}
|
|
}
|
|
public static bool Mucheywhaddres(string DeviceCode)
|
{
|
IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == DeviceCode);
|
SpeStackerCrane Commonstacker = (SpeStackerCrane)device;
|
|
DeviceProDTO? deviceProDTO = Commonstacker.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == DeviceCode && x.DeviceProParamName == "RgvEquipmentStatus" && x.DeviceProParamType == "RgvEquipmentStatus");
|
int MCGStatus = RGVGetLine(Commonstacker, deviceProDTO.DeviceProAddress);
|
if (MCGStatus == (int)RgvEquipmentStatus.NoCargo)
|
{
|
return true;
|
}
|
return false;
|
}
|
|
/// <summary>
|
/// RGV设备状态
|
/// </summary>
|
public enum RgvEquipmentStatus
|
{
|
/// <summary>
|
/// 无货
|
/// </summary>
|
[Description("无货")]
|
NoCargo,
|
/// <summary>
|
/// 有货
|
/// </summary>
|
[Description("有货")]
|
HasCargo,
|
/// <summary>
|
/// 未知
|
/// </summary>
|
[Description("未知")]
|
Unkonw = 6
|
|
}
|
|
/// <summary>
|
/// 传入设备,获取当前位置位置
|
/// </summary>
|
/// <param name="ChildPosiDeviceCode">设备</param>
|
/// <returns></returns>
|
public static int GetEquipmentlocation(string ChildPosiDeviceCode)
|
{
|
IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == ChildPosiDeviceCode);
|
SpeStackerCrane speStackerCrane = (SpeStackerCrane)device;
|
if (speStackerCrane == null) return 0;
|
DeviceProDTO? deviceProDTO = speStackerCrane.DeviceProDTOs.FirstOrDefault(x => x.DeviceChildCode == ChildPosiDeviceCode && x.DeviceProParamName == "RGVCurrentlocation" && x.DeviceProParamType == "RGVCurrentlocation");
|
int MCGStatus = RGVGetLine(speStackerCrane, deviceProDTO.DeviceProAddress);
|
return MCGStatus;
|
}
|
|
public static int RGVGetLine(SpeStackerCrane Commonstacker, string DeviceProDataBlock)
|
{
|
return Commonstacker.Communicator.Read<short>(DeviceProDataBlock);
|
}
|
|
/// <summary>
|
/// 获取到子车位置
|
/// </summary>
|
/// <param name="commonstacker"></param>
|
/// <param name="deviceCode"></param>
|
/// <returns></returns>
|
|
private int GetzicheWZ(SpeStackerCrane commonstacker, string deviceCode)
|
{
|
DeviceProDTO? RGVCurrentlocation = RgvOperationService.GetRGVDeviceProDTO(commonstacker, commonstacker.DeviceCode, "RGVCurrentlocation", "RGVCurrentlocation");
|
return RgvOperationService.GetLine(commonstacker, RGVCurrentlocation.DeviceProAddress);
|
}
|
|
|
/// <summary>
|
/// 一键操作
|
/// </summary>
|
/// <param name="monitorType"></param>
|
/// <param name="operationType"></param>
|
/// <returns></returns>
|
/// <exception cref="NotImplementedException"></exception>
|
public WebResponseContent OneClickOperation(string monitorType, string operationType)
|
{
|
WebResponseContent webResponse = new WebResponseContent();
|
List<string> Devices = new List<string>();
|
if (monitorType == "Inbound")
|
{
|
//入库设备
|
Devices = new List<string> { "RGV103", "RGV105", "RGV108", "RGV109", "RGV104", "RGV107", "RGV101" };
|
}
|
else if (monitorType == "Outbound")
|
{
|
//出库设备
|
Devices = new List<string> { "RGV112", "RGV110", "RGV114", "RGV115", "RGV116", "RGV111", "RGV118" };
|
}
|
try
|
{
|
List<IDevice?> devices = Storage.Devices.Where(x => Devices.Contains(x.DeviceCode)).Cast<IDevice?>().ToList();
|
if (devices == null || !devices.Any())
|
{
|
return webResponse.Error("未找到相关设备");
|
}
|
string DeviceProParamName = null;
|
string DeviceProParamType = null;
|
int zhi = 1002011;
|
switch (operationType)
|
{
|
case "init": //初始化
|
DeviceProParamName = "RGV_Resetoperation";
|
DeviceProParamType = "DeviceCommand";
|
zhi = 1;
|
break;
|
case "reset":
|
DeviceProParamName = "RGV_Resetoperation";
|
DeviceProParamType = "DeviceCommand";
|
zhi = 1;
|
break;
|
case "start":
|
DeviceProParamName = "RGV_DWorkingmode";
|
DeviceProParamType = "DeviceCommand";
|
zhi = 1;
|
break;
|
case "stop":
|
DeviceProParamName = "RGV_DWorkingmode";
|
DeviceProParamType = "DeviceCommand";
|
zhi = 0;
|
break;
|
}
|
foreach(var device in devices)
|
{
|
SpeStackerCrane Commonstacker = (SpeStackerCrane)device;
|
|
if (operationType == "init")
|
{
|
//获取实例
|
DeviceProDTO? RGV_RGVtasktypetcs = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, device.DeviceCode, "RGV_RGVtasktypet", "DeviceCommand"); //任务类型 //第一步写入任务
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_RGVtasktypetcs.DeviceProAddress, (short)3);
|
//写入自动
|
DeviceProDTO? RGV_DWorkingmodecs = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, device.DeviceCode, "RGV_DWorkingmode", "DeviceCommand"); //任务id
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_DWorkingmodecs.DeviceProAddress, (short)1);
|
//写入清除任务
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_RGVtasktypetcs.DeviceProAddress, (short)4);
|
|
//反馈确认任务
|
DeviceProDTO? RGV_taskcompletecs = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, device.DeviceCode, "RGV_taskcomplete", "RGV_taskcomplete"); //任务id
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_taskcompletecs.DeviceProAddress, (short)1);
|
}
|
DeviceProDTO? RGV_Resetoperation = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, device.DeviceCode, DeviceProParamName, DeviceProParamType); //复位报警信息
|
RgvOperationService.RgvSetLine(Commonstacker, RGV_Resetoperation.DeviceProAddress, (short)zhi);
|
}
|
return webResponse.OK("设备操作成功");
|
}catch(Exception)
|
{
|
return webResponse.Error("设备操作失败");
|
}
|
}
|
|
/// <summary>
|
/// 查看报警
|
/// </summary>
|
public WebResponseContent LogAlarmToDatabase(string JobDeviceName)
|
{
|
// 设备分类 - 合并版本
|
var deviceCategories = new Dictionary<string, List<string>>
|
{
|
["MotherCar"] = new List<string> { "RGV112", "RGV110", "RGV114", "RGV115", "RGV103", "RGV105", "RGV108", "RGV109" },
|
["TransferCar"] = new List<string> { "RGV116", "RGV111", "RGV104", "RGV107" },
|
["ExternalRGV"] = new List<string> { "RGV118", "RGV101" }
|
};
|
|
WebResponseContent webResponse = new WebResponseContent();
|
string DeviceName = JobDeviceName; //设备名称
|
IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == DeviceName);
|
if (device == null) return webResponse.Error();
|
SpeStackerCrane Commonstacker = (SpeStackerCrane)device;
|
DeviceProDTO? RGV_Resetoperation = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, DeviceName, "RGV_Faultcode", "ReadDeviceCommand");
|
DeviceProDTO? RGVCurrentlocation = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, DeviceName, "RGVCurrentlocation", "RGVCurrentlocation");
|
DeviceProDTO? RGV_Rgvtaskid = RgvOperationService.GetRGVDeviceProDTO(Commonstacker, DeviceName, "RGV_Rgvtaskid", "ReadDeviceCommand");
|
|
|
int baoj = RgvOperationService.GetLine(Commonstacker, RGV_Resetoperation.DeviceProAddress);
|
|
if (baoj<=0)
|
{
|
return null;
|
}
|
int Currentlocation = RgvOperationService.GetLine(Commonstacker, RGVCurrentlocation.DeviceProAddress);
|
int Rgvtaskid = RgvOperationService.GetLine(Commonstacker, RGV_Rgvtaskid.DeviceProAddress);
|
|
string alarmMessage = "";
|
if (deviceCategories["MotherCar"].Contains(DeviceName))
|
{
|
// 母车专用报警处理逻辑
|
alarmMessage = HandleMotherCarAlarm(baoj);
|
}
|
else if (deviceCategories["TransferCar"].Contains(DeviceName))
|
{
|
// 子车专用报警处理逻辑
|
alarmMessage = HandleTransferCarAlarm(baoj);
|
}
|
else if (deviceCategories["ExternalRGV"].Contains(DeviceName))
|
{
|
// 外口RGV专用报警处理逻辑
|
alarmMessage = HandleExternalRGVAlarm(baoj);
|
}
|
|
// 写入文本日志(按设备分组/按日切分)
|
var logContent = $"设备:{DeviceName} | 报警码:{baoj} | 报警描述:{alarmMessage} | 当前位置:{Currentlocation} | 任务号:{Rgvtaskid}";
|
// groupName: Alarm,logName: 设备名
|
WriteLog.Write_Log("Alarm", DeviceName, logContent, new
|
{
|
DeviceCode = DeviceName,
|
AlarmCode = baoj,
|
AlarmContent = alarmMessage,
|
DeviceLocation = Currentlocation,
|
TaskNum = Rgvtaskid,
|
Time = DateTime.Now
|
});
|
return webResponse.OK();
|
}
|
|
|
// 报警代码映射方法
|
private string HandleExternalRGVAlarm(int alarmCode)
|
{
|
var alarmMessages = new Dictionary<int, string>
|
{
|
{0, "无报警"},
|
{1, "RGV小车急停被按下"},
|
{2, "正转雷达报警"},
|
{3, "反转雷达报警"},
|
{4, "前进限位报警"},
|
{5, "后退限位报警"},
|
{6, ""},
|
{7, "PLC模块故障"},
|
{8, "PLC扩展模块故障"},
|
{9, "称重模块故障"},
|
{10, "扫码定位故障"},
|
{11, "RGV长时间空转故障"},
|
{12, "目的地不等于实际位置故障"},
|
{13, "与总控通讯故障"},
|
{14, "前雷达屏蔽警告"},
|
{15, "后雷达屏蔽警告"},
|
{16, "行走变频器故障"},
|
{17, "伸缩叉变频器故障"},
|
{18, "液压单元过载保护故障"},
|
{19, "液压上升超时报警"},
|
{20, "液压下降超时报警"},
|
{21, "伸缩叉伸出超时报警"},
|
{22, "伸缩叉缩回超时报警"},
|
{23, "外形检测报警"},
|
{24, "称重超重报警"},
|
{25, "货叉伸出极限限位报警"},
|
{26, "货叉缩回极限限位报警"},
|
{27, "取货时自身有货物报警"},
|
{28, "放货时自身无货物报警"},
|
{29, "货叉未回到初始位报警"},
|
{30, "触发仅移动命令时货叉不在初始位报警"},
|
{31, "货叉到达初始位但中位传感器未检测到报警"},
|
{32, "行走轴没到位禁止货叉伸出"},
|
{33, "取货异常报警"},
|
{34, "放货异常报警"},
|
{35, "外型检测-前超出报警"},
|
{36, "外型检测-后超出报警"},
|
{37, "外型检测-左超出报警"},
|
{38, "外型检测-右超出报警"},
|
{39, "外型检测-上超出报警"}
|
};
|
|
return alarmMessages.ContainsKey(alarmCode) ? alarmMessages[alarmCode] : "未知报警代码";
|
}
|
|
|
private string HandleTransferCarAlarm(int alarmCode)
|
{
|
var alarmMessages = new Dictionary<int, string>
|
{
|
{0, "无报警"},
|
{1, "RGV小车急停被按下"},
|
{2, "前进限位报警"},
|
{3, "后退限位报警"},
|
{4, "PLC摸块故障"},
|
{5, "PLC扩展模块故障"},
|
{6, "扫码定位故障"},
|
{7, "RGV长时间空转故障"},
|
{8, "目的地不等于实际位置故障"},
|
{9, "与总控通讯故障"},
|
{10, "行走变频器故障"},
|
{11, "液压单元过载保护故障"},
|
{12, "液压上升超时报警"},
|
{13, "液压下降超时报警"},
|
{14, "取货时自身有货物报警"},
|
{15, "放货时自身无货物报警"},
|
{16, "取货检测不到货物报警"}
|
};
|
|
return alarmMessages.ContainsKey(alarmCode) ? alarmMessages[alarmCode] : "未知报警代码";
|
}
|
|
private string HandleMotherCarAlarm(int alarmCode)
|
{
|
var alarmMessages = new Dictionary<int, string>
|
{
|
{0, "无报警"},
|
{1, "RGV小车急停被按下"},
|
{2, "前进限位报警"},
|
{3, "后退限位报警"},
|
{4, "PLC摸块故障"},
|
{5, "PLC扩展模块故障"},
|
{6, "RGV长时间空转故障"},
|
{7, "目的地不等于实际位置故障"},
|
{8, "与总控通讯故障"},
|
{9, "行走变频器故障"},
|
{10, "取货时自身有货物报警"},
|
{11, "放货时自身无货物报警"},
|
{12, "停止时位置过冲报警"}
|
};
|
|
return alarmMessages.ContainsKey(alarmCode) ? alarmMessages[alarmCode] : "未知报警代码";
|
}
|
}
|
}
|
|