1135 lines
52 KiB
C#
Raw Normal View History

2025-03-10 18:15:27 +08:00
using Abp.Authorization;
2024-07-15 10:31:26 +08:00
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
2025-04-16 13:53:07 +08:00
using Abp.Web.Mvc.Alerts;
2025-03-10 18:15:27 +08:00
using Google.Protobuf;
using Microsoft.AspNetCore.Http;
2024-07-15 10:31:26 +08:00
using Microsoft.AspNetCore.Mvc;
2025-03-10 18:15:27 +08:00
using Microsoft.AspNetCore.Mvc.ModelBinding;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
using NPOI.SS.Formula.Functions;
2024-07-15 10:31:26 +08:00
using System;
using System.Collections.Generic;
using System.ComponentModel;
2025-03-10 18:15:27 +08:00
using System.Globalization;
2024-11-26 13:45:28 +08:00
using System.IO;
2024-07-15 10:31:26 +08:00
using System.Linq;
using System.Linq.Dynamic.Core;
2025-03-10 18:15:27 +08:00
using System.Text;
2024-11-26 13:45:28 +08:00
using System.Text.Json;
2024-07-15 10:31:26 +08:00
using System.Threading.Tasks;
using ToolLibrary.LogHelper;
using YunDa.ISAS.Application.Core;
2025-03-10 18:15:27 +08:00
using YunDa.ISAS.Application.Core.Configuration;
2024-07-15 10:31:26 +08:00
using YunDa.ISAS.Application.Core.Session;
using YunDa.ISAS.Application.Core.SwaggerHelper;
2025-04-16 13:53:07 +08:00
using YunDa.ISAS.Core.Helper;
2024-07-15 10:31:26 +08:00
using YunDa.ISAS.DataTransferObject;
using YunDa.ISAS.DataTransferObject.Account;
using YunDa.ISAS.DataTransferObject.EquipmentLiveData;
using YunDa.ISAS.DataTransferObject.GeneralInformation.EquipmentInfoDto;
using YunDa.ISAS.DataTransferObject.GeneralInformation.EquipmentInfoDto.SearchCondition;
2025-04-16 13:53:07 +08:00
using YunDa.ISAS.DataTransferObject.VideoSurveillance.VideoDevDto;
2024-07-15 10:31:26 +08:00
using YunDa.ISAS.Entities.ClientConfiguration.ThreeDimension;
using YunDa.ISAS.Entities.DataMonitoring;
using YunDa.ISAS.Entities.GeneralInformation;
using YunDa.ISAS.Entities.MySQL.DataMonitoring;
using YunDa.ISAS.Entities.VideoSurveillance;
2025-03-10 18:15:27 +08:00
using YunDa.ISAS.MongoDB.Repositories;
using YunDa.ISAS.Redis.Entities.AlarmCategory;
2024-07-15 10:31:26 +08:00
using YunDa.ISAS.Redis.Repositories;
2025-04-16 13:53:07 +08:00
using YunDa.SOMS.DataTransferObject.AlarmDataDto;
2024-11-26 13:45:28 +08:00
using YunDa.SOMS.DataTransferObject.EquipmentLiveData;
2025-03-10 18:15:27 +08:00
using YunDa.SOMS.DataTransferObject.MainStationMaintenanceInfo.OperationReport;
2024-11-26 13:45:28 +08:00
using YunDa.SOMS.DataTransferObject.ThirdPartyData.NJJW;
2025-04-16 13:53:07 +08:00
using YunDa.SOMS.Entities.GeneralInformation;
using ZstdSharp.Unsafe;
2024-11-26 13:45:28 +08:00
using JsonSerializer = System.Text.Json.JsonSerializer;
2024-07-15 10:31:26 +08:00
namespace YunDa.ISAS.Application.GeneralInformation
{
/// <summary>
2025-04-16 13:53:07 +08:00
/// 设备信息
2024-07-15 10:31:26 +08:00
/// </summary>
[Description("设备信息管理服务")]
public class EquipmentLiveDataAppService : ISASAppServiceBase, IEquipmentLiveDataAppService
{
private LoginUserOutput _currentUser;
private readonly IRepository<EquipmentInfo, Guid> _equipmentInfoRepository;
private readonly IRepository<VideoDev, Guid> _videoDevRepository;
private readonly IRepository<LinkageStrategy, Guid> _linkageStrategyRepository;
private readonly IRepository<MeasureTemperaturePoint, Guid> _measureTemperaturePointRepository;
private readonly IRepository<EquipmentType, Guid> _equipmentTypeRepository;
private readonly IRepository<PresetPoint, Guid> _presetPointRepository;
private readonly IRepository<TelemeteringConfiguration, Guid> _telemeteringConfigurationResitory;
private readonly IRepository<TelesignalisationConfiguration, Guid> _telesignalisationConfigurationResitory;
private readonly IRepository<TelecommandConfiguration, Guid> _telecommandConfigurationResitory;
private readonly IRepository<TelemeteringAlarmStrategy, Guid> _telemeteringAlarmStrategyResitory;
private readonly IRepository<TelemeteringTemplate, Guid> _telemeteringTemplateResitory;
private readonly IRedisRepository<object, string> _redisRepository;
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IRedisRepository<EquipmentDataModel, string> _equipmentDataModelDicRedis;
private readonly IRepository<CCThreeDimension, Guid> _threeDimensionResitory;
2024-11-26 13:45:28 +08:00
private readonly string _telemeteringModelListRediskey = "telemeteringModelList";
/// <summary>
/// 遥测数据实时库
/// </summary>
private readonly IRedisRepository<TelemeteringModel, string> _telemeteringModelListRedis;
private readonly string _telesignalisationModelListRediskey = "telesignalisationModelList";
/// <summary>
/// 遥信数据实时库
/// </summary>
private readonly IRedisRepository<TelesignalisationModel, string> _telesignalisationModelListRedis;
2024-07-15 10:31:26 +08:00
2025-03-10 18:15:27 +08:00
private readonly IRedisRepository<EquipmentInfoDiagnoseResult, string> _equipmentInfoDiagnoseResult;
private readonly IRedisRepository<DiagnoseResultOutPut, string> _diagnoseResultOutPutRedis;
private readonly IMongoDbRepository<BsonDocument, Guid> _bsonDocumentResultRepository;
public readonly IRedisRepository<AlarmMessage, string> _alarmMessageRedis;
private readonly IRedisRepository<AlarmListRedis, string> _redisDataRepository;
private readonly IRedisRepository<EquipmentInfoSearchRecord, string> _equipmentInfoDetailRedis;
2025-04-16 13:53:07 +08:00
private readonly IRedisRepository<VideoDevProperty, string> _videoDevPropertyRedis;
2024-11-26 13:45:28 +08:00
private readonly string _equipmentInfoDetailRedisChannel = "equipmentInfoDetailRedisChannel";
private readonly string _equipmentInfoDiagnoseResultChanel = "equipmentInfoDiagnoseResultChanel";
private readonly EquipmentInfoExAppService _equipmentInfoExAppService;
2025-04-16 13:53:07 +08:00
private readonly IRedisRepository<CheckDefect, string> _checkDefectRedis;
private readonly IRedisRepository<DiagnosisImageResult, string> _diagnosisImageResult;
2024-07-15 10:31:26 +08:00
public EquipmentLiveDataAppService(
IRepository<EquipmentInfo, Guid> repositoryEquipmentInfo
, IRepository<EquipmentType, Guid> repositoryEquipmentType
, IRepository<TelemeteringConfiguration, Guid> telemeteringConfigurationResitory
, IRepository<TelesignalisationConfiguration, Guid> telesignalisationConfigurationResitory
, IRepository<TelecommandConfiguration, Guid> telecommandConfigurationResitory
, IRepository<PresetPoint, Guid> presetPointRepository
, IRepository<TelemeteringAlarmStrategy, Guid> telemeteringAlarmStrategyResitory
, IRepository<TelemeteringTemplate, Guid> telemeteringTemplateResitory
, IRepository<VideoDev, Guid> videoDevRepository
, IRepository<LinkageStrategy, Guid> linkageStrategyRepository
, IRepository<MeasureTemperaturePoint, Guid> measureTemperaturePointRepository
, IRedisRepository<object, string> redisRepository
, IRedisRepository<EquipmentDataModel, string> equipmentDataModelDicRedis
, IRepository<CCThreeDimension, Guid> threeDimensionResitory
, IUnitOfWorkManager unitOfWorkManager
2024-11-26 13:45:28 +08:00
, IRedisRepository<TelemeteringModel, string> telemeteringModelListRedis
, IRedisRepository<TelesignalisationModel, string> telesignalisationModelListRedis
2025-03-10 18:15:27 +08:00
, IRedisRepository<EquipmentInfoDiagnoseResult, string> equipmentInfoDiagnoseResult
, IRedisRepository<EquipmentInfoSearchRecord, string> equipmentInfoDetailRedis
2024-11-26 13:45:28 +08:00
, EquipmentInfoExAppService equipmentInfoExAppService
2025-03-10 18:15:27 +08:00
, IAppServiceConfiguration appServiceConfiguration
, IRedisRepository<DiagnoseResultOutPut, string> diagnoseResultOutPutRedis
, IMongoDbRepository<BsonDocument, Guid> bsonDocumentResultRepository
, IRedisRepository<AlarmMessage, string> alarmMessageRedis
, IRedisRepository<AlarmListRedis, string> redisDataRepository
2025-04-16 13:53:07 +08:00
, IRedisRepository<CheckDefect, string> checkDefectRedis
, IRedisRepository<DiagnosisImageResult, string> diagnosisImageResult
, IRedisRepository<VideoDevProperty, string> videoDevPropertyRedis
2025-03-10 18:15:27 +08:00
, ISessionAppService sessionAppService) : base(sessionAppService, appServiceConfiguration)
2024-07-15 10:31:26 +08:00
{
_equipmentInfoRepository = repositoryEquipmentInfo;
_equipmentTypeRepository = repositoryEquipmentType;
_telemeteringConfigurationResitory = telemeteringConfigurationResitory;
_telesignalisationConfigurationResitory = telesignalisationConfigurationResitory;
_telecommandConfigurationResitory = telecommandConfigurationResitory;
_telemeteringAlarmStrategyResitory = telemeteringAlarmStrategyResitory;
_presetPointRepository = presetPointRepository;
_telemeteringTemplateResitory = telemeteringTemplateResitory;
_currentUser = base.GetCurrentUser();
_unitOfWorkManager = unitOfWorkManager;
_redisRepository = redisRepository;
_equipmentDataModelDicRedis = equipmentDataModelDicRedis;
_threeDimensionResitory = threeDimensionResitory;
_videoDevRepository = videoDevRepository;
_linkageStrategyRepository = linkageStrategyRepository;
_measureTemperaturePointRepository = measureTemperaturePointRepository;
2024-11-26 13:45:28 +08:00
_telemeteringModelListRedis = telemeteringModelListRedis;
_telesignalisationModelListRedis = telesignalisationModelListRedis;
_equipmentInfoDiagnoseResult = equipmentInfoDiagnoseResult;
_equipmentInfoDetailRedis = equipmentInfoDetailRedis;
_equipmentInfoExAppService = equipmentInfoExAppService;
2025-03-10 18:15:27 +08:00
_diagnoseResultOutPutRedis = diagnoseResultOutPutRedis;
_bsonDocumentResultRepository = bsonDocumentResultRepository;
_alarmMessageRedis = alarmMessageRedis;
_redisDataRepository = redisDataRepository;
2025-04-16 13:53:07 +08:00
_checkDefectRedis = checkDefectRedis;
_diagnosisImageResult = diagnosisImageResult;
_videoDevPropertyRedis = videoDevPropertyRedis;
2024-07-15 10:31:26 +08:00
}
#region
public RequestPageResult<EquipmentInfoOutput> FindDatas(PageSearchCondition<EquipmentInfoSearchConditionInput> searchCondition)
{
throw new NotImplementedException();
}
public Task<RequestResult<EquipmentInfoOutput>> CreateOrUpdateAsync(EditEquipmentInfoInput input)
{
throw new NotImplementedException();
}
public Task<RequestEasyResult> DeleteByIdsAsync(List<Guid> ids)
{
throw new NotImplementedException();
}
public Task<RequestEasyResult> DeleteByIdAsync(Guid id)
{
throw new NotImplementedException();
}
#endregion
/// <summary>
/// 根据设备id获取设备实时运行数据
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
[AbpAllowAnonymous]
[ShowApi]
public async Task<RequestResult<EquipmentDataModel>> GetEquipmentLiveStateByEquipmentId(Guid id)
{
RequestResult<EquipmentDataModel> rst = new RequestResult<EquipmentDataModel>();
if (id == default)
{
rst.Message = "设备id为空";
return rst;
}
try
{
var dic = await _equipmentDataModelDicRedis.HashSetGetAllAsync(ConstantModel.EquipmentDataModelDicRedisKey);
if (dic.Any(t=>t.EquipmentInfoId == id))
{
var equipmentdata = dic.FirstOrDefault(t=> t.EquipmentInfoId == id);
var cfgs = _threeDimensionResitory.GetAll().Where(t => t.EquipmentInfoId == id);
equipmentdata.Telemeterings = equipmentdata.Telemeterings.Where(t => cfgs.Any(x => x.TelemeteringConfigurationId == t.Id)).ToList();
equipmentdata.Telesignalisations = equipmentdata.Telesignalisations.Where(t => cfgs.Any(x => x.TelesignalisationConfigurationId == t.Id)).ToList();
rst.Flag = true;
rst.ResultData = equipmentdata;
}
}
catch (Exception ex)
{
Log4Helper.Error(this.GetType(), "根据设备id获取设备实时运行数据出错", ex);
}
return rst;
}
/// <summary>
/// 根据模型id获取设备实时运行数据
/// </summary>
/// <param name="modelId"></param>
/// <returns></returns>
[HttpGet]
[AbpAllowAnonymous]
[ShowApi]
public async Task<RequestResult<EquipmentDataModel>> GetEquipmentLiveStateByModelId(int modelId)
{
RequestResult<EquipmentDataModel> rst = new RequestResult<EquipmentDataModel>();
if (modelId == 0)
{
rst.Message = "模型id为0";
return rst;
}
try
{
var ccDatas = _threeDimensionResitory.GetAll().ToList();
var dic = await _equipmentDataModelDicRedis.HashSetGetAllAsync(ConstantModel.EquipmentDataModelDicRedisKey);
var cc = ccDatas.FirstOrDefault(t => t.ModelId == modelId);
if (dic!=null&&cc != null&& cc.EquipmentInfoId.HasValue)
{
Guid id = cc.EquipmentInfoId.Value;
if (dic.Any(t => t.EquipmentInfoId == id))
{
var equipmentdata = dic.FirstOrDefault(t => t.EquipmentInfoId == id);
var cfgs = ccDatas.Where(t => t.EquipmentInfoId == id);
equipmentdata.Telemeterings = equipmentdata.Telemeterings.Where(t => cfgs.Any(x => x.TelemeteringConfigurationId == t.Id)).ToList();
equipmentdata.Telesignalisations = equipmentdata.Telesignalisations.Where(t => cfgs.Any(x => x.TelesignalisationConfigurationId == t.Id)).ToList();
rst.Flag = true;
rst.ResultData = equipmentdata;
}
}
}
catch (Exception ex)
{
Log4Helper.Error(this.GetType(), "根据设备id获取设备实时运行数据出错", ex);
}
return rst;
}
/// <summary>
/// 设备总览信息
/// </summary>
/// <param name="stationId"></param>
/// <returns></returns>
[HttpGet]
[AbpAllowAnonymous]
[ShowApi]
public async Task<RequestResult<List<EquimentOverviewOutput>>> GetEquipmentOverviewAsync(Guid stationId)
{
2024-12-25 15:06:46 +08:00
RequestResult<List<EquimentOverviewOutput>> rst = new RequestResult<List<EquimentOverviewOutput>>();
2024-07-15 10:31:26 +08:00
try
{
if (stationId == default)
{
Log4Helper.Error(this.GetType(), "传入id为空");
}
List<EquimentOverviewOutput> datas = new List<EquimentOverviewOutput>();
var equipmentTypesRepo = _equipmentTypeRepository.GetAllIncluding(t=>t.EquipmentInfos).OrderBy(t=>t.SeqNo).ToList();
var typesRepo = equipmentTypesRepo.Where(x => x.EquipmentTypeLevel == EquipmentTypeLevelEnum.Type);
var equipmentTypeRepo = equipmentTypesRepo.Where(x => x.EquipmentTypeLevel == EquipmentTypeLevelEnum.Equipment);
var dic = await _equipmentDataModelDicRedis.HashSetGetAllAsync(ConstantModel.EquipmentDataModelDicRedisKey);
foreach (var item in typesRepo)
{
var equipments = equipmentTypeRepo.Where(t => t.EquipmentTypeId == item.Id).SelectMany(t => t.EquipmentInfos);
var query = from equip in equipments
join dataModel in dic on equip.Id equals dataModel.EquipmentInfoId
where dataModel.Telemeterings!=null
from telemetry in dataModel.Telemeterings
where telemetry.ResultValue != -99999
select new
{
EquipmentId = equip.Id,
// Include other properties as needed
};
var query1 = from equip in equipments
join dataModel in dic on equip.Id equals dataModel.EquipmentInfoId
where dataModel.Telesignalisations != null
from telemetry in dataModel.Telesignalisations
where telemetry.ResultValue != -99999
select new
{
EquipmentId = equip.Id,
// Include other properties as needed
};
int lineCount = query.Concat(query1).Distinct().Count();
datas.Add(new EquimentOverviewOutput
{
Id = item.Id,
SeqNo = datas.Count + 1,
Count = equipments.Count(),
LineCount = lineCount,
IsVisable = true,
TypeName = item.Name
});
}
var video = _videoDevRepository.GetAllIncluding(t=>t.PresetPoints).OrderBy(t=>t.SeqNo).ToList();
var nvr = video.Where(t => t.VideoDevId == null);
int nvrOnlineCount = 0;
//CameraOnlineInfo.GetDeviceConnected( nvr.Select(t=>t.IP).ToList()).Where(t=>t.Value).Count();
datas.Add(new EquimentOverviewOutput
{
Id = default,
SeqNo = datas.Count + 1,
Count = nvr.Count(),
LineCount = nvrOnlineCount,
IsVisable = true,
TypeName = "NVR",
Description = ""
});
var camera = video.Where(t => t.VideoDevId != null);
int cameraOnlineCount = 0;//
//CameraOnlineInfo.GetDeviceConnected(camera.Where(x=> !string.IsNullOrWhiteSpace(x.IP)).Select(t => t.IP).ToList()).Where(t => t.Value).Count();
datas.Add(new EquimentOverviewOutput
{
Id = default,
SeqNo = datas.Count + 1,
Count = camera.Count(),
LineCount = cameraOnlineCount,
IsVisable = true,
TypeName = "摄像头",
Description = ""
});
var presetsCount = _presetPointRepository.Count();
datas.Add(new EquimentOverviewOutput
{
Id = default,
SeqNo = datas.Count + 1,
Count = presetsCount,
LineCount = -1,
IsVisable = true,
TypeName = "预置位"
});
var linkageCount = _linkageStrategyRepository.Count();
datas.Add(new EquimentOverviewOutput
{
Id = default,
SeqNo = datas.Count+1,
Count = linkageCount,
LineCount = -1,
IsVisable = true,
TypeName = "联动"
});
var measureTempCount = _measureTemperaturePointRepository.Count();
datas.Add(new EquimentOverviewOutput
{
Id = default,
SeqNo = datas.Count + 1,
Count = measureTempCount,
LineCount = -1,
IsVisable = true,
TypeName = "测温点"
});
rst.ResultData = datas;
rst.Flag = true;
//_equipmentInfoRepository.GetAllIncluding(t => t.EquipmentType);
}
catch (Exception ex)
{
Log4Helper.Error(this.GetType(), "根据设备id获取设备实时运行数据出错", ex);
}
return rst;
}
2024-11-26 13:45:28 +08:00
/// <summary>
/// 根据设备id获取设备遥测实时数据
/// </summary>
/// <returns></returns>
[HttpGet]
[AbpAllowAnonymous]
[ShowApi]
public async Task<RequestResult<List<TelemeteringModel>>> GetEquipmentTelemeteringByEquipmentId(Guid equipmentId,int dataSourceCategory)
{
2024-12-25 15:06:46 +08:00
RequestResult<List<TelemeteringModel>> rst = new RequestResult<List<TelemeteringModel>> ();
2024-11-26 13:45:28 +08:00
if (equipmentId == default)
{
rst.Message = "设备id为空";
return rst;
}
try
{
var telemeterings = await _telemeteringModelListRedis.HashSetGetAllAsync(_telemeteringModelListRediskey + "_" + ((DataSourceCategoryEnum)dataSourceCategory).ToString());
if (telemeterings == null || telemeterings.Count == 0)
{
rst.ResultData = new List<TelemeteringModel>();
}
else
{
var datas = telemeterings
.Where(t => t.EquipmentInfoId == equipmentId && t.DataSourceCategory == (DataSourceCategoryEnum)dataSourceCategory)
.Where(t => t.Name != "未用" || !t.Name.Contains("预留"))
.OrderBy(t => t.DispatcherAddress)
.ToList();
rst.ResultData = datas;
}
rst.Flag = true;
}
catch (Exception ex)
{
Log4Helper.Error(this.GetType(), "根据设备id获取设备遥测实时数据", ex);
}
return rst;
}
[HttpGet]
[AbpAllowAnonymous]
[ShowApi]
public RequestResult<DateTime> TestTimeFormat()
{
return new RequestResult<DateTime> { ResultData = DateTime.Now };
}
/// <summary>
/// 根据设备id获取设备遥信实时数据
/// </summary>
/// <param name="equipmentId"></param>
/// <param name="dataSourceCategory"></param>
/// <returns></returns>
[HttpGet]
[AbpAllowAnonymous]
[ShowApi]
public async Task<RequestResult<List<TelesignalisationModel>>> GetEquipmentTelesignalisationByEquipmentId(Guid equipmentId, int dataSourceCategory)
{
2024-12-25 15:06:46 +08:00
RequestResult<List<TelesignalisationModel>> rst = new RequestResult<List<TelesignalisationModel>>();
2024-11-26 13:45:28 +08:00
if (equipmentId == default)
{
rst.Message = "设备id为空";
return rst;
}
try
{
var telemeterings = await _telesignalisationModelListRedis.HashSetGetAllAsync(_telesignalisationModelListRediskey + "_" + ((DataSourceCategoryEnum)dataSourceCategory).ToString());
if (telemeterings == null|| telemeterings.Count==0)
{
rst.ResultData = new List<TelesignalisationModel>();
}
else
{
var datas = telemeterings
.Where(t => t.EquipmentInfoId == equipmentId && t.DataSourceCategory == (DataSourceCategoryEnum)dataSourceCategory)
.Where(t => t.Name != "未用" || !t.Name.Contains("预留"))
.OrderBy(t => t.DispatcherAddress)
.ToList();
rst.ResultData = datas;
}
rst.Flag = true;
}
catch (Exception ex)
{
Log4Helper.Error(this.GetType(), "根据设备id获取设备遥测实时数据", ex);
}
return rst;
}
2025-03-10 18:15:27 +08:00
/// <summary>
/// 九维发送设备诊断信息到后台
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
2024-11-26 13:45:28 +08:00
[HttpPost]
[AbpAllowAnonymous]
[ShowApi]
[DisableRequestSizeLimit]
[Route("/soms/api/uploadEquipmentDiagnosis")] // 指定完整路径
public async Task<RequestEasyResult> UploadEquipmentDiagnosisAsync(object input)
{
RequestEasyResult rst = new RequestEasyResult();
try
{
2025-04-16 13:53:07 +08:00
//Log4Helper.Info(this.GetType(), $"九维数据:{input.ToString()}");
string filePath = $"..\\logs\\九维数据—{Guid.NewGuid()}.txt";
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.WriteAllText(filePath, input.ToString());
2024-11-26 13:45:28 +08:00
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
var diagnostic = JsonSerializer.Deserialize<IntelligentDiagnostic>(input.ToString(), options);
2025-03-10 18:15:27 +08:00
List<DiagnoseResultOutPut> diagnoseResultOutPuts = new List<DiagnoseResultOutPut>();
DateTime time = DateTime.Now;
string format = "yyyy-MM-dd HH-mm-ss.fff";
if (DateTime.TryParseExact(
diagnostic?.SaveTime,
format,
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out time
))
{
Log4Helper.Info(this.GetType(), time.ToString("yyyy-MM-dd HH:mm:ss.fff"));
}
else
{
Log4Helper.Info(this.GetType(), $"时间解析失败:{diagnostic.SaveTime}");
}
//电站 运检
2025-04-16 13:53:07 +08:00
if (diagnostic != null)
2025-03-10 18:15:27 +08:00
{
2025-04-16 13:53:07 +08:00
Log4Helper.Info(this.GetType(), $"SaveTime: {diagnostic.SaveTime}");
2025-03-10 18:15:27 +08:00
var equipmentDic = _equipmentInfoRepository.GetAllIncluding(t => t.TransformerSubstation)
2025-04-16 13:53:07 +08:00
.Where(t => t.TransformerSubstation.SubstationName.Contains("神池南"))
.ToDictionary(t => t.Name);
2025-03-10 18:15:27 +08:00
foreach (var item in diagnostic.DiagnoseResult)
{
if (item.Name.Contains("整体"))
{
if (item.Device == "电站" || item.Device == "电站诊断")
{
var diagnoseResultOutPut = diagnoseResultOutPuts.FirstOrDefault(t => t.EquipmentInfoName == "变电所");
2025-04-16 13:53:07 +08:00
if (diagnoseResultOutPut == null)
2025-03-10 18:15:27 +08:00
{
diagnoseResultOutPuts.Add(new DiagnoseResultOutPut
{
DiagnoseResultName = item.Name,
DiaStatus = item.DiaStatus,
Score = float.Parse(string.IsNullOrEmpty(item.Score) ? "0" : item.Score),
EquipmentInfoName = "变电所",
Suggest = item.Suggest,
Errortype = item.ErrorType,
2025-04-16 13:53:07 +08:00
Time = time,
2025-03-10 18:15:27 +08:00
});
}
2025-04-16 13:53:07 +08:00
2025-03-10 18:15:27 +08:00
}
else if (item.Device == "运检" || item.Device == "运检诊断")
{
var diagnoseResultOutPut = diagnoseResultOutPuts.FirstOrDefault(t => t.EquipmentInfoName == "运检");
if (diagnoseResultOutPut == null)
{
diagnoseResultOutPuts.Add(new DiagnoseResultOutPut
{
DiagnoseResultName = item.Name,
DiaStatus = item.DiaStatus,
Score = float.Parse(string.IsNullOrEmpty(item.Score) ? "0" : item.Score),
EquipmentInfoName = "运检",
Suggest = item.Suggest,
Errortype = item.ErrorType,
Time = time,
});
}
2025-04-16 13:53:07 +08:00
2025-03-10 18:15:27 +08:00
}
else
{
item.Device = item.Device.Replace("诊断", "");
item.Name = item.Name.Replace(item.Device, "");
2025-04-16 13:53:07 +08:00
var equipmentObjName = equipmentDic.Keys.FirstOrDefault(t => StringHelper.HasMinimumSequentialMatch(t, item.Device));
if (!string.IsNullOrWhiteSpace(equipmentObjName))
2025-03-10 18:15:27 +08:00
{
2025-04-16 13:53:07 +08:00
if (equipmentDic.ContainsKey(equipmentObjName))
2024-11-26 13:45:28 +08:00
{
2025-04-16 13:53:07 +08:00
diagnoseResultOutPuts.Add(new DiagnoseResultOutPut
{
DiagnoseResultName = item.Name,
DiaStatus = item.DiaStatus,
Score = float.Parse(string.IsNullOrEmpty(item.Score) ? "0" : item.Score),
EquipmentInfoName = equipmentObjName,
Suggest = item.Suggest,
Errortype = item.ErrorType,
EquipmentInfoId = equipmentDic[equipmentObjName].Id,
Time = time,
});
}
2025-03-10 18:15:27 +08:00
}
2025-04-16 13:53:07 +08:00
2025-03-10 18:15:27 +08:00
}
}
2025-04-16 13:53:07 +08:00
2025-03-10 18:15:27 +08:00
}
foreach (var item in diagnostic.DiagnoseResult)
2024-11-26 13:45:28 +08:00
{
2025-03-10 18:15:27 +08:00
if (!item.Name.Contains("整体"))
2024-11-26 13:45:28 +08:00
{
2025-03-10 18:15:27 +08:00
if (item.Device == "电站" || item.Device == "电站诊断")
{
2025-04-16 13:53:07 +08:00
2025-03-10 18:15:27 +08:00
var diagnoseResultOutPut = diagnoseResultOutPuts.FirstOrDefault(t => t.EquipmentInfoName == "变电所");
if (diagnoseResultOutPut != null)
{
diagnoseResultOutPut.DiagnoseContentItems.Add(new DiagnoseContent
{
DiagnoseResultName = item.Name,
DiaStatus = item.DiaStatus,
Score = float.Parse(string.IsNullOrEmpty(item.Score) ? "0" : item.Score),
Errortype = item.ErrorType,
Suggest = item.Suggest,
Time = time,
});
}
}
else if (item.Device == "运检" || item.Device == "运检诊断")
{
var diagnoseResultOutPut = diagnoseResultOutPuts.FirstOrDefault(t => t.EquipmentInfoName == "运检");
if (diagnoseResultOutPut != null)
{
diagnoseResultOutPut.DiagnoseContentItems.Add(new DiagnoseContent
{
DiagnoseResultName = item.Name,
DiaStatus = item.DiaStatus,
Score = float.Parse(string.IsNullOrEmpty(item.Score) ? "0" : item.Score),
Errortype = item.ErrorType,
Time = time,
Suggest = item.Suggest
});
}
}
else
{
item.Device = item.Device.Replace("诊断", "");
item.Name = item.Name.Replace(item.Device, "");
2025-04-16 13:53:07 +08:00
var equipmentObjName = equipmentDic.Keys.FirstOrDefault(t => StringHelper.HasMinimumSequentialMatch(t, item.Device));
if (!string.IsNullOrWhiteSpace(equipmentObjName))
2025-03-10 18:15:27 +08:00
{
2025-04-16 13:53:07 +08:00
if (equipmentDic.ContainsKey(equipmentObjName))
2025-03-10 18:15:27 +08:00
{
2025-04-16 13:53:07 +08:00
var diagnoseResultOutPut = diagnoseResultOutPuts.FirstOrDefault(t => t.EquipmentInfoName == equipmentObjName);
2025-03-10 18:15:27 +08:00
2025-04-16 13:53:07 +08:00
if (diagnoseResultOutPut != null)
{
diagnoseResultOutPut.DiagnoseContentItems.Add(new DiagnoseResultOutPut
{
DiagnoseResultName = item.Name,
DiaStatus = item.DiaStatus,
Score = float.Parse(string.IsNullOrEmpty(item.Score) ? "0" : item.Score),
EquipmentInfoName = equipmentObjName,
Suggest = item.Suggest,
Errortype = item.ErrorType,
Time = time,
EquipmentInfoId = equipmentDic[equipmentObjName].Id
});
}
2025-03-10 18:15:27 +08:00
}
}
}
}
2025-04-16 13:53:07 +08:00
2025-03-10 18:15:27 +08:00
}
foreach (var item in diagnoseResultOutPuts)
{
var dataItems = diagnostic.Data.Where(t => t.Name.Contains(item.EquipmentInfoName));
item.DataItems = dataItems.ToList();
}
2025-04-16 13:53:07 +08:00
2025-03-10 18:15:27 +08:00
}
var rediskeys = diagnoseResultOutPuts.Select(t => t.EquipmentInfoName).ToList();
_diagnoseResultOutPutRedis.HashSetUpdateManyAsync(nameof(DiagnoseResultOutPut), rediskeys, diagnoseResultOutPuts);
2025-04-16 13:53:07 +08:00
foreach (var diagnoseResultOutPut in diagnoseResultOutPuts)
2024-11-26 13:45:28 +08:00
{
2025-04-16 13:53:07 +08:00
if (diagnoseResultOutPut.DiaStatus != "正常")
2025-03-10 18:15:27 +08:00
{
2025-04-16 13:53:07 +08:00
var alarmId = $"{diagnoseResultOutPut.EquipmentInfoName}:{diagnoseResultOutPut.DiagnoseResultName}";
2025-03-10 18:15:27 +08:00
2025-04-16 13:53:07 +08:00
var alarmMessage = new AlarmMessage
{
HandlingMeasures = diagnoseResultOutPut.Suggest,
AlarmContent = diagnoseResultOutPut.Errortype,
AlarmDateTime = time.ToString("yyyy-MM-dd HH:mm:ss"),
Id = alarmId,
AlarmObject = $"{diagnoseResultOutPut.EquipmentInfoName}|{diagnoseResultOutPut.DiagnoseResultName}",
AlarmLevel = GetAlarmLevelStr(diagnoseResultOutPut.DiaStatus),
EquipmentInfoId = diagnoseResultOutPut.EquipmentInfoId,
DataSourceCategory = "在线监测",
IsConfirm = false,
AlarmType = "健康诊断",
};
if (!string.IsNullOrEmpty(diagnoseResultOutPut.Errortype))
{
if (IsTrueAlarm(diagnoseResultOutPut.Suggest))
2025-03-10 18:15:27 +08:00
{
2025-04-16 13:53:07 +08:00
_alarmMessageRedis.PublishAsync("alarmMessageChannel", alarmMessage);
_alarmMessageRedis.HashSetUpdateOneAsync(nameof(AlarmMessage), alarmId, alarmMessage);
ChecKAlarm(alarmMessage, diagnoseResultOutPut.Suggest);
}
2025-03-10 18:15:27 +08:00
2024-11-26 13:45:28 +08:00
}
}
2025-04-16 13:53:07 +08:00
foreach (var diaItem in diagnoseResultOutPut.DiagnoseContentItems)
2025-03-10 18:15:27 +08:00
{
if (diaItem.DiaStatus != "正常")
{
2025-04-16 13:53:07 +08:00
var alarmId = $"{diagnoseResultOutPut.EquipmentInfoName}:{diaItem.DiagnoseResultName}";
var alarmMessage = new AlarmMessage
{
HandlingMeasures = diaItem.Suggest,
AlarmContent = diaItem.Errortype,
AlarmDateTime = time.ToString("yyyy-MM-dd HH:mm:ss"),
Id = alarmId,
AlarmObject = $"{diagnoseResultOutPut.EquipmentInfoName}|{diagnoseResultOutPut.DiagnoseResultName}",
AlarmLevel = GetAlarmLevelStr(diagnoseResultOutPut.DiaStatus),
EquipmentInfoId = diagnoseResultOutPut.EquipmentInfoId,
EquipmentInfoName = diagnoseResultOutPut.EquipmentInfoName,
DataSourceCategory = "在线监测",
IsConfirm = false,
AlarmType = "健康诊断",
};
2025-03-10 18:15:27 +08:00
if (!string.IsNullOrEmpty(diaItem.Errortype))
{
2025-04-16 13:53:07 +08:00
if (IsTrueAlarm(diaItem.Suggest))
2025-03-10 18:15:27 +08:00
{
2025-04-16 13:53:07 +08:00
_alarmMessageRedis.PublishAsync("alarmMessageChannel", alarmMessage);
_alarmMessageRedis.HashSetUpdateOneAsync(nameof(AlarmMessage), alarmId, alarmMessage);
ChecKAlarm(alarmMessage, diaItem.Suggest);
}
else
{
ChecKAlarm(alarmMessage, diaItem.Suggest,"在线监测设备");
2025-03-10 18:15:27 +08:00
2025-04-16 13:53:07 +08:00
}
2025-03-10 18:15:27 +08:00
}
2025-04-16 13:53:07 +08:00
2025-03-10 18:15:27 +08:00
}
2025-04-16 13:53:07 +08:00
await _diagnoseResultOutPutRedis.PublishAsync(_equipmentInfoDiagnoseResultChanel, diagnoseResultOutPut);
await Task.Delay(10);
2025-03-10 18:15:27 +08:00
}
2025-04-16 13:53:07 +08:00
_bsonDocumentResultRepository.CollectionName = nameof(DiagnoseResultOutPut);
await _bsonDocumentResultRepository.InsertManyAsync(diagnoseResultOutPuts.Select(t => t.ToBsonDocument()));
2025-03-10 18:15:27 +08:00
2025-04-16 13:53:07 +08:00
var yuanjian = diagnoseResultOutPuts.FirstOrDefault(t => t.EquipmentInfoName == "运检");
// 保存或处理 jsonString
rst.Flag = true;
}
2024-11-26 13:45:28 +08:00
}
catch (Exception ex)
{
Log4Helper.Error(this.GetType(), "获取实时环境数据出错", ex);
}
return rst;
}
2025-04-16 13:53:07 +08:00
/// <summary>
/// 是否为可信报警
/// </summary>
/// <param name="suggest"></param>
/// <returns></returns>
private bool IsTrueAlarm(string suggest)
{
return !suggest.Contains("输入数据异常");
}
/// <summary>
/// 获取报警级别
/// </summary>
/// <param name="status"></param>
/// <returns></returns>
private string GetAlarmLevelStr(string status)
{
string resStr = "告知";
if (status.Contains("异常"))
{
resStr = "异常";
}
else if (status.Contains("报警"))
{
resStr = "告知";
}
return resStr;
}
private void ChecKAlarm(AlarmMessage alarm, string suggest, string category ="一次设备")
{
var checkDefect = new CheckDefect
{
Content = alarm.AlarmContent,
DateTime = alarm.AlarmDateTime,
Id = alarm.Id,
DataSourceCategory = category,
IsConfirm = false,
EquipmentInfoId = alarm.EquipmentInfoId,
HandlingMeasures = suggest,
Level = alarm.AlarmLevel,
Object = alarm.AlarmObject,
Type = alarm.AlarmType,
Analysis = "",
};
_checkDefectRedis.HashSetUpdateOneAsync(nameof(CheckDefect), checkDefect.Id, checkDefect);
}
2024-11-26 13:45:28 +08:00
/// <summary>
/// 导航到客户端详细页面
/// </summary>
/// <param name="equipemntInfoId"></param>
/// <returns></returns>
[HttpPost]
[AbpAllowAnonymous]
[ShowApi]
[DisableRequestSizeLimit]
public async Task<RequestEasyResult> NavigateToClientEquipmentDetailAsync(string equipemntInfoId)
{
RequestEasyResult rst = new RequestEasyResult();
try
{
if (equipemntInfoId!=default)
{
var tempData = await _equipmentInfoExAppService.FindEquipmentSearchRecordAsync(default);
var equipmentInfo = tempData.ResultData.FirstOrDefault(t => t.Id == Guid.Parse( equipemntInfoId));
2025-04-16 13:53:07 +08:00
if (equipmentInfo == null)
{
await NavigateToClientCameraAsync(equipemntInfoId);
}
else
{
await _equipmentInfoDetailRedis.PublishAsync(_equipmentInfoDetailRedisChannel, equipmentInfo);
}
2024-11-26 13:45:28 +08:00
rst.Flag = true;
}
else
{
Log4Helper.Error(this.GetType(), "导航到客户端详细页面设备ID为空");
}
}
catch (Exception ex)
{
Log4Helper.Error(this.GetType(), "导航到客户端详细页面", ex);
}
return rst;
}
2025-04-16 13:53:07 +08:00
/// <summary>
/// 导航到客户端视频页面
/// </summary>
/// <param name="equipemntInfoId"></param>
/// <returns></returns>
[HttpPost]
[AbpAllowAnonymous]
[ShowApi]
[DisableRequestSizeLimit]
public async Task<RequestEasyResult> NavigateToClientCameraAsync(string cameraId)
{
RequestEasyResult rst = new RequestEasyResult();
try
{
if (cameraId != default)
{
var tempData = _videoDevRepository.GetAllIncluding(t => t.Parent,t=>t.ManufacturerInfo).FirstOrDefault(t => t.Id == Guid.Parse(cameraId));
if (tempData!=null)
{
var resData = ObjectMapper.Map<VideoDevProperty>(tempData);
await _videoDevPropertyRedis.PublishAsync("CameraInfo", resData);
rst.Flag = true;
}
}
else
{
Log4Helper.Error(this.GetType(), "导航到客户端详细页面设备ID为空");
}
}
catch (Exception ex)
{
Log4Helper.Error(this.GetType(), "导航到客户端详细页面", ex);
}
return rst;
}
2025-03-10 18:15:27 +08:00
[HttpPost, AbpAllowAnonymous]
[ShowApi]
[UnitOfWork(false)]
[DisableRequestSizeLimit]
[RequestFormLimits(ValueLengthLimit = int.MaxValue, MultipartBodyLengthLimit = int.MaxValue)]
public async Task<RequestEasyResult> UploadEquipmentDiagnosisImageAsync(
[FromQuery] string deviceName,
string description,
[FromForm] IFormFile file = null,
IFormFile datafile = null)
2024-11-26 13:45:28 +08:00
{
2025-03-10 18:15:27 +08:00
RequestEasyResult rst = new RequestEasyResult();
2024-11-26 13:45:28 +08:00
try
{
2025-03-10 18:15:27 +08:00
// 检查设备是否存在
var equipments = _equipmentInfoRepository.GetAll().ToList()
.GroupBy(t => t.Name)
.ToDictionary(g => g.Key, g => g.First());
2024-11-26 13:45:28 +08:00
2025-03-10 18:15:27 +08:00
if (!equipments.ContainsKey(deviceName))
2024-11-26 13:45:28 +08:00
{
2025-03-10 18:15:27 +08:00
rst.Message = $"设备名称不存在:{deviceName}";
Log4Helper.Info(GetType(), rst.Message);
return rst;
2024-11-26 13:45:28 +08:00
}
2025-03-10 18:15:27 +08:00
// 验证至少上传一个文件
if (file == null && datafile == null)
{
rst.Message = "必须上传至少一个文件";
return rst;
}
// 处理图片文件
string imagePath = null, imageUrl = null;
//if (file != null)
//{
// var imgResult = await ProcessFileAsync(file, deviceName, "Images",
// new[] { ".jpg", ".jpeg", ".png", ".svg", ".bmp" });
// if (!imgResult.Success)
// {
// rst.Message = imgResult.Message;
// return rst;
// }
// (imagePath, imageUrl) = (imgResult.FilePath, imgResult.Url);
//}
// 处理数据文件
string dataPath = null, dataUrl = null;
DateTime dataTimestamp = DateTime.Now;
int[] dataArray = null;
2025-04-16 13:53:07 +08:00
//#if DEBUG
// Random random = new Random();
// dataArray = new int[100];
// for (int i = 0; i < dataArray.Length; i++)
// {
// dataArray[i] = random.Next(10, 31); // 生成 10 到 30 之间的随机整数31 不包括)
// }
//#else
if (datafile != null)
2025-03-10 18:15:27 +08:00
{
var dataResult = await ProcessFileAsync(datafile, deviceName, "DataFiles",
new[] { ".csv", ".txt", ".xlsx", ".json", ".dat", "" });
if (!dataResult.Success)
{
rst.Message = dataResult.Message;
return rst;
}
(dataPath, dataUrl) = (dataResult.FilePath, dataResult.Url);
// 解析数据文件中的时间和数据
using (var reader = new StreamReader(datafile.OpenReadStream(), Encoding.Default))
{
string line = await reader.ReadLineAsync(); // 读取第一行时间戳
if (!string.IsNullOrEmpty(line) && DateTime.TryParse(line.Trim('[', ']', ' '), out var timestamp))
{
dataTimestamp = timestamp;
}
// 解析数据部分
line = await reader.ReadLineAsync(); // 读取第二行数据
if (!string.IsNullOrEmpty(line))
{
dataArray = line.Split(',')
.Select(x => int.TryParse(x, out var num) ? num : 0)
.ToArray();
}
}
}
2025-04-16 13:53:07 +08:00
//#endif
2025-03-10 18:15:27 +08:00
// 保存记录到数据库
var diagnosisRecord = new DiagnosisImageResult
{
EquipmentInfoId = equipments[deviceName].Id,
EquipmentInfoName = deviceName,
Time = dataTimestamp,
ImagePath = imagePath,
ImageUrl = imageUrl,
DataFilePath = dataPath,
DataFileUrl = dataUrl,
Description = description,
DataArray = dataArray,
DataType = 1
};
_bsonDocumentResultRepository.CollectionName = nameof(DiagnosisImageResult);
await _bsonDocumentResultRepository.InsertOneAsync(diagnosisRecord.ToBsonDocument());
rst.Flag = true;
Log4Helper.Info(GetType(), $"上传成功 - 设备:{deviceName},描述:{description}");
}
catch (Exception ex)
{
rst.Message = ex.Message;
Log4Helper.Error(GetType(), "上传设备诊断文件失败", ex);
}
return rst;
}
private async Task<(bool Success, string Message, string FilePath, string Url)>
ProcessFileAsync(IFormFile file, string deviceName, string fileType, string[] allowedExtensions)
{
try
{
// 验证文件类型
var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
if (!allowedExtensions.Contains(extension))
{
return (false, $"不支持的文件类型:{extension}", null, null);
}
// 创建存储目录
var uploadDir = Path.Combine(
base.GetAttachmentDirectory(),
"Uploads",
deviceName,
DateTime.Now.ToString("yyyy-MM-dd"),
fileType);
Directory.CreateDirectory(uploadDir); // 自动存在检查
// 生成唯一文件名
var fileName = $"{Guid.NewGuid():N}_{DateTime.Now:HHmmss}{extension}";
var fullPath = Path.Combine(uploadDir, fileName);
// 保存文件
using (var stream = new FileStream(fullPath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
return (true, null, fullPath, fullPath.Replace(base.GetAttachmentDirectory(), ""));
2024-11-26 13:45:28 +08:00
}
catch (Exception ex)
{
2025-03-10 18:15:27 +08:00
Log4Helper.Error(GetType(), $"处理{fileType}文件失败", ex);
return (false, ex.Message, null, null);
2024-11-26 13:45:28 +08:00
}
2025-03-10 18:15:27 +08:00
}
[HttpGet]
[AbpAllowAnonymous]
[ShowApi]
[DisableRequestSizeLimit]
public async Task<RequestResult<List<DiagnosisImageResult>>> GetEquipmentDiagnoseResultAsync(Guid equipmentId,
int dataType,
DateTime? startTime = null,
DateTime? endTime = null
)
{
RequestResult<List<DiagnosisImageResult>> rst = new RequestResult<List<DiagnosisImageResult>>();
try
{
_bsonDocumentResultRepository.CollectionName = nameof(DiagnosisImageResult);
// 计算时间范围默认查询最近1小时的数据
DateTime defaultStartTime = DateTime.Now.AddHours(-1);
DateTime defaultEndTime = DateTime.Now;
DateTime queryStartTime = startTime ?? defaultStartTime;
DateTime queryEndTime = endTime ?? defaultEndTime;
// 构建查询条件
var filterBuilder = Builders<BsonDocument>.Filter;
var filter = filterBuilder.Eq("EquipmentInfoId", equipmentId) &
filterBuilder.Eq("DataType", dataType) &
filterBuilder.Gte("Time", queryStartTime) &
filterBuilder.Lte("Time", queryEndTime);
// 按时间降序排序
SortDefinition<BsonDocument> sortDefinition = Builders<BsonDocument>.Sort.Descending("Time");
2024-11-26 13:45:28 +08:00
2025-03-10 18:15:27 +08:00
// 查询数据
var bsonDocuments = _bsonDocumentResultRepository
.GetAllIncludeToFindFluent(filter, sort: sortDefinition)
.Limit(15*60*24); // 新增限制查询结果数量;
if (bsonDocuments != null && bsonDocuments.Any())
{
var diagnosisImageResults = bsonDocuments.ToList().Select(doc => BsonSerializer.Deserialize<DiagnosisImageResult>(doc)).ToList();
rst.ResultData = diagnosisImageResults;
}
else
{
rst.Message = "未找到符合条件的设备诊断结果";
}
rst.Flag = true;
}
catch (Exception ex)
{
Log4Helper.Error(this.GetType(), "获取设备诊断结果", ex);
rst.Message = "查询设备诊断结果时发生异常";
}
return rst;
2024-11-26 13:45:28 +08:00
}
2024-07-15 10:31:26 +08:00
}
}