修改了二次回路巡检的一些问题

This commit is contained in:
guorui 2025-12-02 13:49:02 +08:00
parent 4d4da8ac2b
commit c9e3609369
17 changed files with 381 additions and 217 deletions

View File

@ -48,6 +48,8 @@ namespace YunDa.SOMS.Application.DataMonitoring.SecondaryCircuitInspection
private readonly IRepository<SecondaryCircuitInspectionEventItem, Guid> _inspectionEventItemRepository;
private readonly IRepository<SecondaryCircuitInspectionTelemetryConfig, Guid> _telemetryConfigRepository;
private readonly IRepository<SecondaryCircuitInspectionTelesignalConfig, Guid> _telesignalConfigRepository;
private readonly IRepository<TelemeteringConfiguration, Guid> _telemeteringConfigurationRepository;
private readonly IRepository<TelesignalisationConfiguration, Guid> _telesignalisationConfigurationRepository;
private readonly IRedisRepository<TelemeteringModel, string> _telemeteringRedisRepository;
private readonly IRedisRepository<TelesignalisationModel, string> _telesignalisationRedisRepository;
private readonly IRepository<EquipmentInfo, Guid> _equipmentInfoRepository;
@ -75,6 +77,8 @@ namespace YunDa.SOMS.Application.DataMonitoring.SecondaryCircuitInspection
IRepository<SecondaryCircuitInspectionEventItem, Guid> inspectionEventItemRepository,
IRepository<SecondaryCircuitInspectionTelemetryConfig, Guid> telemetryConfigRepository,
IRepository<SecondaryCircuitInspectionTelesignalConfig, Guid> telesignalConfigRepository,
IRepository<TelemeteringConfiguration, Guid> telemeteringConfigurationRepository,
IRepository<TelesignalisationConfiguration, Guid> telesignalisationConfigurationRepository,
IRedisRepository<TelemeteringModel, string> telemeteringRedisRepository,
IRedisRepository<TelesignalisationModel, string> telesignalisationRedisRepository,
IRepository<EquipmentInfo, Guid> equipmentInfoRepository,
@ -88,6 +92,8 @@ namespace YunDa.SOMS.Application.DataMonitoring.SecondaryCircuitInspection
_inspectionEventItemRepository = inspectionEventItemRepository;
_telemetryConfigRepository = telemetryConfigRepository;
_telesignalConfigRepository = telesignalConfigRepository;
_telemeteringConfigurationRepository = telemeteringConfigurationRepository;
_telesignalisationConfigurationRepository = telesignalisationConfigurationRepository;
_telemeteringRedisRepository = telemeteringRedisRepository;
_telesignalisationRedisRepository = telesignalisationRedisRepository;
_equipmentInfoRepository = equipmentInfoRepository;
@ -946,22 +952,8 @@ namespace YunDa.SOMS.Application.DataMonitoring.SecondaryCircuitInspection
RequestPageResult<SecondaryCircuitEventDrivenConfigOutput> rst = new RequestPageResult<SecondaryCircuitEventDrivenConfigOutput>();
try
{
// Build query with eager loading of related entities
var query = _eventDrivenConfigRepository.GetAll()
.Include(x => x.SecondaryCircuitInspectionEventItems)
.ThenInclude(t => t.InspectionItem)
.ThenInclude(t => t.TelemetryConfigs)
.ThenInclude(t => t.TelemeteringConfiguration)
.Include(x => x.SecondaryCircuitInspectionEventItems)
.ThenInclude(t => t.InspectionItem)
.ThenInclude(t => t.TelesignalConfigs)
.ThenInclude(t => t.TelesignalisationConfiguration)
.Include(x => x.TelemetryConfigs)
.ThenInclude(t => t.TelemeteringConfiguration)
.Include(x => x.TelesignalConfigs)
.ThenInclude(t => t.TelesignalisationConfiguration)
.AsQueryable()
;
// Step 1: Build query for main entities WITHOUT joins
var query = _eventDrivenConfigRepository.GetAll();
// Apply search conditions
if (input.SearchCondition != null)
@ -996,103 +988,244 @@ namespace YunDa.SOMS.Application.DataMonitoring.SecondaryCircuitInspection
query = query.PageBy(skipCount, input.PageSize);
}
// Execute query to get main entities
var entities = await query.ToListAsync(cancellationToken).ConfigureAwait(false);
// Load equipment info dictionary for efficient lookups
var equipmentInfoDict = await _equipmentInfoRepository.GetAll()
.ToDictionaryAsync(e => e.Id, e => e.Name, cancellationToken)
if (!entities.Any())
{
rst.PageSize = input.PageSize;
rst.PageIndex = input.PageIndex;
rst.TotalCount = totalCount;
rst.Flag = true;
rst.ResultData = new List<SecondaryCircuitEventDrivenConfigOutput>();
return rst;
}
// Step 2: Collect all IDs for subsequent queries
var configIds = entities.Select(e => e.Id).ToList();
// Step 3: Query SecondaryCircuitInspectionEventItems for these configs
var eventItems = await _inspectionEventItemRepository.GetAll()
.Where(ei => configIds.Contains(ei.InpectionEventDrivenId.Value))
.ToListAsync(cancellationToken)
.ConfigureAwait(false);
// Map entities to output DTOs
var inspectionItemIds = eventItems
.Where(ei => ei.InspectionItemId.HasValue)
.Select(ei => ei.InspectionItemId.Value)
.Distinct()
.ToList();
// Step 4: Query InspectionItems
var inspectionItems = inspectionItemIds.Any()
? await _inspectionItemRepository.GetAll()
.Where(ii => inspectionItemIds.Contains(ii.Id))
.ToListAsync(cancellationToken)
.ConfigureAwait(false)
: new List<SecondaryCircuitInspectionItem>();
// Step 5: Query TelemetryConfigs (both from EventDrivenConfig and InspectionItems)
var telemetryConfigs = await _telemetryConfigRepository.GetAll()
.Where(tc => configIds.Contains(tc.SecondaryCircuitEventDrivenConfigId.Value) ||
inspectionItemIds.Contains(tc.SecondaryCircuitInspectionItemId.Value))
.ToListAsync(cancellationToken)
.ConfigureAwait(false);
var telemetryConfigIds = telemetryConfigs
.Where(tc => tc.TelemetryConfigurationId.HasValue)
.Select(tc => tc.TelemetryConfigurationId.Value)
.Distinct()
.ToList();
// Step 6: Query TelesignalConfigs (both from EventDrivenConfig and InspectionItems)
var telesignalConfigs = await _telesignalConfigRepository.GetAll()
.Where(tc => configIds.Contains(tc.SecondaryCircuitEventDrivenConfigId.Value) ||
inspectionItemIds.Contains(tc.SecondaryCircuitInspectionItemId.Value))
.ToListAsync(cancellationToken)
.ConfigureAwait(false);
var telesignalConfigIds = telesignalConfigs
.Where(tc => tc.TelesignalConfigurationId.HasValue)
.Select(tc => tc.TelesignalConfigurationId.Value)
.Distinct()
.ToList();
// Step 7: Query TelemeteringConfiguration entities
var telemeteringConfigurations = telemetryConfigIds.Any()
? await _telemeteringConfigurationRepository.GetAll()
.Where(tc => telemetryConfigIds.Contains(tc.Id))
.ToListAsync(cancellationToken)
.ConfigureAwait(false)
: new List<TelemeteringConfiguration>();
// Step 8: Query TelesignalisationConfiguration entities
var telesignalisationConfigurations = telesignalConfigIds.Any()
? await _telesignalisationConfigurationRepository.GetAll()
.Where(tc => telesignalConfigIds.Contains(tc.Id))
.ToListAsync(cancellationToken)
.ConfigureAwait(false)
: new List<TelesignalisationConfiguration>();
// Step 9: Get all equipment IDs and load equipment info dictionary
var equipmentIds = telemeteringConfigurations
.Where(tc => tc.EquipmentInfoId.HasValue)
.Select(tc => tc.EquipmentInfoId.Value)
.Concat(telesignalisationConfigurations
.Where(tc => tc.EquipmentInfoId.HasValue)
.Select(tc => tc.EquipmentInfoId.Value))
.Distinct()
.ToList();
var equipmentInfoDict = equipmentIds.Any()
? await _equipmentInfoRepository.GetAll()
.Where(e => equipmentIds.Contains(e.Id))
.ToDictionaryAsync(e => e.Id, e => e.Name, cancellationToken)
.ConfigureAwait(false)
: new Dictionary<Guid, string>();
// Step 10: Create lookup dictionaries for efficient in-memory correlation
var telemeteringConfigDict = telemeteringConfigurations.ToDictionary(tc => tc.Id);
var telesignalisationConfigDict = telesignalisationConfigurations.ToDictionary(tc => tc.Id);
var inspectionItemDict = inspectionItems.ToDictionary(ii => ii.Id);
var eventItemsByConfigId = eventItems
.Where(ei => ei.InpectionEventDrivenId.HasValue)
.GroupBy(ei => ei.InpectionEventDrivenId.Value)
.ToDictionary(g => g.Key, g => g.ToList());
var telemetryConfigsByEventConfigId = telemetryConfigs
.Where(tc => tc.SecondaryCircuitEventDrivenConfigId.HasValue)
.GroupBy(tc => tc.SecondaryCircuitEventDrivenConfigId.Value)
.ToDictionary(g => g.Key, g => g.ToList());
var telemetryConfigsByInspectionItemId = telemetryConfigs
.Where(tc => tc.SecondaryCircuitInspectionItemId.HasValue)
.GroupBy(tc => tc.SecondaryCircuitInspectionItemId.Value)
.ToDictionary(g => g.Key, g => g.ToList());
var telesignalConfigsByEventConfigId = telesignalConfigs
.Where(tc => tc.SecondaryCircuitEventDrivenConfigId.HasValue)
.GroupBy(tc => tc.SecondaryCircuitEventDrivenConfigId.Value)
.ToDictionary(g => g.Key, g => g.ToList());
var telesignalConfigsByInspectionItemId = telesignalConfigs
.Where(tc => tc.SecondaryCircuitInspectionItemId.HasValue)
.GroupBy(tc => tc.SecondaryCircuitInspectionItemId.Value)
.ToDictionary(g => g.Key, g => g.ToList());
// Step 11: Map entities to output DTOs using in-memory correlation
var outputList = new List<SecondaryCircuitEventDrivenConfigOutput>();
foreach (var entity in entities)
{
var output = ObjectMapper.Map<SecondaryCircuitEventDrivenConfigOutput>(entity);
output.SecondaryCircuitInspectionEventItems = ObjectMapper.Map<List<SecondaryCircuitInspectionItemOutput>>(
entity.SecondaryCircuitInspectionEventItems.Select(t => t.InspectionItem));
// Enrich nested inspection items with telemetry and telesignal config details
foreach (var eventItem in entity.SecondaryCircuitInspectionEventItems)
// Get event items for this config
var configEventItems = eventItemsByConfigId.ContainsKey(entity.Id)
? eventItemsByConfigId[entity.Id]
: new List<SecondaryCircuitInspectionEventItem>();
// Map inspection items
var inspectionItemOutputs = new List<SecondaryCircuitInspectionItemOutput>();
foreach (var eventItem in configEventItems)
{
if (eventItem.InspectionItem == null) continue;
if (!eventItem.InspectionItemId.HasValue || !inspectionItemDict.ContainsKey(eventItem.InspectionItemId.Value))
continue;
var outputItem = output.SecondaryCircuitInspectionEventItems.FirstOrDefault(x => x.Id == eventItem.InspectionItem.Id);
if (outputItem == null) continue;
var inspectionItem = inspectionItemDict[eventItem.InspectionItemId.Value];
var inspectionItemOutput = ObjectMapper.Map<SecondaryCircuitInspectionItemOutput>(inspectionItem);
// Enrich telemetry configs for nested inspection item
if (eventItem.InspectionItem.TelemetryConfigs != null && eventItem.InspectionItem.TelemetryConfigs.Any())
// Get telemetry configs for this inspection item
var itemTelemetryConfigs = telemetryConfigsByInspectionItemId.ContainsKey(inspectionItem.Id)
? telemetryConfigsByInspectionItemId[inspectionItem.Id]
: new List<SecondaryCircuitInspectionTelemetryConfig>();
inspectionItemOutput.TelemetryConfigs = itemTelemetryConfigs
.Where(tc => tc.TelemetryConfigurationId.HasValue && telemeteringConfigDict.ContainsKey(tc.TelemetryConfigurationId.Value))
.Select(tc =>
{
outputItem.TelemetryConfigs = eventItem.InspectionItem.TelemetryConfigs.Select(tc => new SecondaryCircuitInspectionTelemetryConfigOutput
var telemetryConfig = telemeteringConfigDict[tc.TelemetryConfigurationId.Value];
return new SecondaryCircuitInspectionTelemetryConfigOutput
{
Id = tc.Id,
EquipmentInfoId = tc.TelemeteringConfiguration.EquipmentInfoId.Value,
EquipmentInfoName = equipmentInfoDict.ContainsKey(tc.TelemeteringConfiguration.EquipmentInfoId.Value)
? equipmentInfoDict[tc.TelemeteringConfiguration.EquipmentInfoId.Value]
EquipmentInfoId = telemetryConfig.EquipmentInfoId ?? Guid.Empty,
EquipmentInfoName = telemetryConfig.EquipmentInfoId.HasValue && equipmentInfoDict.ContainsKey(telemetryConfig.EquipmentInfoId.Value)
? equipmentInfoDict[telemetryConfig.EquipmentInfoId.Value]
: string.Empty,
TelemetryConfigurationId = tc.TelemetryConfigurationId ?? Guid.Empty,
TelemetryConfigurationName = tc.TelemeteringConfiguration?.Name,
TelemetryConfigurationIsmsId = tc.TelemeteringConfiguration?.ismsbaseYCId
TelemetryConfigurationName = telemetryConfig.Name,
TelemetryConfigurationIsmsId = telemetryConfig.ismsbaseYCId
};
}).ToList();
outputItem.TelemetryConfigCount = outputItem.TelemetryConfigs.Count;
}
inspectionItemOutput.TelemetryConfigCount = inspectionItemOutput.TelemetryConfigs.Count;
// Enrich telesignal configs for nested inspection item
if (eventItem.InspectionItem.TelesignalConfigs != null && eventItem.InspectionItem.TelesignalConfigs.Any())
// Get telesignal configs for this inspection item
var itemTelesignalConfigs = telesignalConfigsByInspectionItemId.ContainsKey(inspectionItem.Id)
? telesignalConfigsByInspectionItemId[inspectionItem.Id]
: new List<SecondaryCircuitInspectionTelesignalConfig>();
inspectionItemOutput.TelesignalConfigs = itemTelesignalConfigs
.Where(tc => tc.TelesignalConfigurationId.HasValue && telesignalisationConfigDict.ContainsKey(tc.TelesignalConfigurationId.Value))
.Select(tc =>
{
outputItem.TelesignalConfigs = eventItem.InspectionItem.TelesignalConfigs.Select(tc => new SecondaryCircuitInspectionTelesignalConfigOutput
var telesignalConfig = telesignalisationConfigDict[tc.TelesignalConfigurationId.Value];
return new SecondaryCircuitInspectionTelesignalConfigOutput
{
Id = tc.Id,
EquipmentInfoId = tc.TelesignalisationConfiguration.EquipmentInfoId.Value,
EquipmentInfoName = equipmentInfoDict.ContainsKey(tc.TelesignalisationConfiguration.EquipmentInfoId.Value)
? equipmentInfoDict[tc.TelesignalisationConfiguration.EquipmentInfoId.Value]
EquipmentInfoId = telesignalConfig.EquipmentInfoId ?? Guid.Empty,
EquipmentInfoName = telesignalConfig.EquipmentInfoId.HasValue && equipmentInfoDict.ContainsKey(telesignalConfig.EquipmentInfoId.Value)
? equipmentInfoDict[telesignalConfig.EquipmentInfoId.Value]
: string.Empty,
TelesignalConfigurationId = tc.TelesignalConfigurationId ?? Guid.Empty,
TelesignalConfigurationName = tc.TelesignalisationConfiguration?.Name,
TelesignalConfigurationIsmsId = tc.TelesignalisationConfiguration?.ismsbaseYXId
TelesignalConfigurationName = telesignalConfig.Name,
TelesignalConfigurationIsmsId = telesignalConfig.ismsbaseYXId
};
}).ToList();
outputItem.TelesignalConfigCount = outputItem.TelesignalConfigs.Count;
}
}
inspectionItemOutput.TelesignalConfigCount = inspectionItemOutput.TelesignalConfigs.Count;
// Map telemetry configs
if (entity.TelemetryConfigs != null && entity.TelemetryConfigs.Any())
inspectionItemOutputs.Add(inspectionItemOutput);
}
output.SecondaryCircuitInspectionEventItems = inspectionItemOutputs;
// Map telemetry configs directly associated with event driven config
var configTelemetryConfigs = telemetryConfigsByEventConfigId.ContainsKey(entity.Id)
? telemetryConfigsByEventConfigId[entity.Id]
: new List<SecondaryCircuitInspectionTelemetryConfig>();
output.TelemetryConfigs = configTelemetryConfigs
.Where(tc => tc.TelemetryConfigurationId.HasValue && telemeteringConfigDict.ContainsKey(tc.TelemetryConfigurationId.Value))
.Select(tc =>
{
output.TelemetryConfigs = entity.TelemetryConfigs.Select(tc => new SecondaryCircuitInspectionTelemetryConfigOutput
var telemetryConfig = telemeteringConfigDict[tc.TelemetryConfigurationId.Value];
return new SecondaryCircuitInspectionTelemetryConfigOutput
{
Id = tc.Id,
EquipmentInfoId = tc.TelemeteringConfiguration.EquipmentInfoId.Value,
EquipmentInfoName = equipmentInfoDict.ContainsKey(tc.TelemeteringConfiguration.EquipmentInfoId.Value)
? equipmentInfoDict[tc.TelemeteringConfiguration.EquipmentInfoId.Value]
EquipmentInfoId = telemetryConfig.EquipmentInfoId ?? Guid.Empty,
EquipmentInfoName = telemetryConfig.EquipmentInfoId.HasValue && equipmentInfoDict.ContainsKey(telemetryConfig.EquipmentInfoId.Value)
? equipmentInfoDict[telemetryConfig.EquipmentInfoId.Value]
: string.Empty,
TelemetryConfigurationId = tc.TelemetryConfigurationId ?? Guid.Empty,
TelemetryConfigurationName = tc.TelemeteringConfiguration?.Name,
TelemetryConfigurationIsmsId = tc.TelemeteringConfiguration?.ismsbaseYCId
TelemetryConfigurationName = telemetryConfig.Name,
TelemetryConfigurationIsmsId = telemetryConfig.ismsbaseYCId
};
}).ToList();
}
else
{
output.TelemetryConfigs = new List<SecondaryCircuitInspectionTelemetryConfigOutput>();
}
// Map telesignal configs
if (entity.TelesignalConfigs != null && entity.TelesignalConfigs.Any())
// Map telesignal configs directly associated with event driven config
var configTelesignalConfigs = telesignalConfigsByEventConfigId.ContainsKey(entity.Id)
? telesignalConfigsByEventConfigId[entity.Id]
: new List<SecondaryCircuitInspectionTelesignalConfig>();
output.TelesignalConfigs = configTelesignalConfigs
.Where(tc => tc.TelesignalConfigurationId.HasValue && telesignalisationConfigDict.ContainsKey(tc.TelesignalConfigurationId.Value))
.Select(tc =>
{
output.TelesignalConfigs = entity.TelesignalConfigs.Select(tc => new SecondaryCircuitInspectionTelesignalConfigOutput
var telesignalConfig = telesignalisationConfigDict[tc.TelesignalConfigurationId.Value];
return new SecondaryCircuitInspectionTelesignalConfigOutput
{
Id = tc.Id,
EquipmentInfoId = tc.TelesignalisationConfiguration.EquipmentInfoId.Value,
EquipmentInfoName = equipmentInfoDict.ContainsKey(tc.TelesignalisationConfiguration.EquipmentInfoId.Value)
? equipmentInfoDict[tc.TelesignalisationConfiguration.EquipmentInfoId.Value]
EquipmentInfoId = telesignalConfig.EquipmentInfoId ?? Guid.Empty,
EquipmentInfoName = telesignalConfig.EquipmentInfoId.HasValue && equipmentInfoDict.ContainsKey(telesignalConfig.EquipmentInfoId.Value)
? equipmentInfoDict[telesignalConfig.EquipmentInfoId.Value]
: string.Empty,
TelesignalConfigurationId = tc.TelesignalConfigurationId ?? Guid.Empty,
TelesignalConfigurationName = tc.TelesignalisationConfiguration?.Name,
TelesignalConfigurationIsmsId = tc.TelesignalisationConfiguration?.ismsbaseYXId
TelesignalConfigurationName = telesignalConfig.Name,
TelesignalConfigurationIsmsId = telesignalConfig.ismsbaseYXId
};
}).ToList();
}
else
{
output.TelesignalConfigs = new List<SecondaryCircuitInspectionTelesignalConfigOutput>();
}
outputList.Add(output);
}

