using Abp.Authorization; using Abp.Domain.Repositories; using Abp.Domain.Uow; using Abp.Web.Mvc.Alerts; using Google.Protobuf; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ModelBinding; using MongoDB.Bson; using MongoDB.Bson.Serialization; using MongoDB.Driver; using NPOI.SS.Formula.Functions; using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Dynamic.Core; using System.Text; using System.Text.Json; using System.Threading.Tasks; using ToolLibrary.LogHelper; using YunDa.ISAS.Application.Core; using YunDa.ISAS.Application.Core.Configuration; using YunDa.ISAS.Application.Core.Session; using YunDa.ISAS.Application.Core.SwaggerHelper; using YunDa.ISAS.Core.Helper; 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; using YunDa.ISAS.DataTransferObject.VideoSurveillance.VideoDevDto; 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; using YunDa.ISAS.MongoDB.Repositories; using YunDa.ISAS.Redis.Entities.AlarmCategory; using YunDa.ISAS.Redis.Repositories; using YunDa.SOMS.DataTransferObject.AlarmDataDto; using YunDa.SOMS.DataTransferObject.EquipmentLiveData; using YunDa.SOMS.DataTransferObject.MainStationMaintenanceInfo.OperationReport; using YunDa.SOMS.DataTransferObject.ThirdPartyData.NJJW; using YunDa.SOMS.Entities.GeneralInformation; using ZstdSharp.Unsafe; using JsonSerializer = System.Text.Json.JsonSerializer; namespace YunDa.ISAS.Application.GeneralInformation { /// /// 设备信息 /// [Description("设备信息管理服务")] public class EquipmentLiveDataAppService : ISASAppServiceBase, IEquipmentLiveDataAppService { private LoginUserOutput _currentUser; private readonly IRepository _equipmentInfoRepository; private readonly IRepository _videoDevRepository; private readonly IRepository _linkageStrategyRepository; private readonly IRepository _measureTemperaturePointRepository; private readonly IRepository _equipmentTypeRepository; private readonly IRepository _presetPointRepository; private readonly IRepository _telemeteringConfigurationResitory; private readonly IRepository _telesignalisationConfigurationResitory; private readonly IRepository _telecommandConfigurationResitory; private readonly IRepository _telemeteringAlarmStrategyResitory; private readonly IRepository _telemeteringTemplateResitory; private readonly IRedisRepository _redisRepository; private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly IRedisRepository _equipmentDataModelDicRedis; private readonly IRepository _threeDimensionResitory; private readonly string _telemeteringModelListRediskey = "telemeteringModelList"; /// /// 遥测数据实时库 /// private readonly IRedisRepository _telemeteringModelListRedis; private readonly string _telesignalisationModelListRediskey = "telesignalisationModelList"; /// /// 遥信数据实时库 /// private readonly IRedisRepository _telesignalisationModelListRedis; private readonly IRedisRepository _equipmentInfoDiagnoseResult; private readonly IRedisRepository _diagnoseResultOutPutRedis; private readonly IMongoDbRepository _bsonDocumentResultRepository; public readonly IRedisRepository _alarmMessageRedis; private readonly IRedisRepository _redisDataRepository; private readonly IRedisRepository _equipmentInfoDetailRedis; private readonly IRedisRepository _videoDevPropertyRedis; private readonly string _equipmentInfoDetailRedisChannel = "equipmentInfoDetailRedisChannel"; private readonly string _equipmentInfoDiagnoseResultChanel = "equipmentInfoDiagnoseResultChanel"; private readonly EquipmentInfoExAppService _equipmentInfoExAppService; private readonly IRedisRepository _checkDefectRedis; private readonly IRedisRepository _diagnosisImageResult; public EquipmentLiveDataAppService( IRepository repositoryEquipmentInfo , IRepository repositoryEquipmentType , IRepository telemeteringConfigurationResitory , IRepository telesignalisationConfigurationResitory , IRepository telecommandConfigurationResitory , IRepository presetPointRepository , IRepository telemeteringAlarmStrategyResitory , IRepository telemeteringTemplateResitory , IRepository videoDevRepository , IRepository linkageStrategyRepository , IRepository measureTemperaturePointRepository , IRedisRepository redisRepository , IRedisRepository equipmentDataModelDicRedis , IRepository threeDimensionResitory , IUnitOfWorkManager unitOfWorkManager , IRedisRepository telemeteringModelListRedis , IRedisRepository telesignalisationModelListRedis , IRedisRepository equipmentInfoDiagnoseResult , IRedisRepository equipmentInfoDetailRedis , EquipmentInfoExAppService equipmentInfoExAppService , IAppServiceConfiguration appServiceConfiguration , IRedisRepository diagnoseResultOutPutRedis , IMongoDbRepository bsonDocumentResultRepository , IRedisRepository alarmMessageRedis , IRedisRepository redisDataRepository , IRedisRepository checkDefectRedis , IRedisRepository diagnosisImageResult , IRedisRepository videoDevPropertyRedis , ISessionAppService sessionAppService) : base(sessionAppService, appServiceConfiguration) { _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; _telemeteringModelListRedis = telemeteringModelListRedis; _telesignalisationModelListRedis = telesignalisationModelListRedis; _equipmentInfoDiagnoseResult = equipmentInfoDiagnoseResult; _equipmentInfoDetailRedis = equipmentInfoDetailRedis; _equipmentInfoExAppService = equipmentInfoExAppService; _diagnoseResultOutPutRedis = diagnoseResultOutPutRedis; _bsonDocumentResultRepository = bsonDocumentResultRepository; _alarmMessageRedis = alarmMessageRedis; _redisDataRepository = redisDataRepository; _checkDefectRedis = checkDefectRedis; _diagnosisImageResult = diagnosisImageResult; _videoDevPropertyRedis = videoDevPropertyRedis; } #region 基础接口 public RequestPageResult FindDatas(PageSearchCondition searchCondition) { throw new NotImplementedException(); } public Task> CreateOrUpdateAsync(EditEquipmentInfoInput input) { throw new NotImplementedException(); } public Task DeleteByIdsAsync(List ids) { throw new NotImplementedException(); } public Task DeleteByIdAsync(Guid id) { throw new NotImplementedException(); } #endregion /// /// 根据设备id获取设备实时运行数据 /// /// /// [HttpGet] [AbpAllowAnonymous] [ShowApi] public async Task> GetEquipmentLiveStateByEquipmentId(Guid id) { RequestResult rst = new RequestResult(); 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; } /// /// 根据模型id获取设备实时运行数据 /// /// /// [HttpGet] [AbpAllowAnonymous] [ShowApi] public async Task> GetEquipmentLiveStateByModelId(int modelId) { RequestResult rst = new RequestResult(); 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; } /// /// 设备总览信息 /// /// /// [HttpGet] [AbpAllowAnonymous] [ShowApi] public async Task>> GetEquipmentOverviewAsync(Guid stationId) { RequestResult> rst = new RequestResult>(); try { if (stationId == default) { Log4Helper.Error(this.GetType(), "传入id为空"); } List datas = new List(); 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; } /// /// 根据设备id获取设备遥测实时数据 /// /// [HttpGet] [AbpAllowAnonymous] [ShowApi] public async Task>> GetEquipmentTelemeteringByEquipmentId(Guid equipmentId,int dataSourceCategory) { RequestResult> rst = new RequestResult> (); 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(); } 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 TestTimeFormat() { return new RequestResult { ResultData = DateTime.Now }; } /// /// 根据设备id获取设备遥信实时数据 /// /// /// /// [HttpGet] [AbpAllowAnonymous] [ShowApi] public async Task>> GetEquipmentTelesignalisationByEquipmentId(Guid equipmentId, int dataSourceCategory) { RequestResult> rst = new RequestResult>(); 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(); } 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; } /// /// 九维发送设备诊断信息到后台 /// /// /// [HttpPost] [AbpAllowAnonymous] [ShowApi] [DisableRequestSizeLimit] [Route("/soms/api/uploadEquipmentDiagnosis")] // 指定完整路径 public async Task UploadEquipmentDiagnosisAsync(object input) { RequestEasyResult rst = new RequestEasyResult(); try { //Log4Helper.Info(this.GetType(), $"九维数据:{input.ToString()}"); string filePath = $"..\\logs\\九维数据—{Guid.NewGuid()}.txt"; Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.WriteAllText(filePath, input.ToString()); var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; var diagnostic = JsonSerializer.Deserialize(input.ToString(), options); List diagnoseResultOutPuts = new List(); 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}"); } //电站 运检 if (diagnostic != null) { Log4Helper.Info(this.GetType(), $"SaveTime: {diagnostic.SaveTime}"); var equipmentDic = _equipmentInfoRepository.GetAllIncluding(t => t.TransformerSubstation) .Where(t => t.TransformerSubstation.SubstationName.Contains("神池南")) .ToDictionary(t => t.Name); foreach (var item in diagnostic.DiagnoseResult) { if (item.Name.Contains("整体")) { 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, }); } } 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, }); } } else { item.Device = item.Device.Replace("诊断", ""); item.Name = item.Name.Replace(item.Device, ""); var equipmentObjName = equipmentDic.Keys.FirstOrDefault(t => StringHelper.HasMinimumSequentialMatch(t, item.Device)); if (!string.IsNullOrWhiteSpace(equipmentObjName)) { if (equipmentDic.ContainsKey(equipmentObjName)) { 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, }); } } } } } foreach (var item in diagnostic.DiagnoseResult) { if (!item.Name.Contains("整体")) { 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, 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, ""); var equipmentObjName = equipmentDic.Keys.FirstOrDefault(t => StringHelper.HasMinimumSequentialMatch(t, item.Device)); if (!string.IsNullOrWhiteSpace(equipmentObjName)) { if (equipmentDic.ContainsKey(equipmentObjName)) { var diagnoseResultOutPut = diagnoseResultOutPuts.FirstOrDefault(t => t.EquipmentInfoName == equipmentObjName); 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 }); } } } } } } foreach (var item in diagnoseResultOutPuts) { var dataItems = diagnostic.Data.Where(t => t.Name.Contains(item.EquipmentInfoName)); item.DataItems = dataItems.ToList(); } } var rediskeys = diagnoseResultOutPuts.Select(t => t.EquipmentInfoName).ToList(); _diagnoseResultOutPutRedis.HashSetUpdateManyAsync(nameof(DiagnoseResultOutPut), rediskeys, diagnoseResultOutPuts); foreach (var diagnoseResultOutPut in diagnoseResultOutPuts) { if (diagnoseResultOutPut.DiaStatus != "正常") { var alarmId = $"{diagnoseResultOutPut.EquipmentInfoName}:{diagnoseResultOutPut.DiagnoseResultName}"; 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)) { _alarmMessageRedis.PublishAsync("alarmMessageChannel", alarmMessage); _alarmMessageRedis.HashSetUpdateOneAsync(nameof(AlarmMessage), alarmId, alarmMessage); ChecKAlarm(alarmMessage, diagnoseResultOutPut.Suggest); } } } foreach (var diaItem in diagnoseResultOutPut.DiagnoseContentItems) { if (diaItem.DiaStatus != "正常") { 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 = "健康诊断", }; if (!string.IsNullOrEmpty(diaItem.Errortype)) { if (IsTrueAlarm(diaItem.Suggest)) { _alarmMessageRedis.PublishAsync("alarmMessageChannel", alarmMessage); _alarmMessageRedis.HashSetUpdateOneAsync(nameof(AlarmMessage), alarmId, alarmMessage); ChecKAlarm(alarmMessage, diaItem.Suggest); } else { ChecKAlarm(alarmMessage, diaItem.Suggest,"在线监测设备"); } } } await _diagnoseResultOutPutRedis.PublishAsync(_equipmentInfoDiagnoseResultChanel, diagnoseResultOutPut); await Task.Delay(10); } _bsonDocumentResultRepository.CollectionName = nameof(DiagnoseResultOutPut); await _bsonDocumentResultRepository.InsertManyAsync(diagnoseResultOutPuts.Select(t => t.ToBsonDocument())); var yuanjian = diagnoseResultOutPuts.FirstOrDefault(t => t.EquipmentInfoName == "运检"); // 保存或处理 jsonString rst.Flag = true; } } catch (Exception ex) { Log4Helper.Error(this.GetType(), "获取实时环境数据出错", ex); } return rst; } /// /// 是否为可信报警 /// /// /// private bool IsTrueAlarm(string suggest) { return !suggest.Contains("输入数据异常"); } /// /// 获取报警级别 /// /// /// 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); } /// /// 导航到客户端详细页面 /// /// /// [HttpPost] [AbpAllowAnonymous] [ShowApi] [DisableRequestSizeLimit] public async Task 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)); if (equipmentInfo == null) { await NavigateToClientCameraAsync(equipemntInfoId); } else { await _equipmentInfoDetailRedis.PublishAsync(_equipmentInfoDetailRedisChannel, equipmentInfo); } rst.Flag = true; } else { Log4Helper.Error(this.GetType(), "导航到客户端详细页面:设备ID为空"); } } catch (Exception ex) { Log4Helper.Error(this.GetType(), "导航到客户端详细页面", ex); } return rst; } /// /// 导航到客户端视频页面 /// /// /// [HttpPost] [AbpAllowAnonymous] [ShowApi] [DisableRequestSizeLimit] public async Task 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(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; } [HttpPost, AbpAllowAnonymous] [ShowApi] [UnitOfWork(false)] [DisableRequestSizeLimit] [RequestFormLimits(ValueLengthLimit = int.MaxValue, MultipartBodyLengthLimit = int.MaxValue)] public async Task UploadEquipmentDiagnosisImageAsync( [FromQuery] string deviceName, string description, [FromForm] IFormFile file = null, IFormFile datafile = null) { RequestEasyResult rst = new RequestEasyResult(); try { // 检查设备是否存在 var equipments = _equipmentInfoRepository.GetAll().ToList() .GroupBy(t => t.Name) .ToDictionary(g => g.Key, g => g.First()); if (!equipments.ContainsKey(deviceName)) { rst.Message = $"设备名称不存在:{deviceName}"; Log4Helper.Info(GetType(), rst.Message); return rst; } // 验证至少上传一个文件 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; //#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) { 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(); } } } //#endif // 保存记录到数据库 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(), "")); } catch (Exception ex) { Log4Helper.Error(GetType(), $"处理{fileType}文件失败", ex); return (false, ex.Message, null, null); } } [HttpGet] [AbpAllowAnonymous] [ShowApi] [DisableRequestSizeLimit] public async Task>> GetEquipmentDiagnoseResultAsync(Guid equipmentId, int dataType, DateTime? startTime = null, DateTime? endTime = null ) { RequestResult> rst = new RequestResult>(); 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.Filter; var filter = filterBuilder.Eq("EquipmentInfoId", equipmentId) & filterBuilder.Eq("DataType", dataType) & filterBuilder.Gte("Time", queryStartTime) & filterBuilder.Lte("Time", queryEndTime); // 按时间降序排序 SortDefinition sortDefinition = Builders.Sort.Descending("Time"); // 查询数据 var bsonDocuments = _bsonDocumentResultRepository .GetAllIncludeToFindFluent(filter, sort: sortDefinition) .Limit(15*60*24); // 新增限制查询结果数量; if (bsonDocuments != null && bsonDocuments.Any()) { var diagnosisImageResults = bsonDocuments.ToList().Select(doc => BsonSerializer.Deserialize(doc)).ToList(); rst.ResultData = diagnosisImageResults; } else { rst.Message = "未找到符合条件的设备诊断结果"; } rst.Flag = true; } catch (Exception ex) { Log4Helper.Error(this.GetType(), "获取设备诊断结果", ex); rst.Message = "查询设备诊断结果时发生异常"; } return rst; } } }