View File

@ -28,6 +28,7 @@ using YunDa.SOMS.DataTransferObject.ExternalEntities.BeijingYounuo;
using YunDa.SOMS.Entities.DataMonitoring;
using YunDa.SOMS.Entities.ExternalEntities.BeijingYounuo;
using YunDa.SOMS.Entities.GeneralInformation;
using JsonException = System.Text.Json.JsonException;
namespace YunDa.SOMS.Application.ExternalDataManager.BjYounuo
{

View File

@ -29,6 +29,7 @@ using YunDa.SOMS.DataTransferObject;
using YunDa.SOMS.DataTransferObject.ExternalEntities.BeijingYounuo;
using YunDa.SOMS.Entities.ExternalEntities.BeijingYounuo;
using YunDa.SOMS.Entities.GeneralInformation;
using JsonException = System.Text.Json.JsonException;
namespace YunDa.SOMS.Application.ExternalDataManager.BjYounuo
{

View File

@ -29,6 +29,7 @@ using YunDa.SOMS.DataTransferObject;
using YunDa.SOMS.DataTransferObject.ExternalEntities.BeijingYounuo;
using YunDa.SOMS.Entities.ExternalEntities.BeijingYounuo;
using YunDa.SOMS.Entities.GeneralInformation;
using JsonException = System.Text.Json.JsonException;
namespace YunDa.SOMS.Application.ExternalDataManager.BjYounuo
{

View File

@ -64,7 +64,7 @@ namespace YunDa.SOMS.Application.GeneralInformation.SettingAndFaultRpt
private readonly SOMSAuditingStore _SOMSAuditingStore;
private string _ISMSGateWayIp = "http://127.0.0.1:38094";
private string _ISMSftpIp = "192.168.65.33";
private string _ISMSftpIp = "192.168.81.21";
private string _ISMSftpUser = "admin";
private string _ISMSftpPassword = "yunda123";
public TransformInfomationAppService(ISessionAppService sessionAppService

View File

@ -38,14 +38,12 @@ namespace YunDa.SOMS.DataTransferObject.DataMonitoring.SecondaryCircuitInspectio
/// 格式示例: Js代码
/// </summary>
[Required(ErrorMessage = "触发表达式不能为空")]
[StringLength(500, ErrorMessage = "触发表达式长度不能超过500个字符")]
public string TriggerExpression { get; set; }
/// <summary>
/// 强制等待时间(秒)- 防止连续触发
/// </summary>
[Range(1, 3600, ErrorMessage = "强制等待时间必须在1-3600秒之间")]
public int? MandatoryWaitSeconds { get; set; } = 30;
/// <summary>

View File

@ -38,6 +38,9 @@ namespace YunDa.SOMS.DataTransferObject.MaintenanceAndOperations.SecondaryEquipm
[BsonDateTimeOptions(Kind = DateTimeKind.Local)]
[MongoDBDescendingIndex]
public DateTime Time { get; set; }
public string DiagnoseResultName{ get; set; }
public string DiaStatus { get; set; }
}

View File

@ -1236,6 +1236,12 @@
</summary>
<returns></returns>
</member>
<member name="M:YunDa.SOMS.MongoDB.Application.Inspection.InspectionItemResultAppService.TestGetAlarmMessage(System.String,System.String,System.String)">
<summary>
测试报警api
</summary>
<returns></returns>
</member>
<member name="M:YunDa.SOMS.MongoDB.Application.Inspection.InspectionItemResultAppService.GetAlarmMessage(System.Nullable{System.Guid},System.Int32,System.String)">
<summary>
获取报警信息
@ -1538,6 +1544,26 @@
<param name="stationId"></param>
<returns></returns>
</member>
<member name="M:YunDa.SOMS.MongoDB.Application.MeasuresTemperature.MeasuresTemperatureResultAppService.FindMeasureTempertureResults(YunDa.SOMS.DataTransferObject.PageSearchCondition{YunDa.SOMS.DataTransferObject.VideoSurveillance.MeasureTemperatureResultDto.SearchCondition.MeasureTemperatureResultSearchConditonInput})">
<summary>
查询温度测量结果(热成像设备)
</summary>
<param name="searchCondition">查询条件</param>
<returns></returns>
</member>
<member name="M:YunDa.SOMS.MongoDB.Application.MeasuresTemperature.MeasuresTemperatureResultAppService.ParseTemperatureFromResult(YunDa.SOMS.DataTransferObject.MainstationData.OriginalInspectionStoreResult,YunDa.SOMS.Entities.VideoSurveillance.PresetPoint)">
<summary>
从巡检结果数据中解析温度数据
</summary>
<param name="data">原始巡检结果数据</param>
<param name="preset">预置点信息</param>
<returns>温度测量结果列表</returns>
</member>
<member name="M:YunDa.SOMS.MongoDB.Application.MeasuresTemperature.MeasuresTemperatureResultAppService.CalculateSimilarity(System.String,System.String)">
<summary>
计算字符串相似度
</summary>
</member>
<member name="M:YunDa.SOMS.MongoDB.Application.MobileSurveillance.IRobotTaskAlarmResultAppService.CreateManyAsync(System.Collections.Generic.List{YunDa.SOMS.DataTransferObject.MobileSurveillance.RobotTaskAlarmResultDto.EditRobotTaskAlarmResultInput})">
<summary>
添加多条机器人巡检任务报警结果

View File

@ -27,7 +27,6 @@ namespace YunDa.SOMS.Entities.DataMonitoring.SecondaryCircuitInspection
/// 格式示例: {16385_0}==1&&{752}>1000
/// </summary>
[Required]
[StringLength(500)]
public virtual string TriggerExpression { get; set; }

View File

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Logging;
using Pomelo.EntityFrameworkCore.MySql;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure;
@ -10,37 +11,75 @@ namespace YunDa.SOMS.EntityFrameworkCore.EntityFrameworkCore
public static void Configure(
DbContextOptionsBuilder<SOMSDbContext> dbContextOptions,
string connectionString,
ILoggerFactory loggerFactory = null)
ILoggerFactory loggerFactory = null,
bool isDevelopment = false)
{
dbContextOptions.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString),
// 缓存 ServerVersion 以避免重复检测
var serverVersion = ServerVersion.AutoDetect(connectionString);
dbContextOptions.UseMySql(connectionString, serverVersion,
builder =>
{
builder.CommandTimeout(600);
// 启用连接重试机制(生产环境推荐)
//builder.EnableRetryOnFailure(
// maxRetryCount: 3,
// maxRetryDelay: TimeSpan.FromSeconds(5),
// errorNumbersToAdd: null
//);
// 性能优化选项
builder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery); // 避免笛卡尔爆炸
builder.MigrationsAssembly(typeof(SOMSDbContext).Assembly.GetName().Name);
}
)
.EnableSensitiveDataLogging() // 显示敏感数据(如参数值)
.EnableDetailedErrors() // 显示详细错误信息
);
// 仅在开发环境启用详细日志
if (isDevelopment)
{
dbContextOptions
.EnableSensitiveDataLogging()
.EnableDetailedErrors()
.LogTo(
Console.WriteLine, // 可以改为你的日志方法
Console.WriteLine,
new[] {
DbLoggerCategory.Database.Command.Name,
DbLoggerCategory.Database.Connection.Name,
DbLoggerCategory.Database.Transaction.Name,
DbLoggerCategory.Query.Name
},
LogLevel.Information // 或 LogLevel.Debug 获取更详细信息
LogLevel.Information
);
}
else
{
// 生产环境:只记录警告和错误
dbContextOptions.LogTo(
Console.WriteLine,
new[] {
DbLoggerCategory.Database.Command.Name,
DbLoggerCategory.Database.Connection.Name
},
LogLevel.Warning
);
}
// 如果传入了 loggerFactory使用它
// 使用外部 LoggerFactory如果提供
if (loggerFactory != null)
{
dbContextOptions.UseLoggerFactory(loggerFactory);
}
// 性能优化配置
dbContextOptions
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking) // 默认无跟踪查询
.ConfigureWarnings(warnings =>
{
// 忽略常见的非关键警告
warnings.Ignore(CoreEventId.FirstWithoutOrderByAndFilterWarning);
warnings.Ignore(CoreEventId.RowLimitingOperationWithoutOrderByWarning);
});
}
}
}

View File

@ -22,7 +22,7 @@ namespace YunDa.Server.ISMSTcp.Models
/// <summary>
/// 定值
/// </summary>
public decimal Value { get; set; }
public string Value { get; set; }
/// <summary>
/// 单位

View File

@ -258,23 +258,6 @@ namespace YunDa.Server.ISMSTcp.Services
if (contentToken is JArray contentArray && contentArray.Count > 0)
{
//2025-10-25 所有值加1 send CallYXByDevice|B001208
//foreach (var item in contentArray)
//{
// if (item["YX_ID"].Value<string>() == "YXB001103058")
// {
// int kk = 0;
// }
// if (item["V"] != null && item["V"].Type == JTokenType.String)
// {
// string val = item["V"].Value<string>();
// if(int.TryParse(val, out int value))
// {
// //item["V"] = (value + 1).ToString();
// }
// }
//}
List<TelesignalisationModel> telesignalisationModels = new List<TelesignalisationModel>();
@ -1136,9 +1119,9 @@ namespace YunDa.Server.ISMSTcp.Services
// 检查Value是否为非数字值如"退出"等中文字符)
if (!string.IsNullOrEmpty(valueString) && !decimal.TryParse(valueString, out _))
{
_logger.LogWarning("DZ数据Value字段包含非数字值: {Value}将设置为0", valueString);
_logger.LogWarning("DZ数据Value字段包含非数字值: {Value}", valueString);
// 将非数字值替换为0
jObject["Value"] = 0;
jObject["Value"] = valueString;
}
}
return item;

View File

@ -233,7 +233,7 @@ namespace YunDa.Server.ISMSTcp.Services
_ = Task.Run(async () =>
{
while (true)
{//每30秒更新一下配置
{//每10分钟更新一下配置
await UpdatePlans();
@ -241,7 +241,7 @@ namespace YunDa.Server.ISMSTcp.Services
//await CheckAiChannel();
await Task.Delay(30000);
await Task.Delay(TimeSpan.FromMinutes(10));
}
});
@ -256,11 +256,11 @@ namespace YunDa.Server.ISMSTcp.Services
{
await CheckPlan();
await Task.Delay(10000);
await Task.Delay(TimeSpan.FromSeconds(60));
}
else
{
await Task.Delay(10000);
await Task.Delay(TimeSpan.FromSeconds(60));
}
}
@ -278,14 +278,14 @@ namespace YunDa.Server.ISMSTcp.Services
}
else
{
await Task.Delay(10000);
await Task.Delay(TimeSpan.FromSeconds(60));
}
}
});
//执行计划(两个线程同时执行)
int threadNumber = _isDebug ? 1 : 3;
int threadNumber = _isDebug ? 1 : 1;
for (int i = 0; i < threadNumber; ++i)
{
@ -319,7 +319,7 @@ namespace YunDa.Server.ISMSTcp.Services
await CallAiAndSave(item);
await Task.Delay(500);
await Task.Delay(5000);
}
});
}
@ -571,60 +571,44 @@ namespace YunDa.Server.ISMSTcp.Services
for (int i = 0; i < item.TimeWindowCount; i++)
{
var tasks = new List<Task>();
Task<List<ZzDataResultModel>>? t1 = null;
Task<List<ZzDataResultModel>>? t2 = null;
Task<List<DeviceDzData>>? t3 = null;
Task<List<InspectionResultData>>? t4 = null;
Task<List<ZzDataResultModel>>? t5 = null;
Task<List<ZzDataResultModel>>? t6 = null;
List<ZzDataResultModel>? telemetryData = null;
List<ZzDataResultModel>? teleSignalData = null;
List<DeviceDzData>? settingData = null;
List<InspectionResultData>? presetData = null;
List<ZzDataResultModel>? gatewayData = null;
List<ZzDataResultModel>? variantData = null;
if (item.TelemetryConfigCount > 0)
{
t1 = GetSourceDataAsync<List<ZzDataResultModel>>(id, 1);
tasks.Add(t1);
telemetryData = await GetSourceDataAsync<List<ZzDataResultModel>>(id, 1);
}
if (item.TelesignalConfigCount > 0)
{
t2 = GetSourceDataAsync<List<ZzDataResultModel>>(id, 2);
tasks.Add(t2);
teleSignalData = await GetSourceDataAsync<List<ZzDataResultModel>>(id, 2);
}
if (item.DeviceConfigCount > 0)
{
t3 = GetSourceDataAsync<List<DeviceDzData>>(id, 3);
tasks.Add(t3);
settingData = await GetSourceDataAsync<List<DeviceDzData>>(id, 3);
}
if (item.CameraPresetCount > 0)
{
t4 = GetSourceDataAsync<List<InspectionResultData>>(id, 4);
tasks.Add(t4);
presetData = await GetSourceDataAsync<List<InspectionResultData>>(id, 4);
}
if (item.GatewayConfigCount > 0)
{
t5 = GetSourceDataAsync<List<ZzDataResultModel>>(id, 5);
tasks.Add(t5);
gatewayData = await GetSourceDataAsync<List<ZzDataResultModel>>(id, 5);
}
if (item.VariantConfigCount > 0)
{
t6 = GetSourceDataAsync<List<ZzDataResultModel>>(id, 6);
tasks.Add(t6);
variantData = await GetSourceDataAsync<List<ZzDataResultModel>>(id, 6);
}
await Task.WhenAll(tasks);
if (t1 != null) jsData.StoreData.TelemetryData = await t1;
if (t2 != null) jsData.StoreData.TeleSignalData = await t2;
if (t3 != null) jsData.StoreData.SettingData = await t3;
if (t4 != null) jsData.StoreData.PresetData = await t4;
if (t5 != null) jsData.StoreData.GatewayData = await t5;
if (t6 != null) jsData.StoreData.VariantData = await t6;
jsData.StoreData.TelemetryData = telemetryData;
jsData.StoreData.TeleSignalData = teleSignalData;
jsData.StoreData.SettingData = settingData;
jsData.StoreData.PresetData = presetData;
jsData.StoreData.GatewayData = gatewayData;
jsData.StoreData.VariantData = variantData;
if (jsData.StoreData.TelemetryData == null && jsData.StoreData.TeleSignalData == null && jsData.StoreData.SettingData == null &&
jsData.StoreData.PresetData == null && jsData.StoreData.GatewayData == null && jsData.StoreData.VariantData == null)
@ -632,27 +616,20 @@ namespace YunDa.Server.ISMSTcp.Services
continue;
}
var json = JsonConvert.SerializeObject(jsData,
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
var js = $"JSON.parse('{json.Replace("'", "\\'")}')";
var jsObj = engine.Evaluate(js).ToObject();
var jsResult = engine.Invoke("calculate", jsObj).AsObject();
if (jsResult != null && jsResult.HasProperty("status"))
{
saveObj = jsResult;
var status = jsResult.Get("status").ToString();
if (status == "正常" || string.IsNullOrWhiteSpace(status))
{//只要正常,就不用再检测了
{
break;
}
}

View File

@ -59,11 +59,11 @@ namespace YunDa.Server.ISMSTcp.Services
if (protectionDeviceCommInfos == null || !protectionDeviceCommInfos.Any())
{
_logger.LogWarning("Redis中未获取到保护装置通信信息跳过本次召唤");
return;
//return;
}
// 只处理在线的设备
var onlineDevices = protectionDeviceCommInfos.Where(d => d.IsOnline).ToList();
var onlineDevices = protectionDeviceCommInfos.ToList();
_logger.LogInformation("从Redis获取到 {TotalCount} 个保护装置,其中在线设备 {OnlineCount} 个",
protectionDeviceCommInfos.Count, onlineDevices.Count);
@ -99,12 +99,15 @@ namespace YunDa.Server.ISMSTcp.Services
// 再次检查TCP连接状态防止在循环过程中连接断开
if (!_tcpClient.IsConnected)
{
_logger.LogWarning("TCP连接已断开等待5S发送召唤命令");
Task.Delay(5000).Wait();
if (!_tcpClient.IsConnected)
{
_logger.LogWarning("TCP连接已断开停止发送召唤命令");
failureCount++;
failedDevices.Add($"{device.DeviceId}({device.DeviceName})");
continue;
}
}
// 构造召唤命令CallYCByDevice|{装置ID}
string command = $"CallYCByDevice|{device.DeviceId}";
@ -132,7 +135,7 @@ namespace YunDa.Server.ISMSTcp.Services
_yxCount = (_yxCount + 1) % 6;
// 每个命令之间间隔100毫秒
await Task.Delay(100);
await Task.Delay(1000);
}
catch (Exception ex)
{

View File

@ -103,14 +103,14 @@ namespace YunDa.Server.ISMSTcp.Services
}
// 检查设备通信状态
bool isCommNormal = await _deviceCommunicationStateService.IsDeviceCommunicationNormalAsync(device.Id, cancellationToken);
if (!isCommNormal)
{
_logger.LogWarning("装置通信状态异常,取消数据召唤操作 - 设备ID: {DeviceId} ({DeviceName})", device.Id, device.DeviceName);
commStateSkippedCount++;
commStateSkippedDevices.Add($"{device.Id}({device.DeviceName})");
continue;
}
//bool isCommNormal = await _deviceCommunicationStateService.IsDeviceCommunicationNormalAsync(device.Id, cancellationToken);
//if (!isCommNormal)
//{
// _logger.LogWarning("装置通信状态异常,取消数据召唤操作 - 设备ID: {DeviceId} ({DeviceName})", device.Id, device.DeviceName);
// commStateSkippedCount++;
// commStateSkippedDevices.Add($"{device.Id}({device.DeviceName})");
// continue;
//}
// 再次检查TCP连接状态防止在循环过程中连接断开
if (!_tcpClient.IsConnected)

View File

@ -10,8 +10,8 @@
},
"ISMSServer": {
"ServerIP": "192.168.81.21",
"HeartbeatIntervalSeconds": 60,
"AutoConnectDelaySeconds": 10
"HeartbeatIntervalSeconds": 1800,
"AutoConnectDelaySeconds": 60
},
"ScheduledTelemetry": {
"IntervalMinutes": 30

View File

@ -14,12 +14,12 @@
"IncompleteDataTimeoutSeconds": 5,
"BufferSize": 1024,
"EnableHeartbeat": true,
"HeartbeatIntervalSeconds": 30,
"HeartbeatIntervalSeconds": 1800,
"HeartbeatTimeoutSeconds": 10,
"HeartbeatMessage": "HEARTBEAT_PING",
"EnableAutoConnect": true,
"AutoConnectDelaySeconds": 3,
"ConnectionTimeoutSeconds": 30,
"ConnectionTimeoutSeconds": 180,
"EnableConnectionRetry": true
},
"ApiEndpoints": {
@ -34,7 +34,7 @@
},
"ScheduledTelemetry": {
"Enabled": true,
"IntervalSeconds": 60,
"IntervalSeconds": 1800,
"MaxRetries": 10,
"RetryDelayMs": 2000,
"CommandDelayMs": 100