Compare commits
4 Commits
111f8d06ff
...
326d50630a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
326d50630a | ||
|
|
1fc9614257 | ||
|
|
1d0d933aa5 | ||
|
|
52290ac5f7 |
@ -378,6 +378,28 @@
|
|||||||
<param name="videos">Video devices list</param>
|
<param name="videos">Video devices list</param>
|
||||||
<param name="presets">Preset points list</param>
|
<param name="presets">Preset points list</param>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:YunDa.SOMS.ExternalInteraction.Application.MainStation.HandleUploadInspectionItems.Services.IBatchOperationService">
|
||||||
|
<summary>
|
||||||
|
Batch operation service interface for optimizing database operations
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:YunDa.SOMS.ExternalInteraction.Application.MainStation.HandleUploadInspectionItems.Services.IBatchOperationService.BatchInsertInspectionResultsAsync(System.Collections.Generic.List{YunDa.SOMS.DataTransferObject.MainstationData.OriginalInspectionStoreResult},System.Threading.CancellationToken)">
|
||||||
|
<summary>
|
||||||
|
Batch insert inspection results into MongoDB with automatic partitioning
|
||||||
|
</summary>
|
||||||
|
<param name="items">Collection of inspection results to insert</param>
|
||||||
|
<param name="cancellationToken">Cancellation token for async operation</param>
|
||||||
|
<returns>True if all batches inserted successfully, false otherwise</returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:YunDa.SOMS.ExternalInteraction.Application.MainStation.HandleUploadInspectionItems.Services.IBatchOperationService.BatchInsertInspectionResultsAsync(System.Collections.Generic.List{YunDa.SOMS.DataTransferObject.MainstationData.OriginalInspectionStoreResult},System.Int32,System.Threading.CancellationToken)">
|
||||||
|
<summary>
|
||||||
|
Batch insert inspection results with custom batch size
|
||||||
|
</summary>
|
||||||
|
<param name="items">Collection of inspection results to insert</param>
|
||||||
|
<param name="batchSize">Custom batch size for partitioning</param>
|
||||||
|
<param name="cancellationToken">Cancellation token for async operation</param>
|
||||||
|
<returns>True if all batches inserted successfully, false otherwise</returns>
|
||||||
|
</member>
|
||||||
<member name="T:YunDa.SOMS.ExternalInteraction.Application.PatternRecognition.MainstationGetTempService">
|
<member name="T:YunDa.SOMS.ExternalInteraction.Application.PatternRecognition.MainstationGetTempService">
|
||||||
<summary>
|
<summary>
|
||||||
对外通信-主站额外需求
|
对外通信-主站额外需求
|
||||||
|
|||||||
@ -1417,6 +1417,12 @@
|
|||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</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)">
|
<member name="M:YunDa.SOMS.MongoDB.Application.Inspection.InspectionItemResultAppService.GetAlarmMessage(System.Nullable{System.Guid},System.Int32,System.String)">
|
||||||
<summary>
|
<summary>
|
||||||
获取报警信息
|
获取报警信息
|
||||||
|
|||||||
@ -150,6 +150,10 @@ namespace YunDa.Server.ISMSTcp.Configuration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string GetOpticalCableConfigUri => $"{BaseUrl.TrimEnd('/')}/api/services/SOMS/OpticalCable/GetList";
|
public string GetOpticalCableConfigUri => $"{BaseUrl.TrimEnd('/')}/api/services/SOMS/OpticalCable/GetList";
|
||||||
|
|
||||||
|
|
||||||
|
//获取架式设备配置
|
||||||
|
public string GetRackEquipmentConfig => $"{BaseUrl.TrimEnd('/')}/api/services/SOMS/RackEquipment/GetList";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 保存巡检计划执行结果
|
/// 保存巡检计划执行结果
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -37,6 +37,8 @@ namespace YunDa.Server.ISMSTcp.Controllers
|
|||||||
private readonly TelesignalisationHandle _telesignalisationHandle;
|
private readonly TelesignalisationHandle _telesignalisationHandle;
|
||||||
private readonly GwErrorRatioService _gwErrorRatioService;
|
private readonly GwErrorRatioService _gwErrorRatioService;
|
||||||
private readonly VirtualTerminalHandler _virtualTerminalHandler;
|
private readonly VirtualTerminalHandler _virtualTerminalHandler;
|
||||||
|
private readonly SecondaryCircuitInspectionPlanService _secondaryCircuitInspectionPlanService;
|
||||||
|
private readonly ThingService _thingService;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造函数
|
/// 构造函数
|
||||||
@ -58,7 +60,9 @@ namespace YunDa.Server.ISMSTcp.Controllers
|
|||||||
TelemeteringHandle telemeteringHandle,
|
TelemeteringHandle telemeteringHandle,
|
||||||
TelesignalisationHandle telesignalisationHandle,
|
TelesignalisationHandle telesignalisationHandle,
|
||||||
GwErrorRatioService gwErrorRatioService,
|
GwErrorRatioService gwErrorRatioService,
|
||||||
VirtualTerminalHandler virtualTerminalHandler)
|
VirtualTerminalHandler virtualTerminalHandler,
|
||||||
|
SecondaryCircuitInspectionPlanService secondaryCircuitInspectionPlanService,
|
||||||
|
ThingService thingService)
|
||||||
{
|
{
|
||||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
_queryService = queryService ?? throw new ArgumentNullException(nameof(queryService));
|
_queryService = queryService ?? throw new ArgumentNullException(nameof(queryService));
|
||||||
@ -70,6 +74,8 @@ namespace YunDa.Server.ISMSTcp.Controllers
|
|||||||
_telesignalisationHandle = telesignalisationHandle ?? throw new ArgumentNullException(nameof(telesignalisationHandle));
|
_telesignalisationHandle = telesignalisationHandle ?? throw new ArgumentNullException(nameof(telesignalisationHandle));
|
||||||
_gwErrorRatioService = gwErrorRatioService ?? throw new ArgumentNullException(nameof(gwErrorRatioService));
|
_gwErrorRatioService = gwErrorRatioService ?? throw new ArgumentNullException(nameof(gwErrorRatioService));
|
||||||
_virtualTerminalHandler = virtualTerminalHandler ?? throw new ArgumentNullException(nameof(virtualTerminalHandler));
|
_virtualTerminalHandler = virtualTerminalHandler ?? throw new ArgumentNullException(nameof(virtualTerminalHandler));
|
||||||
|
_secondaryCircuitInspectionPlanService = secondaryCircuitInspectionPlanService ?? throw new ArgumentNullException(nameof(secondaryCircuitInspectionPlanService));
|
||||||
|
_thingService = thingService ?? throw new ArgumentNullException( nameof(thingService));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -255,49 +261,6 @@ namespace YunDa.Server.ISMSTcp.Controllers
|
|||||||
return StatusCode(500, $"服务器内部错误: {ex.Message}");
|
return StatusCode(500, $"服务器内部错误: {ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<string> GetValidZzCmd(string cmdName, List<string> ids)
|
|
||||||
{
|
|
||||||
const int maxLength = 250;
|
|
||||||
|
|
||||||
var cmds = new List<string>();
|
|
||||||
|
|
||||||
// 开始构建
|
|
||||||
string prefix = cmdName + "|"; // 固定前缀
|
|
||||||
int prefixLength = prefix.Length;
|
|
||||||
|
|
||||||
var currentIds = new List<string>();
|
|
||||||
int currentLength = prefixLength; // 当前命令的长度(含前缀)
|
|
||||||
|
|
||||||
foreach (var id in ids)
|
|
||||||
{
|
|
||||||
// 如果添加这个ID会超长,则先生成一个命令
|
|
||||||
int idLength = (currentIds.Count == 0 ? id.Length : (1 + id.Length)); // 第一个ID不需要 '#'
|
|
||||||
|
|
||||||
if (currentLength + idLength > maxLength)
|
|
||||||
{
|
|
||||||
// 将当前批次加入 cmds
|
|
||||||
cmds.Add(prefix + string.Join("#", currentIds));
|
|
||||||
|
|
||||||
// 清空并重建
|
|
||||||
currentIds.Clear();
|
|
||||||
currentLength = prefixLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加新的 ID
|
|
||||||
currentIds.Add(id);
|
|
||||||
currentLength += idLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 收尾:如果还有剩余 IDs,生成最后一个命令
|
|
||||||
if (currentIds.Count > 0)
|
|
||||||
{
|
|
||||||
cmds.Add(prefix + string.Join("#", currentIds));
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据数据ID召唤遥测数据
|
/// 根据数据ID召唤遥测数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -320,21 +283,18 @@ namespace YunDa.Server.ISMSTcp.Controllers
|
|||||||
[FromBody] ZzDataRequestModel request,
|
[FromBody] ZzDataRequestModel request,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var id = request.Id;
|
var ids = request.Id;
|
||||||
var times = request.Times;
|
var times = request.Times;
|
||||||
|
|
||||||
id.RemoveAll(string.IsNullOrWhiteSpace);
|
ids.RemoveAll(string.IsNullOrWhiteSpace);
|
||||||
|
|
||||||
//string cmd = string.Format("CallYCByDataID|{0}", string.Join("#", id));
|
_logger.LogWarning("收到 CallYCByDataId");
|
||||||
|
|
||||||
//System.Console.WriteLine($"发送遥测命令:{cmd}");
|
|
||||||
|
|
||||||
var cmds = GetValidZzCmd("CallYCByDataID", id);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 参数验证
|
// 参数验证
|
||||||
if (id.Count == 0)
|
if (ids.Count == 0)
|
||||||
{
|
{
|
||||||
return BadRequest(new
|
return BadRequest(new
|
||||||
{
|
{
|
||||||
@ -344,64 +304,23 @@ namespace YunDa.Server.ISMSTcp.Controllers
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("收到遥测数据召唤请求 - cmd: {cmd}", string.Join("#", id));
|
|
||||||
// 发送TCP消息
|
|
||||||
|
|
||||||
DateTime cmdTime = DateTime.Now;
|
|
||||||
|
|
||||||
int sucessCount = 0;
|
|
||||||
|
|
||||||
if(request.TimeWindowType == 1 || request.TimeWindowType == 2)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < times; i++)
|
|
||||||
{
|
|
||||||
bool isSuccess = true;
|
|
||||||
|
|
||||||
foreach (var cmd in cmds)
|
|
||||||
{
|
|
||||||
var sendResult = await SendTcpMessageAsync(cmd, cancellationToken);
|
|
||||||
isSuccess &= sendResult.Success;
|
|
||||||
if (!isSuccess)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await Task.Delay(5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSuccess)
|
|
||||||
{
|
|
||||||
sucessCount++;
|
|
||||||
}
|
|
||||||
await Task.Delay(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sucessCount = 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (times - sucessCount < 3)
|
|
||||||
{
|
|
||||||
List<ZzDataResultModel>? ycDataList = null;
|
List<ZzDataResultModel>? ycDataList = null;
|
||||||
|
|
||||||
var sw = Stopwatch.StartNew();
|
|
||||||
|
|
||||||
while (sw.ElapsedMilliseconds < 10 * 1000)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
ycDataList = await _telemeteringHandle.GetYCDataByDataIds(id, times, request.TimeWindowType, cancellationToken, cmdTime);
|
ycDataList = await _telemeteringHandle.GetYCDataByDataIds(ids, times, request.TimeWindowType, cancellationToken);
|
||||||
|
|
||||||
if (ycDataList.Count == id.Count)
|
if (ycDataList.Count == ids.Count)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
|
||||||
await Task.Delay(100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ycDataList?.Count == id.Count)
|
if(request.TimeWindowType == 0)
|
||||||
|
await Task.Delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ycDataList?.Count == ids.Count)
|
||||||
{
|
{
|
||||||
return Ok(new
|
return Ok(new
|
||||||
{
|
{
|
||||||
@ -421,21 +340,10 @@ namespace YunDa.Server.ISMSTcp.Controllers
|
|||||||
timestamp = DateTime.Now
|
timestamp = DateTime.Now
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return StatusCode(500, new
|
|
||||||
{
|
|
||||||
success = false,
|
|
||||||
message = $"发送命令失败",
|
|
||||||
timestamp = DateTime.Now
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("遥测数据召唤请求被取消 - cmd: {cmd}", string.Join("#", id));
|
_logger.LogWarning("遥测数据召唤请求被取消 - cmd: {cmd}", string.Join("#", ids));
|
||||||
return StatusCode(504, new
|
return StatusCode(504, new
|
||||||
{
|
{
|
||||||
success = false,
|
success = false,
|
||||||
@ -445,7 +353,7 @@ namespace YunDa.Server.ISMSTcp.Controllers
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "处理遥测数据召唤请求时发生异常 - cmd: {cmd}", string.Join("#", id));
|
_logger.LogError(ex, "处理遥测数据召唤请求时发生异常 - cmd: {cmd}", string.Join("#", ids));
|
||||||
return StatusCode(500, new
|
return StatusCode(500, new
|
||||||
{
|
{
|
||||||
success = false,
|
success = false,
|
||||||
@ -1163,6 +1071,103 @@ namespace YunDa.Server.ISMSTcp.Controllers
|
|||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
[HttpGet("UpdateConfig")]
|
||||||
|
public async Task<IActionResult> UpdateConfig([FromQuery] int configType)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (configType)
|
||||||
|
{
|
||||||
|
//更新计划巡检、事件巡检
|
||||||
|
case 1:
|
||||||
|
await _secondaryCircuitInspectionPlanService.UpdatePlanConfig();
|
||||||
|
break;
|
||||||
|
|
||||||
|
//更新网线配置
|
||||||
|
case 2:
|
||||||
|
await _thingService.UpdateNetworkCableConfig();
|
||||||
|
break;
|
||||||
|
|
||||||
|
//更新光纤配置
|
||||||
|
case 3:
|
||||||
|
await _thingService.UpdateOpticalFiberConfig();
|
||||||
|
break;
|
||||||
|
|
||||||
|
//更新光缆配置
|
||||||
|
case 4:
|
||||||
|
await _thingService.UpdateOpticalCableConfig();
|
||||||
|
break;
|
||||||
|
|
||||||
|
//更新架式设备配置、孪生体与遥测数据绑定关系、设备和孪生体的关联
|
||||||
|
case 5:
|
||||||
|
await _thingService.UpdateRackEquipmentConfig();
|
||||||
|
await _thingService.UpdateDeviceBindingConfig();
|
||||||
|
await _thingService.UpdateSimDatasConfig();
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
return BadRequest(new
|
||||||
|
{
|
||||||
|
success = false,
|
||||||
|
message = "错误configType",
|
||||||
|
timestamp = DateTime.Now
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation($"收到配置更新命令:configType = {configType}");
|
||||||
|
|
||||||
|
|
||||||
|
return Ok(new
|
||||||
|
{
|
||||||
|
success = true,
|
||||||
|
message = "更新成功",
|
||||||
|
timestamp = DateTime.Now
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return StatusCode(500, $"更新失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("ClearAllThingAlarm")]
|
||||||
|
public async Task<IActionResult> ClearAllThingAlarm()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool success = await _thingService.ClearAllAlarm();
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
|
||||||
|
return Ok(new
|
||||||
|
{
|
||||||
|
success = true,
|
||||||
|
message = "清除成功",
|
||||||
|
timestamp = DateTime.Now
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return BadRequest(new
|
||||||
|
{
|
||||||
|
success = false,
|
||||||
|
message = "清除失败",
|
||||||
|
timestamp = DateTime.Now
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return StatusCode(500, $"清除失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -107,6 +107,9 @@ namespace YunDa.Server.ISMSTcp.Domain
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
string GetOpticalCableConfigUri { get; }
|
string GetOpticalCableConfigUri { get; }
|
||||||
|
|
||||||
|
//获取架式设备配置
|
||||||
|
string GetRackEquipmentConfig { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 保存巡检计划执行结果
|
/// 保存巡检计划执行结果
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -251,6 +254,9 @@ namespace YunDa.Server.ISMSTcp.Domain
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string GetOpticalCableConfigUri => _config.GetOpticalCableConfigUri;
|
public string GetOpticalCableConfigUri => _config.GetOpticalCableConfigUri;
|
||||||
|
|
||||||
|
//获取架式设备配置
|
||||||
|
public string GetRackEquipmentConfig => _config.GetRackEquipmentConfig;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 保存巡检计划执行结果
|
/// 保存巡检计划执行结果
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -700,12 +700,12 @@ namespace YunDa.Server.ISMSTcp.Domain
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取孪生体与遥测数据绑定关系
|
/// 获取孪生体与遥测数据绑定关系
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<List<ThingDeviceBindingModel>> GetThingDeviceBindingConfigAsync()
|
public async Task<List<ThingDeviceBindingModel>> GetThingDeviceBindingConfigAsync(int pageIndex, int pageSize)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
var response = await HttpHelper.HttpPostRequestAsync<JObject>(_apiEndpoints.ThingDeviceBindingConfigUri, new object());
|
var response = await HttpHelper.HttpPostRequestAsync<JObject>(_apiEndpoints.ThingDeviceBindingConfigUri, new { pageIndex = pageIndex, pageSize = pageSize });
|
||||||
|
|
||||||
if (response != null)
|
if (response != null)
|
||||||
{
|
{
|
||||||
@ -908,12 +908,12 @@ namespace YunDa.Server.ISMSTcp.Domain
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取网线配置
|
/// 获取网线配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<List<OpticalFiberConfigModel>> GetNetworkCableConfigAsync()
|
public async Task<List<OpticalFiberConfigModel>> GetNetworkCableConfigAsync(int pageIndex, int pageSize)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
var response = await Task.Run(() => HttpHelper.HttpPostRequestAsync<JObject>(_apiEndpoints.GetNetworkCableConfigUri, new object()));
|
var response = await Task.Run(() => HttpHelper.HttpPostRequestAsync<JObject>(_apiEndpoints.GetNetworkCableConfigUri, new { pageIndex = pageIndex, pageSize = pageSize }));
|
||||||
|
|
||||||
if (response != null)
|
if (response != null)
|
||||||
{
|
{
|
||||||
@ -947,12 +947,12 @@ namespace YunDa.Server.ISMSTcp.Domain
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取光纤配置
|
/// 获取光纤配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<List<OpticalFiberConfigModel>> GetOpticalFiberConfigAsync()
|
public async Task<List<OpticalFiberConfigModel>> GetOpticalFiberConfigAsync(int pageIndex, int pageSize)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
var response = await Task.Run(() => HttpHelper.HttpPostRequestAsync<JObject>(_apiEndpoints.GetOpticalFiberConfigUri, new object()));
|
var response = await Task.Run(() => HttpHelper.HttpPostRequestAsync<JObject>(_apiEndpoints.GetOpticalFiberConfigUri, new { pageIndex = pageIndex, pageSize = pageSize }));
|
||||||
|
|
||||||
if (response != null)
|
if (response != null)
|
||||||
{
|
{
|
||||||
@ -985,11 +985,11 @@ namespace YunDa.Server.ISMSTcp.Domain
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取光缆配置
|
/// 获取光缆配置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<List<OpticalFiberConfigModel>> GetOpticalCableConfigAsync()
|
public async Task<List<OpticalFiberConfigModel>> GetOpticalCableConfigAsync(int pageIndex, int pageSize)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = await Task.Run(() => HttpHelper.HttpPostRequestAsync<JObject>(_apiEndpoints.GetOpticalCableConfigUri, new { includeInspectionItems = true }));
|
var response = await Task.Run(() => HttpHelper.HttpPostRequestAsync<JObject>(_apiEndpoints.GetOpticalCableConfigUri, new { pageIndex = pageIndex, pageSize = pageSize }));
|
||||||
|
|
||||||
if (response != null)
|
if (response != null)
|
||||||
{
|
{
|
||||||
@ -1007,6 +1007,31 @@ namespace YunDa.Server.ISMSTcp.Domain
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///获取架式设备配置
|
||||||
|
public async Task<List<OpticalFiberConfigModel>> GetRackEquipmentConfigAsync(int pageIndex, int pageSize)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var response = await Task.Run(() => HttpHelper.HttpPostRequestAsync<JObject>(_apiEndpoints.GetRackEquipmentConfig, new { pageIndex = pageIndex, pageSize = pageSize }));
|
||||||
|
|
||||||
|
if (response != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
var result = ExtractDataFromAbpResponse<List<OpticalFiberConfigModel>>(response);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error Call GetRackEquipmentConfigAsync Api");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 保存巡检计划执行结果
|
/// 保存巡检计划执行结果
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -132,6 +132,7 @@ namespace YunDa.Server.ISMSTcp.Extensions
|
|||||||
services.AddSingleton<GwErrorRatioService>();
|
services.AddSingleton<GwErrorRatioService>();
|
||||||
services.AddSingleton<ZzTcpService>();
|
services.AddSingleton<ZzTcpService>();
|
||||||
services.AddSingleton<ZzDataCacheContainerInit>();
|
services.AddSingleton<ZzDataCacheContainerInit>();
|
||||||
|
services.AddSingleton<ZzDataCmdService>();
|
||||||
|
|
||||||
// 日志过滤器配置
|
// 日志过滤器配置
|
||||||
services.Configure<YunDa.Server.ISMSTcp.Filters.Configuration.LogFilterConfiguration>(
|
services.Configure<YunDa.Server.ISMSTcp.Filters.Configuration.LogFilterConfiguration>(
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace YunDa.Server.ISMSTcp.Helpers
|
||||||
|
{
|
||||||
|
public static class StringHelper
|
||||||
|
{
|
||||||
|
public static string GetAfterLastOfAny(string input, params char[] separators)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(input) || separators == null || separators.Length == 0)
|
||||||
|
return input;
|
||||||
|
|
||||||
|
int index = input.AsSpan().LastIndexOfAny(separators);
|
||||||
|
return index >= 0
|
||||||
|
? input.Substring(index + 1)
|
||||||
|
: input;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,151 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using YunDa.Server.ISMSTcp.Services;
|
||||||
|
using YunDa.SOMS.DataTransferObject.DataMonitoring.SecondaryCircuitInspection;
|
||||||
|
using YunDa.SOMS.DataTransferObject.MaintenanceAndOperations.SecondaryEquipment;
|
||||||
|
using YunDa.SOMS.Entities.DataMonitoring.SecondaryCircuitInspection;
|
||||||
|
|
||||||
|
namespace YunDa.Server.ISMSTcp.Models
|
||||||
|
{
|
||||||
|
//带执行状态的巡检计划结构体
|
||||||
|
public class SecondaryCircuitInspectionPlanStateModel
|
||||||
|
{
|
||||||
|
//执行时间
|
||||||
|
public DateTime ExecuteTime { get; set; } = DateTime.MinValue;
|
||||||
|
|
||||||
|
public SecondaryCircuitInspectionPlanOutput Plan { get; set; }
|
||||||
|
|
||||||
|
public SecondaryCircuitInspectionPlanStateModel()
|
||||||
|
{
|
||||||
|
Plan = new SecondaryCircuitInspectionPlanOutput();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class SecondaryCircuitInspectionItemOutputEx
|
||||||
|
{
|
||||||
|
public int TriggerType { get; set; }
|
||||||
|
|
||||||
|
public SecondaryCircuitInspectionItemOutput Item { get; set; }
|
||||||
|
|
||||||
|
public string PlanId { get; set; }
|
||||||
|
|
||||||
|
public SecondaryCircuitInspectionItemOutputEx(int triggerType, SecondaryCircuitInspectionItemOutput item, string planId)
|
||||||
|
{
|
||||||
|
TriggerType = triggerType;
|
||||||
|
Item = item;
|
||||||
|
PlanId = planId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DeviceDzData
|
||||||
|
{
|
||||||
|
public List<DzInfo> UserDz { get; set; }
|
||||||
|
|
||||||
|
public List<DzInfo> SysDz { get; set; }
|
||||||
|
|
||||||
|
public string DeviceName { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InspectionResultData
|
||||||
|
{
|
||||||
|
public string PresetName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public int PresetCode { get; set; }
|
||||||
|
|
||||||
|
public string TimeStamp { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string Value { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class SecondaryCircuitInspectionStoreDataModel
|
||||||
|
{
|
||||||
|
//遥测数据
|
||||||
|
public List<ZzDataResultModel> TelemetryData { get; set; }
|
||||||
|
|
||||||
|
//遥信数据
|
||||||
|
public List<ZzDataResultModel> TeleSignalData { get; set; }
|
||||||
|
|
||||||
|
//定值
|
||||||
|
public List<DeviceDzData> SettingData { get; set; }
|
||||||
|
|
||||||
|
//预置位
|
||||||
|
public List<InspectionResultData> PresetData { get; set; }
|
||||||
|
|
||||||
|
//虚点数据
|
||||||
|
public List<ZzDataResultModel> VariantData { get; set; }
|
||||||
|
|
||||||
|
//网关数据
|
||||||
|
public List<ZzDataResultModel> GatewayData { get; set; }
|
||||||
|
|
||||||
|
public bool IsAllDataNull()
|
||||||
|
{
|
||||||
|
return (TelemetryData == null && TeleSignalData == null && SettingData == null &&
|
||||||
|
PresetData == null && GatewayData == null && VariantData == null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//巡检结果
|
||||||
|
public class SecondaryCircuitInspectionJsDataModel
|
||||||
|
{
|
||||||
|
public int TimeWindowSeconds { get; set; }
|
||||||
|
public int TimeWindowCount { get; set; }
|
||||||
|
public TimeWindowTypeEnum TimeWindowType { get; set; }
|
||||||
|
|
||||||
|
public SecondaryCircuitInspectionStoreDataModel StoreData { get; set; } = new SecondaryCircuitInspectionStoreDataModel();
|
||||||
|
public List<SecondaryCircuitInspectionTelemetryConfigOutput> TelemetryConfigs { get; set; }
|
||||||
|
public List<SecondaryCircuitInspectionTelesignalConfigOutput> TelesignalConfigs { get; set; }
|
||||||
|
public List<SecondaryCircuitInspectionCameraPresetOutput> CameraPresets { get; set; }
|
||||||
|
public List<SecondaryCircuitInspectionDeviceConfigOutput> DeviceConfigs { get; set; }
|
||||||
|
public List<SecondaryCircuitInspectionVariantOutput> VariantConfigs { get; set; }
|
||||||
|
public List<SecondaryCircuitInspectionGatewayOutput> GatewayConfigs { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//巡检结果上传Model
|
||||||
|
public class SecondaryCircuitInspectionResultSaveModel
|
||||||
|
{
|
||||||
|
public string SecondaryCircuitInspectionItemId { get; set; } = string.Empty;
|
||||||
|
public string InspectionPlanId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string ExecutionTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
public long ExecutionDurationMs { get; set; }
|
||||||
|
|
||||||
|
public int TriggerType { get; set; } //1计划,2事件
|
||||||
|
|
||||||
|
public string TriggerEventId { get; set; } = string.Empty;
|
||||||
|
public string Status { get; set; } = string.Empty; //"异常|正常|故障",
|
||||||
|
public string InspectionResult { get; set; } = string.Empty; //巡检结果 inspectionResult不能超过15个字符
|
||||||
|
public string CalculationProcess { get; set; } = string.Empty; //计算过程
|
||||||
|
public string VerificationResult { get; set; } = string.Empty; //校验结果
|
||||||
|
public SecondaryCircuitInspectionJsDataModel Data { get; set; }
|
||||||
|
public string Remark { get; set; } = string.Empty; //无用
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
public class SecondaryCircuitInspectionAiParamModel
|
||||||
|
{
|
||||||
|
public string InspectionResultId { get; set; } = string.Empty;
|
||||||
|
public string InspectionName { get; set; } = string.Empty;
|
||||||
|
public string InspectionDescription { get; set; } = string.Empty;
|
||||||
|
public string PlanName => string.Concat(InspectionName, " ", InspectionDescription);
|
||||||
|
public string Status { get; set; } = string.Empty; //"异常|正常|故障",
|
||||||
|
public string InspectionResult { get; set; } = string.Empty; //巡检结果 inspectionResult不能超过15个字符
|
||||||
|
public string CalculationProcess { get; set; } = string.Empty; //计算过程
|
||||||
|
public string VerificationResult { get; set; } = string.Empty; //校验结果
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SecondaryCircuitInspectionAiSaveModel
|
||||||
|
{
|
||||||
|
public string InspectionResultId { get; set; } = string.Empty;
|
||||||
|
public string AiAnalysisResult { get; set; } = string.Empty; // "AI结果状态:失败|成功",
|
||||||
|
public string ResultHandleDescription { get; set; } = string.Empty; //"AI返回的处理结果"
|
||||||
|
}
|
||||||
|
}
|
||||||
174
src/YunDa.Server/YunDa.Server.ISMSTcp/Models/ThingModel.cs
Normal file
174
src/YunDa.Server/YunDa.Server.ISMSTcp/Models/ThingModel.cs
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
using Esprima.Ast;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using YunDa.Server.ISMSTcp.Helpers;
|
||||||
|
using YunDa.SOMS.DataTransferObject.MaintenanceAndOperations.SecondaryEquipment;
|
||||||
|
using YunDa.SOMS.Entities.ExternalEntities.BeijingYounuo;
|
||||||
|
|
||||||
|
namespace YunDa.Server.ISMSTcp.Models
|
||||||
|
{
|
||||||
|
//ThingApiService配置
|
||||||
|
public class ThingApiServiceSettings
|
||||||
|
{
|
||||||
|
public string ApiServerUrl { get; set; } = string.Empty;
|
||||||
|
public string LoginCode { get; set; } = string.Empty;
|
||||||
|
public string LoginKey { get; set; } = string.Empty;
|
||||||
|
public string EsAuthorization { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ThingDeviceStatusModel
|
||||||
|
{
|
||||||
|
public string TwinID { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string Metric { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string Val { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ThingDeviceBindingModel
|
||||||
|
{
|
||||||
|
public string Description { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string TwinID { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string Metric { get; set; } = string.Empty; //格式:1:绿灯1|0:红灯1
|
||||||
|
|
||||||
|
public string Val { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public int TwinDataBindingType { get; set; }
|
||||||
|
|
||||||
|
public string Remark { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public bool IsActive { get; set; }
|
||||||
|
|
||||||
|
public string Id { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public TelesignalisationConfigurationModel TelesignalisationConfiguration { get; set; }
|
||||||
|
|
||||||
|
public List<ThingDevicePushDataModel> MetricList { get; set; }
|
||||||
|
|
||||||
|
public List<ThingDevicePushDataModel> ValList { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TelesignalisationConfigurationModel
|
||||||
|
{
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public int DispatcherAddress { get; set; }
|
||||||
|
|
||||||
|
public string IsmsbaseYXId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public int RemoteType { get; set; }
|
||||||
|
|
||||||
|
public string Id { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ThingDevicePushDataModel
|
||||||
|
{
|
||||||
|
public string Val { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string Cmd { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string CloseCmd { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
//性能数据
|
||||||
|
public class TingSimDataModel
|
||||||
|
{
|
||||||
|
public string TwinId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string EquipmentInfoId { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string EquipmentInfoName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public bool IsActive { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
//告警推送数据
|
||||||
|
public class TingAlarmPushDataModel
|
||||||
|
{
|
||||||
|
public string TwinId { get; set; } = string.Empty; //孪生体Id ******
|
||||||
|
|
||||||
|
public int Severity { get; set; } //报警级别
|
||||||
|
|
||||||
|
public int Status { get; set; } //状态:1=告警;2=恢复
|
||||||
|
|
||||||
|
public string SourceAlertKey { get; set; } = string.Empty; //指标名称 ******
|
||||||
|
|
||||||
|
public string Summary { get; set; } = string.Empty; //告警内容
|
||||||
|
|
||||||
|
public string SourceIdentifier { get; set; } = string.Empty;//事件源的唯一标识 ******
|
||||||
|
|
||||||
|
public string LastOccurrence { get; set; } = string.Empty; //告警最后一次发生时间
|
||||||
|
|
||||||
|
|
||||||
|
static public string[] AlarmKeyword = { "分", "未同步", "告警", "异常", "断", "未就绪", "无效", "未复归", "动作", "检修", "未储能", "跳闸", "失步", "分位", "故障", "产生", "不定", "中断", "不良", "失灵" };
|
||||||
|
//static public string[] RecoveryKeyword = { "正常", "消失", "通", "同步", "解除", "复归", "已复归", "返回", "已储能", "恢复" };
|
||||||
|
|
||||||
|
|
||||||
|
public bool Parse(string twinId, AlertData alertData)
|
||||||
|
{
|
||||||
|
List<string> alarmLevel = new List<string> { "", "事故", "异常", "变位", "越限", "告知" };
|
||||||
|
Severity = alarmLevel.IndexOf(alertData.AlertLevel);
|
||||||
|
|
||||||
|
if (Severity < 1)
|
||||||
|
return false;
|
||||||
|
else if (Severity == 5)
|
||||||
|
Severity = 4;
|
||||||
|
|
||||||
|
|
||||||
|
bool isAlarm = AlarmKeyword.Any(e => alertData.Content.Contains(e));
|
||||||
|
|
||||||
|
TwinId = twinId;
|
||||||
|
|
||||||
|
Status = isAlarm ? 1 : 2;
|
||||||
|
|
||||||
|
SourceAlertKey = alertData.Alerter; //Alerter是唯一的,相同的告警,TwinId、SourceAlertKey和SourceIdentifier要相同
|
||||||
|
|
||||||
|
Summary = $"{ StringHelper.GetAfterLastOfAny(alertData.Alerter, '|')} : {StringHelper.GetAfterLastOfAny(alertData.Content, ':')}";
|
||||||
|
|
||||||
|
SourceIdentifier = alertData.Alerter; //Alerter是唯一的
|
||||||
|
|
||||||
|
LastOccurrence = alertData.AlertTime.ToString("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
|
||||||
|
if (Summary.Contains("保护CPU连接状态"))
|
||||||
|
{
|
||||||
|
int kk = 0;
|
||||||
|
Debug.WriteLine($"{Summary}\ttwinId ={twinId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Parse(string twinId, int severity, bool isAlarm, string alarmUuid, string alarmContent, string alarmTime)
|
||||||
|
{
|
||||||
|
TwinId = twinId;
|
||||||
|
Severity = severity;
|
||||||
|
Status = isAlarm ? 1 : 2;
|
||||||
|
SourceAlertKey = alarmUuid;
|
||||||
|
Summary = $"{alarmUuid}{alarmContent}";
|
||||||
|
SourceIdentifier = alarmUuid;
|
||||||
|
LastOccurrence = alarmTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//光纤
|
||||||
|
public class OpticalFiberConfigModel : NetworkCable
|
||||||
|
{
|
||||||
|
public string VirtualPointCode { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string[] VirtualPointCodes => string.IsNullOrWhiteSpace(VirtualPointCode) ? Array.Empty<string>() : VirtualPointCode.Split(',', ',');
|
||||||
|
|
||||||
|
public string LinkageData { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string[] LinkageDatas => string.IsNullOrWhiteSpace(LinkageData) ? Array.Empty<string>() : LinkageData.Split(',', ',');
|
||||||
|
|
||||||
|
public string[] LogicalExpressions => string.IsNullOrWhiteSpace(LogicalExpression) ? Array.Empty<string>() : LogicalExpression.Split(',', ',');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ using Microsoft.Extensions.Hosting;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using YunDa.Server.ISMSTcp.Extensions;
|
using YunDa.Server.ISMSTcp.Extensions;
|
||||||
|
using YunDa.Server.ISMSTcp.Models;
|
||||||
using YunDa.Server.ISMSTcp.Services;
|
using YunDa.Server.ISMSTcp.Services;
|
||||||
|
|
||||||
namespace YunDa.Server.ISMSTcp
|
namespace YunDa.Server.ISMSTcp
|
||||||
|
|||||||
62
src/YunDa.Server/YunDa.Server.ISMSTcp/Services/AppInit.cs
Normal file
62
src/YunDa.Server/YunDa.Server.ISMSTcp/Services/AppInit.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace YunDa.Server.ISMSTcp.Services
|
||||||
|
{
|
||||||
|
public static class AppInit
|
||||||
|
{
|
||||||
|
private static readonly TaskCompletionSource<bool> _tcs =
|
||||||
|
new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
|
|
||||||
|
private static int _state = 0; // 0 = 未初始化; 1 = 已初始化
|
||||||
|
private static readonly DateTime _startTime = DateTime.UtcNow;
|
||||||
|
|
||||||
|
public static readonly TimeSpan DefaultTimeOut = TimeSpan.FromMinutes(10);
|
||||||
|
|
||||||
|
/// <summary>立即返回初始化状态</summary>
|
||||||
|
public static bool IsInitialized() => Volatile.Read(ref _state) == 1;
|
||||||
|
|
||||||
|
/// <summary>从程序启动开始计算超时,如果初始化完成或超过超时返回 true</summary>
|
||||||
|
public static bool IsInitialized(TimeSpan timeout)
|
||||||
|
{
|
||||||
|
if (IsInitialized())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return (DateTime.UtcNow - _startTime) >= timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>等待初始化完成(无限等待)</summary>
|
||||||
|
public static Task WaitAsync() => _tcs.Task;
|
||||||
|
|
||||||
|
/// <summary>等待初始化完成(从调用时间开始计时超时)</summary>
|
||||||
|
public static async ValueTask<bool> WaitAsync(TimeSpan timeout)
|
||||||
|
{
|
||||||
|
if (IsInitialized())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
using var cts = new CancellationTokenSource(timeout);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _tcs.Task.WaitAsync(cts.Token);
|
||||||
|
return IsInitialized();
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>标记初始化完成(线程安全,只会触发一次)</summary>
|
||||||
|
public static void MarkInitialized()
|
||||||
|
{
|
||||||
|
if (Interlocked.Exchange(ref _state, 1) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_tcs.TrySetResult(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -76,6 +76,9 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
//二次回路巡检计划
|
//二次回路巡检计划
|
||||||
private readonly SecondaryCircuitInspectionPlanService _secondaryCircuitInspectionPlanService;
|
private readonly SecondaryCircuitInspectionPlanService _secondaryCircuitInspectionPlanService;
|
||||||
|
|
||||||
|
|
||||||
|
private readonly ZzDataCmdService _zzDataCmdService;
|
||||||
|
|
||||||
public DataProcessor(
|
public DataProcessor(
|
||||||
ILogger<DataProcessor> logger,
|
ILogger<DataProcessor> logger,
|
||||||
MessageParser messageParser,
|
MessageParser messageParser,
|
||||||
@ -94,7 +97,8 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
WebApiRequest webApiRequest,
|
WebApiRequest webApiRequest,
|
||||||
SecondaryCircuitInspectionPlanService secondaryCircuitInspectionPlanService,
|
SecondaryCircuitInspectionPlanService secondaryCircuitInspectionPlanService,
|
||||||
ThingService thingService,
|
ThingService thingService,
|
||||||
GwErrorRatioService gwErrorRatioService)
|
GwErrorRatioService gwErrorRatioService,
|
||||||
|
ZzDataCmdService zzDataCmdService)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_messageParser = messageParser;
|
_messageParser = messageParser;
|
||||||
@ -114,6 +118,7 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
_secondaryCircuitInspectionPlanService = secondaryCircuitInspectionPlanService ?? throw new ArgumentNullException(nameof(secondaryCircuitInspectionPlanService));
|
_secondaryCircuitInspectionPlanService = secondaryCircuitInspectionPlanService ?? throw new ArgumentNullException(nameof(secondaryCircuitInspectionPlanService));
|
||||||
_thingService = thingService ?? throw new ArgumentNullException(nameof(thingService));
|
_thingService = thingService ?? throw new ArgumentNullException(nameof(thingService));
|
||||||
_gwErrorRatioService = gwErrorRatioService ?? throw new ArgumentNullException(nameof(gwErrorRatioService));
|
_gwErrorRatioService = gwErrorRatioService ?? throw new ArgumentNullException(nameof(gwErrorRatioService));
|
||||||
|
_zzDataCmdService = zzDataCmdService ?? throw new ArgumentNullException(nameof(zzDataCmdService));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -180,6 +185,8 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
{
|
{
|
||||||
HandleRecvMsg(contentToken, "FAULTRPT");
|
HandleRecvMsg(contentToken, "FAULTRPT");
|
||||||
var alertDatas = contentToken.ToObject<List<AlertData>>();
|
var alertDatas = contentToken.ToObject<List<AlertData>>();
|
||||||
|
if(alertDatas != null)
|
||||||
|
Log.Warning($"收到故障报告:数量{alertDatas.Count}");
|
||||||
foreach (var item in alertDatas)
|
foreach (var item in alertDatas)
|
||||||
{
|
{
|
||||||
var json = JsonConvert.SerializeObject(item);
|
var json = JsonConvert.SerializeObject(item);
|
||||||
@ -226,6 +233,7 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
// 批量处理遥测数据
|
// 批量处理遥测数据
|
||||||
await _telemeteringHandle.ProcessYCDataAsync(contentArray);
|
await _telemeteringHandle.ProcessYCDataAsync(contentArray);
|
||||||
|
|
||||||
|
//_logger.LogWarning($"收到遥测数据,数量:{contentArray.Count}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -464,6 +472,10 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
deviceUpdates.Add((deviceId, isOnline));
|
deviceUpdates.Add((deviceId, isOnline));
|
||||||
processedCount++;
|
processedCount++;
|
||||||
|
|
||||||
|
|
||||||
|
//更新装置状态
|
||||||
|
_zzDataCmdService.UpdateDeviceCommState(deviceId, isOnline);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception itemEx)
|
catch (Exception itemEx)
|
||||||
{
|
{
|
||||||
@ -610,10 +622,10 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
//await ProcessFaultReportsAsync(alertDatas);
|
//await ProcessFaultReportsAsync(alertDatas);
|
||||||
|
|
||||||
//报警上传
|
//报警上传
|
||||||
await _webApiRequest.UploadAlertMessageAsync(alertDatas);
|
_webApiRequest.UploadAlertMessageAsync(alertDatas);
|
||||||
|
|
||||||
//报警推送到孪生体
|
//报警推送到孪生体
|
||||||
await _thingService.UpdateAlarmDatas(alertDatas);
|
_thingService.UpdateAlarmDatas(alertDatas);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,9 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
_zzDataCacheContainerInit = zzDataCacheContainerInit;
|
_zzDataCacheContainerInit = zzDataCacheContainerInit;
|
||||||
_zzDataCacheContainerInit.InitGateWayBaseInfo(_cacheContainer);
|
_zzDataCacheContainerInit.InitGateWayBaseInfo(_cacheContainer);
|
||||||
|
|
||||||
|
|
||||||
|
ZzDataCache.SetDataCache(ZzDataCacheContainerDataType.eGW, _cacheContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
//解析数据
|
//解析数据
|
||||||
@ -79,7 +82,7 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//缓存遥信数据到内存
|
//缓存数据到内存
|
||||||
private void SaveDataToCache(GwErrorRatioDataModel data)
|
private void SaveDataToCache(GwErrorRatioDataModel data)
|
||||||
{
|
{
|
||||||
_cacheContainer.Write(data.GatewayID, data.ErrorRatio, data.DataTimeStamp, "", data.ErrorRatio.ToString("P2"));
|
_cacheContainer.Write(data.GatewayID, data.ErrorRatio, data.DataTimeStamp, "", data.ErrorRatio.ToString("P2"));
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
using DotNetty.Common.Utilities;
|
using Abp.AutoMapper;
|
||||||
|
using DotNetty.Common.Utilities;
|
||||||
using Jint;
|
using Jint;
|
||||||
|
using Jint.Native;
|
||||||
using Jint.Native.Object;
|
using Jint.Native.Object;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@ -25,14 +27,13 @@ using System.Threading;
|
|||||||
using System.Threading.Channels;
|
using System.Threading.Channels;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using YunDa.Server.ISMSTcp.Domain;
|
using YunDa.Server.ISMSTcp.Domain;
|
||||||
|
using YunDa.Server.ISMSTcp.Helpers;
|
||||||
using YunDa.Server.ISMSTcp.Interfaces;
|
using YunDa.Server.ISMSTcp.Interfaces;
|
||||||
using YunDa.Server.ISMSTcp.Models;
|
using YunDa.Server.ISMSTcp.Models;
|
||||||
using YunDa.SOMS.DataTransferObject.DataMonitoring.SecondaryCircuitInspection;
|
using YunDa.SOMS.DataTransferObject.DataMonitoring.SecondaryCircuitInspection;
|
||||||
using YunDa.SOMS.DataTransferObject.DataMonitoring.SecondaryCircuitInspection.Configurations;
|
using YunDa.SOMS.DataTransferObject.DataMonitoring.SecondaryCircuitInspection.Configurations;
|
||||||
using YunDa.SOMS.DataTransferObject.MaintenanceAndOperations.SecondaryEquipment;
|
using YunDa.SOMS.DataTransferObject.MaintenanceAndOperations.SecondaryEquipment;
|
||||||
using YunDa.SOMS.Entities.DataMonitoring.SecondaryCircuitInspection;
|
using YunDa.SOMS.Entities.DataMonitoring.SecondaryCircuitInspection;
|
||||||
using YunDa.Server.ISMSTcp.Helpers;
|
|
||||||
using Abp.AutoMapper;
|
|
||||||
|
|
||||||
namespace YunDa.Server.ISMSTcp.Services
|
namespace YunDa.Server.ISMSTcp.Services
|
||||||
{
|
{
|
||||||
@ -42,137 +43,7 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
//带执行状态的巡检计划结构体
|
|
||||||
public class SecondaryCircuitInspectionPlanStateModel
|
|
||||||
{
|
|
||||||
//执行时间
|
|
||||||
public DateTime ExecuteTime { get; set; } = DateTime.MinValue;
|
|
||||||
|
|
||||||
public SecondaryCircuitInspectionPlanOutput Plan { get; set; }
|
|
||||||
|
|
||||||
public SecondaryCircuitInspectionPlanStateModel()
|
|
||||||
{
|
|
||||||
Plan = new SecondaryCircuitInspectionPlanOutput();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class SecondaryCircuitInspectionItemOutputEx
|
|
||||||
{
|
|
||||||
public int TriggerType { get; set; }
|
|
||||||
|
|
||||||
public SecondaryCircuitInspectionItemOutput Item { get; set; }
|
|
||||||
|
|
||||||
public SecondaryCircuitInspectionItemOutputEx(int triggerType, SecondaryCircuitInspectionItemOutput item)
|
|
||||||
{
|
|
||||||
TriggerType = triggerType;
|
|
||||||
Item = item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DeviceDzData
|
|
||||||
{
|
|
||||||
public List<DzInfo> UserDz { get; set; }
|
|
||||||
|
|
||||||
public List<DzInfo> SysDz { get; set; }
|
|
||||||
|
|
||||||
public string DeviceName { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class InspectionResultData
|
|
||||||
{
|
|
||||||
public string PresetName { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public int PresetCode { get; set; }
|
|
||||||
|
|
||||||
public string TimeStamp { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public string Value { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class SecondaryCircuitInspectionStoreDataModel
|
|
||||||
{
|
|
||||||
//遥测数据
|
|
||||||
public List<ZzDataResultModel> TelemetryData { get; set; }
|
|
||||||
|
|
||||||
//遥信数据
|
|
||||||
public List<ZzDataResultModel> TeleSignalData { get; set; }
|
|
||||||
|
|
||||||
//定值
|
|
||||||
public List<DeviceDzData> SettingData { get; set; }
|
|
||||||
|
|
||||||
//预置位
|
|
||||||
public List<InspectionResultData> PresetData { get; set; }
|
|
||||||
|
|
||||||
//虚点数据
|
|
||||||
public List<ZzDataResultModel> VariantData { get; set; }
|
|
||||||
|
|
||||||
//网关数据
|
|
||||||
public List<ZzDataResultModel> GatewayData { get; set; }
|
|
||||||
}
|
|
||||||
//巡检结果
|
|
||||||
public class SecondaryCircuitInspectionJsDataModel
|
|
||||||
{
|
|
||||||
public int TimeWindowSeconds { get; set; }
|
|
||||||
public int TimeWindowCount { get; set; }
|
|
||||||
public TimeWindowTypeEnum TimeWindowType { get; set; }
|
|
||||||
|
|
||||||
public SecondaryCircuitInspectionStoreDataModel StoreData { get; set; } = new SecondaryCircuitInspectionStoreDataModel();
|
|
||||||
public List<SecondaryCircuitInspectionTelemetryConfigOutput> TelemetryConfigs { get; set; }
|
|
||||||
public List<SecondaryCircuitInspectionTelesignalConfigOutput> TelesignalConfigs { get; set; }
|
|
||||||
public List<SecondaryCircuitInspectionCameraPresetOutput> CameraPresets { get; set; }
|
|
||||||
public List<SecondaryCircuitInspectionDeviceConfigOutput> DeviceConfigs { get; set; }
|
|
||||||
public List<SecondaryCircuitInspectionVariantOutput> VariantConfigs { get; set; }
|
|
||||||
public List<SecondaryCircuitInspectionGatewayOutput> GatewayConfigs { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//巡检结果上传Model
|
|
||||||
public class SecondaryCircuitInspectionResultSaveModel
|
|
||||||
{
|
|
||||||
public string SecondaryCircuitInspectionItemId { get; set; } = string.Empty;
|
|
||||||
public string InspectionPlanId { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public string ExecutionTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|
||||||
|
|
||||||
public long ExecutionDurationMs { get; set; }
|
|
||||||
|
|
||||||
public int TriggerType { get; set; } //1计划,2事件
|
|
||||||
|
|
||||||
public string TriggerEventId { get; set; } = string.Empty;
|
|
||||||
public string Status { get; set; } = string.Empty; //"异常|正常|故障",
|
|
||||||
public string InspectionResult { get; set; } = string.Empty; //巡检结果 inspectionResult不能超过15个字符
|
|
||||||
public string CalculationProcess { get; set; } = string.Empty; //计算过程
|
|
||||||
public string VerificationResult { get; set; } = string.Empty; //校验结果
|
|
||||||
public SecondaryCircuitInspectionJsDataModel Data { get; set; }
|
|
||||||
public string Remark { get; set; } = string.Empty; //无用
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
public class SecondaryCircuitInspectionAiParamModel
|
|
||||||
{
|
|
||||||
public string InspectionResultId { get; set; } = string.Empty;
|
|
||||||
public string InspectionName { get; set; } = string.Empty;
|
|
||||||
public string InspectionDescription { get; set; } = string.Empty;
|
|
||||||
public string PlanName => string.Concat(InspectionName, " ", InspectionDescription);
|
|
||||||
public string Status { get; set; } = string.Empty; //"异常|正常|故障",
|
|
||||||
public string InspectionResult { get; set; } = string.Empty; //巡检结果 inspectionResult不能超过15个字符
|
|
||||||
public string CalculationProcess { get; set; } = string.Empty; //计算过程
|
|
||||||
public string VerificationResult { get; set; } = string.Empty; //校验结果
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SecondaryCircuitInspectionAiSaveModel
|
|
||||||
{
|
|
||||||
public string InspectionResultId { get; set; } = string.Empty;
|
|
||||||
public string AiAnalysisResult { get; set; } = string.Empty; // "AI结果状态:失败|成功",
|
|
||||||
public string ResultHandleDescription { get; set; } = string.Empty; //"AI返回的处理结果"
|
|
||||||
}
|
|
||||||
|
|
||||||
//二次回路巡检计划
|
//二次回路巡检计划
|
||||||
public class SecondaryCircuitInspectionPlanService
|
public class SecondaryCircuitInspectionPlanService
|
||||||
@ -184,12 +55,12 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
private readonly WebApiRequest _webApiRequest;
|
private readonly WebApiRequest _webApiRequest;
|
||||||
private readonly WebApiSettings _webApiSettings;
|
private readonly WebApiSettings _webApiSettings;
|
||||||
|
|
||||||
private bool _updatedPlanOk = false;
|
|
||||||
|
|
||||||
|
|
||||||
private Queue<SecondaryCircuitInspectionPlanStateModel> _planList;
|
private Queue<SecondaryCircuitInspectionPlanStateModel> _planList;
|
||||||
private readonly AsyncLock _planLock = new AsyncLock();
|
private readonly AsyncLock _planLock = new AsyncLock();
|
||||||
private int _planCheckDay = 0;
|
private int _planCheckDay = 0;
|
||||||
|
private bool _getPlanListOk = false;
|
||||||
|
|
||||||
private readonly Channel<SecondaryCircuitInspectionItemOutputEx> _singlePlanChannel; //巡检计划
|
private readonly Channel<SecondaryCircuitInspectionItemOutputEx> _singlePlanChannel; //巡检计划
|
||||||
private readonly ChannelEx<SecondaryCircuitInspectionAiParamModel, string> _aiChannel; //Ai调用
|
private readonly ChannelEx<SecondaryCircuitInspectionAiParamModel, string> _aiChannel; //Ai调用
|
||||||
@ -199,11 +70,14 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
private readonly AsyncLock _eventPlanLock = new AsyncLock();
|
private readonly AsyncLock _eventPlanLock = new AsyncLock();
|
||||||
private bool _getEventPlanListOk = false;
|
private bool _getEventPlanListOk = false;
|
||||||
|
|
||||||
|
private readonly ZzDataCmdService _zzDataCmdService;
|
||||||
|
|
||||||
public SecondaryCircuitInspectionPlanService(
|
public SecondaryCircuitInspectionPlanService(
|
||||||
ILogger<SecondaryCircuitInspectionPlanService> logger,
|
ILogger<SecondaryCircuitInspectionPlanService> logger,
|
||||||
IApiEndpoints apiEndpoints,
|
IApiEndpoints apiEndpoints,
|
||||||
WebApiRequest webApiRequest,
|
WebApiRequest webApiRequest,
|
||||||
IOptions<WebApiSettings> webApiOptions
|
IOptions<WebApiSettings> webApiOptions,
|
||||||
|
ZzDataCmdService zzDataCmdService
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_apiEndpoints = apiEndpoints ?? throw new ArgumentNullException(nameof(apiEndpoints));
|
_apiEndpoints = apiEndpoints ?? throw new ArgumentNullException(nameof(apiEndpoints));
|
||||||
@ -212,6 +86,8 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
|
|
||||||
_webApiSettings = webApiOptions.Value;
|
_webApiSettings = webApiOptions.Value;
|
||||||
|
|
||||||
|
_zzDataCmdService = zzDataCmdService ?? throw new ArgumentNullException(nameof(zzDataCmdService));
|
||||||
|
|
||||||
_planList = new Queue<SecondaryCircuitInspectionPlanStateModel>();
|
_planList = new Queue<SecondaryCircuitInspectionPlanStateModel>();
|
||||||
|
|
||||||
_singlePlanChannel = Channel.CreateUnbounded<SecondaryCircuitInspectionItemOutputEx>();
|
_singlePlanChannel = Channel.CreateUnbounded<SecondaryCircuitInspectionItemOutputEx>();
|
||||||
@ -235,24 +111,32 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
while (true)
|
while (true)
|
||||||
{//每10分钟更新一下配置
|
{//每10分钟更新一下配置
|
||||||
|
|
||||||
await UpdatePlans();
|
await UpdatePlanConfig();
|
||||||
|
|
||||||
await UpdateEventPlans();
|
|
||||||
|
|
||||||
//await CheckAiChannel();
|
//await CheckAiChannel();
|
||||||
|
|
||||||
await Task.Delay(TimeSpan.FromMinutes(10));
|
//await Task.Delay(TimeSpan.FromMinutes(10));
|
||||||
|
if(_getPlanListOk && _getEventPlanListOk)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("SecondaryCircuitInspectionPlanService 获取配置信息成功!");
|
||||||
|
break; //程序启动时,主动获取一次,之后有更新,会主动通知
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await Task.Delay(TimeSpan.FromMinutes(3));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await AppInit.WaitAsync(AppInit.DefaultTimeOut);
|
||||||
|
|
||||||
//检测计划
|
//检测计划
|
||||||
_ = Task.Run(async () =>
|
_ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{//每10秒检测一下计划
|
{//每60秒检测一下计划
|
||||||
|
|
||||||
if (_updatedPlanOk)
|
if (_getPlanListOk)
|
||||||
{
|
{
|
||||||
await CheckPlan();
|
await CheckPlan();
|
||||||
|
|
||||||
@ -300,7 +184,15 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
|
|
||||||
await ExecutePlan(item);
|
await ExecutePlan(item);
|
||||||
|
|
||||||
await Task.Delay(500);
|
if(item.Item.DeviceConfigCount > 0)
|
||||||
|
{//需要判断定值的,间隔久一点
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(60));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(30));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -327,11 +219,23 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task UpdatePlanConfig()
|
||||||
|
{
|
||||||
|
_zzDataCmdService.ClearYcIds();
|
||||||
|
|
||||||
|
await UpdatePlans();
|
||||||
|
await UpdateEventPlans();
|
||||||
|
|
||||||
|
}
|
||||||
//更新计划
|
//更新计划
|
||||||
private async Task UpdatePlans()
|
private async Task UpdatePlans()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
|
SecondaryCircuitInspectionPlanStateModel[] planList;
|
||||||
|
|
||||||
using (await _planLock.LockAsync())
|
using (await _planLock.LockAsync())
|
||||||
{
|
{
|
||||||
var oldPlan = _planList.ToArray();
|
var oldPlan = _planList.ToArray();
|
||||||
@ -381,17 +285,21 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
|
|
||||||
//获取到绑定信息,可以更新全部状态了
|
//获取到绑定信息,可以更新全部状态了
|
||||||
if (_planList.Count > 0)
|
if (_planList.Count > 0)
|
||||||
_updatedPlanOk = true;
|
_getPlanListOk = true;
|
||||||
|
|
||||||
|
planList = _planList.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_zzDataCmdService.AddCircuitPlanYcIds(planList);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_updatedPlanOk = false;
|
_getPlanListOk = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,6 +308,7 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
SecondaryCircuitEventDrivenConfigOutput[] eventPlantList = null;
|
||||||
|
|
||||||
using (await _eventPlanLock.LockAsync())
|
using (await _eventPlanLock.LockAsync())
|
||||||
{
|
{
|
||||||
@ -432,7 +341,12 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
//获取到绑定信息,可以更新全部状态了
|
//获取到绑定信息,可以更新全部状态了
|
||||||
if (_eventPlanList.Count > 0)
|
if (_eventPlanList.Count > 0)
|
||||||
_getEventPlanListOk = true;
|
_getEventPlanListOk = true;
|
||||||
|
|
||||||
|
eventPlantList = _eventPlanList.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_zzDataCmdService.AddEventPlanYcIds(eventPlantList);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -475,11 +389,16 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
|
|
||||||
foreach (var item in planList)
|
foreach (var item in planList)
|
||||||
{
|
{
|
||||||
if (item.ExecuteTime == DateTime.MinValue && item.Plan.IsActive)
|
bool debugCheck = false;
|
||||||
|
//if (item.Plan.Name == "软压板巡检")
|
||||||
|
//{
|
||||||
|
// debugCheck = true;
|
||||||
|
//}
|
||||||
|
if (item.ExecuteTime == DateTime.MinValue && item.Plan.IsActive || debugCheck)
|
||||||
{//当天未执行
|
{//当天未执行
|
||||||
if (now.Hour == item.Plan.ScheduledHour && now.Minute == item.Plan.ScheduledMinute)
|
if (now.Hour == item.Plan.ScheduledHour && now.Minute == item.Plan.ScheduledMinute || debugCheck)
|
||||||
{
|
{
|
||||||
if (item.Plan.ScheduledWeekDaysList.IndexOf(week) != -1)
|
if (item.Plan.ScheduledWeekDaysList.IndexOf(week) != -1 || debugCheck)
|
||||||
{
|
{
|
||||||
await PushPlanToChannel(1, item.Plan);
|
await PushPlanToChannel(1, item.Plan);
|
||||||
|
|
||||||
@ -514,10 +433,21 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
{
|
{
|
||||||
string id = item.Id.ToString();
|
string id = item.Id.ToString();
|
||||||
|
|
||||||
if(item.IsActive && !string.IsNullOrWhiteSpace(item.CalculationExpression) && !string.IsNullOrWhiteSpace(id))
|
bool debugCheck = true;
|
||||||
|
|
||||||
|
//if (item.Name == "212馈线软压板 + 控制字一致性校验")
|
||||||
|
//{
|
||||||
|
// debugCheck = true;
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// debugCheck = false;
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (debugCheck && item.IsActive && !string.IsNullOrWhiteSpace(item.CalculationExpression) && !string.IsNullOrWhiteSpace(id))
|
||||||
{
|
{
|
||||||
//写到队列里,由队列控制执行频率
|
//写到队列里,由队列控制执行频率
|
||||||
await _singlePlanChannel.Writer.WriteAsync(new SecondaryCircuitInspectionItemOutputEx(triggerType, item));
|
await _singlePlanChannel.Writer.WriteAsync(new SecondaryCircuitInspectionItemOutputEx(triggerType, item, plan.Id.ToString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,6 +519,15 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
if (item.DeviceConfigCount > 0)
|
if (item.DeviceConfigCount > 0)
|
||||||
{
|
{
|
||||||
settingData = await GetSourceDataAsync<List<DeviceDzData>>(id, 3);
|
settingData = await GetSourceDataAsync<List<DeviceDzData>>(id, 3);
|
||||||
|
|
||||||
|
if(settingData?.Count > 0)
|
||||||
|
{
|
||||||
|
_logger.LogWarning($"{DateTime.Now.ToString()}: 获取定值成功,id = {id}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogError($"{DateTime.Now.ToString()}: 获取定值失败,id = {id}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (item.CameraPresetCount > 0)
|
if (item.CameraPresetCount > 0)
|
||||||
{
|
{
|
||||||
@ -610,8 +549,7 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
jsData.StoreData.GatewayData = gatewayData;
|
jsData.StoreData.GatewayData = gatewayData;
|
||||||
jsData.StoreData.VariantData = variantData;
|
jsData.StoreData.VariantData = variantData;
|
||||||
|
|
||||||
if (jsData.StoreData.TelemetryData == null && jsData.StoreData.TeleSignalData == null && jsData.StoreData.SettingData == null &&
|
if (jsData.StoreData.IsAllDataNull())
|
||||||
jsData.StoreData.PresetData == null && jsData.StoreData.GatewayData == null && jsData.StoreData.VariantData == null)
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -653,16 +591,36 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
saveData.ExecutionDurationMs = sw.ElapsedMilliseconds;
|
saveData.ExecutionDurationMs = sw.ElapsedMilliseconds;
|
||||||
saveData.TriggerType = itemEx.TriggerType;
|
saveData.TriggerType = itemEx.TriggerType;
|
||||||
if (saveData.TriggerType == 1)
|
if (saveData.TriggerType == 1)
|
||||||
saveData.InspectionPlanId = id;
|
saveData.InspectionPlanId = itemEx.PlanId;
|
||||||
else
|
else
|
||||||
saveData.TriggerEventId = id;
|
saveData.TriggerEventId = itemEx.PlanId;
|
||||||
|
|
||||||
saveData.Status = saveObj.Get("status").ToString();
|
saveData.Status = saveObj.Get("status").ToString();
|
||||||
saveData.InspectionResult = saveObj.Get("inspectionResult").ToString();
|
saveData.InspectionResult = saveObj.Get("inspectionResult").ToString();
|
||||||
saveData.CalculationProcess = saveObj.Get("calculationProcess").ToString();
|
saveData.CalculationProcess = saveObj.Get("calculationProcess").ToString();
|
||||||
saveData.VerificationResult = saveObj.Get("verificationResult").ToString();
|
saveData.VerificationResult = saveObj.Get("verificationResult").ToString();
|
||||||
|
|
||||||
|
|
||||||
|
if (saveObj.HasProperty("data"))
|
||||||
|
{//使用过滤后的数据:2025-12-09 王喜沟通
|
||||||
|
engine.SetValue("data", saveObj.Get("data"));
|
||||||
|
var dataJsonString = engine.Evaluate("JSON.stringify(data)").AsString();
|
||||||
|
var model = JsonConvert.DeserializeObject<SecondaryCircuitInspectionJsDataModel>(dataJsonString);
|
||||||
|
|
||||||
|
if(model != null && model.StoreData != null && !model.StoreData.IsAllDataNull())
|
||||||
|
{
|
||||||
|
saveData.Data = model;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
saveData.Data = jsData;
|
saveData.Data = jsData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
saveData.Data = jsData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var inspectionResultId = await _webApiRequest.SaveSecondaryCircuitInspectionPlanResultAsync(saveData);
|
var inspectionResultId = await _webApiRequest.SaveSecondaryCircuitInspectionPlanResultAsync(saveData);
|
||||||
|
|
||||||
@ -938,13 +896,13 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
planList = _eventPlanList.ToArray();
|
planList = _eventPlanList.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var item in planList)
|
foreach (var plan in planList)
|
||||||
{
|
{
|
||||||
await Task.Delay(item.DelayTriggerSeconds * 1000);
|
await Task.Delay(plan.DelayTriggerSeconds * 1000);
|
||||||
|
|
||||||
if (item.IsActive && item.SecondaryCircuitInspectionEventItems?.Count > 0 && !string.IsNullOrWhiteSpace(item.TriggerExpression))
|
if (plan.IsActive && plan.SecondaryCircuitInspectionEventItems?.Count > 0 && !string.IsNullOrWhiteSpace(plan.TriggerExpression))
|
||||||
{
|
{
|
||||||
string id = item.Id.ToString() ?? "";
|
string id = plan.Id.ToString() ?? "";
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(id))
|
if (!string.IsNullOrWhiteSpace(id))
|
||||||
{
|
{
|
||||||
@ -957,13 +915,13 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
Task<List<ZzDataResultModel>>? t1 = null;
|
Task<List<ZzDataResultModel>>? t1 = null;
|
||||||
Task<List<ZzDataResultModel>>? t2 = null;
|
Task<List<ZzDataResultModel>>? t2 = null;
|
||||||
|
|
||||||
if (item.TelemetryConfigs.Count > 0)
|
if (plan.TelemetryConfigs.Count > 0)
|
||||||
{
|
{
|
||||||
t1 = GetSourceDataAsync<List<ZzDataResultModel>>(id, 1);
|
t1 = GetSourceDataAsync<List<ZzDataResultModel>>(id, 1);
|
||||||
tasks.Add(t1);
|
tasks.Add(t1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.TelesignalConfigs.Count > 0)
|
if (plan.TelesignalConfigs.Count > 0)
|
||||||
{
|
{
|
||||||
t2 = GetSourceDataAsync<List<ZzDataResultModel>>(id, 2);
|
t2 = GetSourceDataAsync<List<ZzDataResultModel>>(id, 2);
|
||||||
tasks.Add(t2);
|
tasks.Add(t2);
|
||||||
@ -974,7 +932,7 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
if (t1 != null) jsData.StoreData.TelemetryData = await t1;
|
if (t1 != null) jsData.StoreData.TelemetryData = await t1;
|
||||||
if (t2 != null) jsData.StoreData.TeleSignalData = await t2;
|
if (t2 != null) jsData.StoreData.TeleSignalData = await t2;
|
||||||
|
|
||||||
engine.Execute(item.TriggerExpression);
|
engine.Execute(plan.TriggerExpression);
|
||||||
|
|
||||||
bool canCheck = true;
|
bool canCheck = true;
|
||||||
|
|
||||||
@ -985,17 +943,17 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
|
|
||||||
if(canCheck)
|
if(canCheck)
|
||||||
{
|
{
|
||||||
await Task.Delay(item.MandatoryWaitSeconds * 1000);
|
await Task.Delay(plan.MandatoryWaitSeconds * 1000);
|
||||||
|
|
||||||
//CheckPlanFormIds(item.SecondaryCircuitInspectionEventItems);
|
//CheckPlanFormIds(item.SecondaryCircuitInspectionEventItems);
|
||||||
|
|
||||||
//执行巡检
|
//执行巡检
|
||||||
foreach(var planItem in item.SecondaryCircuitInspectionEventItems)
|
foreach(var planItem in plan.SecondaryCircuitInspectionEventItems)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(planItem.CalculationExpression) && !string.IsNullOrWhiteSpace(planItem.Id.ToString()))
|
if (!string.IsNullOrWhiteSpace(planItem.CalculationExpression) && !string.IsNullOrWhiteSpace(planItem.Id.ToString()))
|
||||||
{
|
{
|
||||||
//写到队列里,由队列控制执行频率
|
//写到队列里,由队列控制执行频率
|
||||||
await _singlePlanChannel.Writer.WriteAsync(new SecondaryCircuitInspectionItemOutputEx(2, planItem));
|
await _singlePlanChannel.Writer.WriteAsync(new SecondaryCircuitInspectionItemOutputEx(2, planItem, plan.Id.ToString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -103,6 +103,9 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
//_cleanupTimer = new Timer(CleanupExpiredData, null, CLEANUP_INTERVAL_MS, CLEANUP_INTERVAL_MS);
|
//_cleanupTimer = new Timer(CleanupExpiredData, null, CLEANUP_INTERVAL_MS, CLEANUP_INTERVAL_MS);
|
||||||
|
|
||||||
_zzDataCacheContainer.SetTelemeteringHandle(this);
|
_zzDataCacheContainer.SetTelemeteringHandle(this);
|
||||||
|
|
||||||
|
|
||||||
|
ZzDataCache.SetDataCache(ZzDataCacheContainerDataType.eYC, _zzDataCacheContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -378,6 +381,12 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//if(ycDataModel.YC_ID == "YCB001162001")
|
||||||
|
//{
|
||||||
|
// _logger.LogWarning($"{DateTime.Now.ToString()}: 收到{ycDataModel.YC_ID}遥测数据");
|
||||||
|
//}
|
||||||
|
|
||||||
// 使用映射字典查找对应的haskey列表
|
// 使用映射字典查找对应的haskey列表
|
||||||
if (!_ycIdToHashKeysMapping.TryGetValue(ycDataModel.YC_ID, out List<string> haskeys))
|
if (!_ycIdToHashKeysMapping.TryGetValue(ycDataModel.YC_ID, out List<string> haskeys))
|
||||||
{
|
{
|
||||||
@ -393,6 +402,13 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
{
|
{
|
||||||
if (parsedTime.Year>2000)
|
if (parsedTime.Year>2000)
|
||||||
{
|
{
|
||||||
|
//if (ycDataModel.YC_ID == "YCB001209003")
|
||||||
|
//if(ycDataModels.Count == 188)
|
||||||
|
//if (ycDataModel.YC_ID == "YCB001112000")
|
||||||
|
//{
|
||||||
|
// _logger.LogWarning($"{resultTime.ToString()} : 收到遥测数据:Id = {ycDataModel.YC_ID}, Time = {parsedTime.ToString()}, 相差{(resultTime - parsedTime).TotalSeconds}秒");
|
||||||
|
|
||||||
|
//}
|
||||||
resultTime = parsedTime;
|
resultTime = parsedTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -669,7 +685,7 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
await InitAsync();
|
await InitAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await _zzDataCacheContainer.Read(ids, seconds, timeWindowType, cancellationToken, now);
|
var result = await _zzDataCacheContainer.Read(ids, seconds, timeWindowType, cancellationToken, now, true);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -695,6 +711,10 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LogWarning(string msg)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -127,7 +127,7 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
// 发送遥测召唤命令到TCP客户端
|
// 发送遥测召唤命令到TCP客户端
|
||||||
bool ycResult = await _tcpClient.SendMessageAsync(ycCommand, cancellationToken);
|
bool ycResult = await _tcpClient.SendMessageAsync(ycCommand, cancellationToken);
|
||||||
// 遥测和遥信命令之间间隔100毫秒
|
// 遥测和遥信命令之间间隔100毫秒
|
||||||
await Task.Delay(100, cancellationToken);
|
await Task.Delay(1000, cancellationToken);
|
||||||
|
|
||||||
// 构造遥信召唤命令:CallYXByDevice|{装置ID}
|
// 构造遥信召唤命令:CallYXByDevice|{装置ID}
|
||||||
string yxCommand = $"CallYXByDevice|{device.Id}";
|
string yxCommand = $"CallYXByDevice|{device.Id}";
|
||||||
@ -135,7 +135,7 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
// 发送遥信召唤命令到TCP客户端
|
// 发送遥信召唤命令到TCP客户端
|
||||||
bool yxResult = await _tcpClient.SendMessageAsync(yxCommand, cancellationToken);
|
bool yxResult = await _tcpClient.SendMessageAsync(yxCommand, cancellationToken);
|
||||||
// 每个装置处理完成后间隔100毫秒
|
// 每个装置处理完成后间隔100毫秒
|
||||||
await Task.Delay(100, cancellationToken);
|
await Task.Delay(1000, cancellationToken);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -179,6 +179,9 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
|
|
||||||
// 执行遥测和遥信召唤
|
// 执行遥测和遥信召唤
|
||||||
await ExecuteTelemetryCallAsync(cancellationToken);
|
await ExecuteTelemetryCallAsync(cancellationToken);
|
||||||
|
|
||||||
|
//召唤完成
|
||||||
|
AppInit.MarkInitialized();
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,6 +4,7 @@ using Newtonsoft.Json.Linq;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -77,6 +78,8 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
_webSocketPushService = webSocketPushService ?? throw new ArgumentNullException(nameof(webSocketPushService));
|
_webSocketPushService = webSocketPushService ?? throw new ArgumentNullException(nameof(webSocketPushService));
|
||||||
_protectionDeviceCommInfoRedis = protectionDeviceCommInfoRedis ?? throw new ArgumentNullException(nameof(protectionDeviceCommInfoRedis));
|
_protectionDeviceCommInfoRedis = protectionDeviceCommInfoRedis ?? throw new ArgumentNullException(nameof(protectionDeviceCommInfoRedis));
|
||||||
_webApiRequest = webApiRequest ?? throw new ArgumentNullException(nameof(webApiRequest));
|
_webApiRequest = webApiRequest ?? throw new ArgumentNullException(nameof(webApiRequest));
|
||||||
|
|
||||||
|
ZzDataCache.SetDataCache(ZzDataCacheContainerDataType.eYX, _zzDataCacheContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -144,7 +147,6 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
if (_yxIdToHashKeyMapping.TryAdd(model.ismsbaseYXId, haskey))
|
if (_yxIdToHashKeyMapping.TryAdd(model.ismsbaseYXId, haskey))
|
||||||
{
|
{
|
||||||
mappingCount++;
|
mappingCount++;
|
||||||
|
|
||||||
//初始化
|
//初始化
|
||||||
_zzDataCacheContainer.Write(model.ismsbaseYXId, model.ResultValue, model.ResultTime, model.Name, model.ResultValueStr, model.DispatcherAddress);
|
_zzDataCacheContainer.Write(model.ismsbaseYXId, model.ResultValue, model.ResultTime, model.Name, model.ResultValueStr, model.DispatcherAddress);
|
||||||
}
|
}
|
||||||
@ -370,6 +372,12 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if (yxDataModel.YX_ID == "YXB001121065")
|
||||||
|
//{
|
||||||
|
// _logger.LogWarning($"YXB001121065: {yxDataModel.V}, {yxDataModel.T}");
|
||||||
|
// Debug.WriteLine($"YXB001121065: {yxDataModel.V}, {yxDataModel.T}");
|
||||||
|
//}
|
||||||
|
|
||||||
// 使用映射字典查找对应的haskey
|
// 使用映射字典查找对应的haskey
|
||||||
if (!_yxIdToHashKeyMapping.TryGetValue(yxDataModel.YX_ID, out string haskey))
|
if (!_yxIdToHashKeyMapping.TryGetValue(yxDataModel.YX_ID, out string haskey))
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -43,6 +43,9 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
_webApiRequest = webApiRequest ?? throw new ArgumentNullException(nameof(webApiRequest));
|
_webApiRequest = webApiRequest ?? throw new ArgumentNullException(nameof(webApiRequest));
|
||||||
_zzDataCacheContainerInit = zzDataCacheContainerInit;
|
_zzDataCacheContainerInit = zzDataCacheContainerInit;
|
||||||
_zzDataCacheContainerInit.InitVariantBaseinfo(_zzDataCacheContainer);
|
_zzDataCacheContainerInit.InitVariantBaseinfo(_zzDataCacheContainer);
|
||||||
|
|
||||||
|
|
||||||
|
ZzDataCache.SetDataCache(ZzDataCacheContainerDataType.eVA, _zzDataCacheContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -96,6 +96,11 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
.Select(x => x.point)
|
.Select(x => x.point)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ZzDataPoint GetCurrentData()
|
||||||
|
{
|
||||||
|
return new ZzDataPoint(TimeStamp, Value, ValueStr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -192,6 +197,20 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
data.AddData(new ZzDataPoint(time, val, valStr));
|
data.AddData(new ZzDataPoint(time, val, valStr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ZzDataPoint? ReadCurrentValue(string id, out ZzData? zzData)
|
||||||
|
{
|
||||||
|
if (_datas.TryGetValue(id, out var channel))
|
||||||
|
{
|
||||||
|
zzData = channel;
|
||||||
|
return channel.GetCurrentData();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zzData = null;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Dictionary<string, ZzDataResultModel>> Read(List<string> ids, DateTime start, DateTime end)
|
public async Task<Dictionary<string, ZzDataResultModel>> Read(List<string> ids, DateTime start, DateTime end)
|
||||||
{
|
{
|
||||||
var result = new Dictionary<string, ZzDataResultModel>();
|
var result = new Dictionary<string, ZzDataResultModel>();
|
||||||
@ -213,30 +232,30 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
|
|
||||||
if (data.Data.Count == 0 && data.TimeStamp != DateTime.MinValue)
|
if (data.Data.Count == 0 && data.TimeStamp != DateTime.MinValue)
|
||||||
{
|
{
|
||||||
ZzDataPoint zzDataPoint = new ZzDataPoint(DateTime.Now, data.Value, data.ValueStr.Replace(" ", ""));
|
ZzDataPoint zzDataPoint = new ZzDataPoint(DateTime.Now, data.Value, data.ValueStr);
|
||||||
|
|
||||||
data.Data.Add(zzDataPoint);
|
data.Data.Add(zzDataPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_telemeteringHandle != null &&_dataType == ZzDataCacheContainerDataType.eYC && id == "YCB001103003")
|
//if (_telemeteringHandle != null &&_dataType == ZzDataCacheContainerDataType.eYC && id == "YCB001103003")
|
||||||
{
|
//{
|
||||||
if (data.Data.Where(e => Math.Abs(e.Value) < 0.0001).Count() == data.Data.Count)
|
// if (data.Data.Where(e => Math.Abs(e.Value) < 0.0001).Count() == data.Data.Count)
|
||||||
{
|
// {
|
||||||
string time = DateTime.Now.ToString("yyy/MM/dd HH:mm:ss");
|
// string time = DateTime.Now.ToString("yyy/MM/dd HH:mm:ss");
|
||||||
System.Console.WriteLine($"【{time}】: {id}所有值为0[{data.Data.Count}]:状态:{isFind}, Cache长度:{channel.Datas.Count}, Cache时间:{channel.StartTimeStamp.ToString("yyy/MM/dd HH:mm:ss")} ~ {channel.TimeStamp.ToString("yyy/MM/dd HH:mm:ss")}, 最后一个值:{channel.ValueStr}");
|
// _telemeteringHandle.LogWarning($"【{time}】: {id}所有值为0[{data.Data.Count}]:状态:{isFind}, Cache长度:{channel.Datas.Count}, Cache时间:{channel.StartTimeStamp.ToString("yyy/MM/dd HH:mm:ss")} ~ {channel.TimeStamp.ToString("yyy/MM/dd HH:mm:ss")}, 最后一个值:{channel.ValueStr}");
|
||||||
|
|
||||||
var redisData = await _telemeteringHandle.GetDataFromRedis(id);
|
// var redisData = await _telemeteringHandle.GetDataFromRedis(id);
|
||||||
if (redisData != null)
|
// if (redisData != null)
|
||||||
{
|
// {
|
||||||
System.Console.WriteLine($"【{time}】: {id}在Redis中的值为:{redisData.ResultValue} - {redisData.ResultTime }");
|
// _telemeteringHandle.LogWarning($"【{time}】: {id}在Redis中的值为:{redisData.ResultValue} - {redisData.ResultTime }");
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
System.Console.WriteLine($"【{time}】: {id}在Redis中没有找到");
|
// _telemeteringHandle.LogWarning($"【{time}】: {id}在Redis中没有找到");
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
result[id] = data;
|
result[id] = data;
|
||||||
|
|
||||||
@ -246,7 +265,7 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<ZzDataResultModel>> Read(List<string> ids, int seconds, int timeWindowType, CancellationToken cancellationToken, DateTime now = default)
|
public async Task<List<ZzDataResultModel>> Read(List<string> ids, int seconds, int timeWindowType, CancellationToken cancellationToken, DateTime now = default, bool forceCorrectCount = false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -259,7 +278,40 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
|
|
||||||
if (timeWindowType == 0 || timeWindowType == 2)
|
if (timeWindowType == 0 || timeWindowType == 2)
|
||||||
{
|
{
|
||||||
matched1 = await Read(ids, now.AddSeconds(-seconds), now);
|
DateTime startTime = now.AddSeconds(-seconds);
|
||||||
|
|
||||||
|
|
||||||
|
for(int i = 0; i < seconds; i++)
|
||||||
|
{
|
||||||
|
matched1 = await Read(ids, startTime, now);
|
||||||
|
|
||||||
|
//要保证有多少秒,就至少有多少个点
|
||||||
|
if (forceCorrectCount)
|
||||||
|
{
|
||||||
|
bool isCountCorrect = true;
|
||||||
|
|
||||||
|
foreach (var item in matched1)
|
||||||
|
{
|
||||||
|
if (item.Value.Data.Count < seconds)
|
||||||
|
{
|
||||||
|
isCountCorrect = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCountCorrect)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startTime = startTime.AddSeconds(-3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeWindowType == 1 || timeWindowType == 2)
|
if (timeWindowType == 1 || timeWindowType == 2)
|
||||||
@ -268,7 +320,41 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
|
|
||||||
if(span > 0)
|
if(span > 0)
|
||||||
await Task.Delay(span, cancellationToken);
|
await Task.Delay(span, cancellationToken);
|
||||||
|
|
||||||
|
for(int i = 0; i < seconds; i++)
|
||||||
|
{
|
||||||
|
|
||||||
matched2 = await Read(ids, now, DateTime.Now);
|
matched2 = await Read(ids, now, DateTime.Now);
|
||||||
|
|
||||||
|
//要保证有多少秒,就至少有多少个点
|
||||||
|
if (forceCorrectCount)
|
||||||
|
{
|
||||||
|
bool isCountCorrect = true;
|
||||||
|
|
||||||
|
foreach (var item in matched2)
|
||||||
|
{
|
||||||
|
if (item.Value.Data.Count < seconds)
|
||||||
|
{
|
||||||
|
isCountCorrect = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCountCorrect)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(2), cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var kv in matched2)
|
foreach (var kv in matched2)
|
||||||
@ -288,6 +374,27 @@ namespace YunDa.Server.ISMSTcp.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ZzDataCache
|
||||||
|
{
|
||||||
|
private static readonly ConcurrentDictionary<ZzDataCacheContainerDataType, ZzDataCacheContainer> _datas = new ConcurrentDictionary<ZzDataCacheContainerDataType, ZzDataCacheContainer>();
|
||||||
|
|
||||||
|
public static void SetDataCache(ZzDataCacheContainerDataType type, ZzDataCacheContainer cache)
|
||||||
|
{
|
||||||
|
_datas.TryAdd(type, cache);
|
||||||
|
}
|
||||||
|
public static ZzDataCacheContainer? GetDataCache(ZzDataCacheContainerDataType type)
|
||||||
|
{
|
||||||
|
if(_datas.TryGetValue(type, out ZzDataCacheContainer cache))
|
||||||
|
{
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class ZzDataCacheContainerInit
|
public class ZzDataCacheContainerInit
|
||||||
{
|
{
|
||||||
private readonly ILogger<SecondaryCircuitInspectionPlanService> _logger;
|
private readonly ILogger<SecondaryCircuitInspectionPlanService> _logger;
|
||||||
|
|||||||
@ -0,0 +1,249 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using YunDa.Server.ISMSTcp.Domain;
|
||||||
|
using YunDa.Server.ISMSTcp.Interfaces;
|
||||||
|
using YunDa.Server.ISMSTcp.Models;
|
||||||
|
using YunDa.SOMS.DataTransferObject.DataMonitoring.SecondaryCircuitInspection.Configurations;
|
||||||
|
|
||||||
|
namespace YunDa.Server.ISMSTcp.Services
|
||||||
|
{
|
||||||
|
public class YcIdExInfo
|
||||||
|
{
|
||||||
|
public string Id { get; set; } = string.Empty;
|
||||||
|
public string DeviceId { get; set; } = string.Empty;
|
||||||
|
public bool DeviceCommState { get; set; } = true;
|
||||||
|
|
||||||
|
public YcIdExInfo(string id)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ZzDataIdList
|
||||||
|
{
|
||||||
|
private ConcurrentDictionary<string, YcIdExInfo> _ids = new ConcurrentDictionary<string, YcIdExInfo>();
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_ids.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AddId(string id)
|
||||||
|
{
|
||||||
|
return _ids.TryAdd(id, new YcIdExInfo(id));
|
||||||
|
}
|
||||||
|
public void AddIds(string ids, string keyword, string separator)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(ids))
|
||||||
|
return;
|
||||||
|
|
||||||
|
string[] list = ids.Trim().Split(separator);
|
||||||
|
foreach (string id in list)
|
||||||
|
{
|
||||||
|
if(string.IsNullOrWhiteSpace(id))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(id.Contains(keyword))
|
||||||
|
_ids.TryAdd(id, new YcIdExInfo(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateDeviceCommState(string deviceId, bool commState)
|
||||||
|
{
|
||||||
|
foreach (var yc in _ids.Values)
|
||||||
|
{
|
||||||
|
if (yc.Id.Contains(deviceId))
|
||||||
|
{
|
||||||
|
yc.DeviceCommState = commState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> GetIds(bool? commState)
|
||||||
|
{
|
||||||
|
if(commState.HasValue)
|
||||||
|
return _ids.Where(kvp => kvp.Value.DeviceCommState == commState)
|
||||||
|
.Select(kvp => kvp.Key)
|
||||||
|
.ToList();
|
||||||
|
else
|
||||||
|
return _ids.Keys.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class ZzDataCmdService
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly ILogger<ZzDataCmdService> _logger;
|
||||||
|
private readonly ZzTcpService _zTcpService = null;
|
||||||
|
|
||||||
|
private ZzDataIdList _ycIds = new ZzDataIdList();
|
||||||
|
|
||||||
|
public ZzDataCmdService(
|
||||||
|
ILogger<ZzDataCmdService> logger,
|
||||||
|
ZzTcpService zTcpService)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_zTcpService = zTcpService;
|
||||||
|
|
||||||
|
StartAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task StartAsync()
|
||||||
|
{
|
||||||
|
await AppInit.WaitAsync(AppInit.DefaultTimeOut);
|
||||||
|
|
||||||
|
_ = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{//每秒发送一次命令
|
||||||
|
|
||||||
|
await SendYcCmd();
|
||||||
|
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(1));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_ = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{//每30秒发送一次命令
|
||||||
|
|
||||||
|
await SendVaCmd();
|
||||||
|
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(30));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<string> GetValidZzCmd(string cmdName, List<string> ids)
|
||||||
|
{
|
||||||
|
const int maxLength = 25000;
|
||||||
|
|
||||||
|
var cmds = new List<string>();
|
||||||
|
|
||||||
|
// 开始构建
|
||||||
|
string prefix = cmdName + "|"; // 固定前缀
|
||||||
|
int prefixLength = prefix.Length;
|
||||||
|
|
||||||
|
var currentIds = new List<string>();
|
||||||
|
int currentLength = prefixLength; // 当前命令的长度(含前缀)
|
||||||
|
|
||||||
|
foreach (var id in ids)
|
||||||
|
{
|
||||||
|
// 如果添加这个ID会超长,则先生成一个命令
|
||||||
|
int idLength = (currentIds.Count == 0 ? id.Length : (1 + id.Length)); // 第一个ID不需要 '#'
|
||||||
|
|
||||||
|
if (currentLength + idLength > maxLength)
|
||||||
|
{
|
||||||
|
// 将当前批次加入 cmds
|
||||||
|
cmds.Add(prefix + string.Join("#", currentIds));
|
||||||
|
|
||||||
|
// 清空并重建
|
||||||
|
currentIds.Clear();
|
||||||
|
currentLength = prefixLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加新的 ID
|
||||||
|
currentIds.Add(id);
|
||||||
|
currentLength += idLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收尾:如果还有剩余 IDs,生成最后一个命令
|
||||||
|
if (currentIds.Count > 0)
|
||||||
|
{
|
||||||
|
cmds.Add(prefix + string.Join("#", currentIds));
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmds;
|
||||||
|
}
|
||||||
|
|
||||||
|
//更新装置状态
|
||||||
|
public void UpdateDeviceCommState(string deviceId, bool commState)
|
||||||
|
{
|
||||||
|
_ycIds.UpdateDeviceCommState(deviceId, commState);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/////遥测
|
||||||
|
|
||||||
|
public void ClearYcIds()
|
||||||
|
{
|
||||||
|
_ycIds.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//计划巡检配置
|
||||||
|
public void AddCircuitPlanYcIds(SecondaryCircuitInspectionPlanStateModel[] planList)
|
||||||
|
{
|
||||||
|
foreach (var plan in planList)
|
||||||
|
{
|
||||||
|
foreach(var inspection in plan.Plan.InspectionItems)
|
||||||
|
{
|
||||||
|
foreach (var item in inspection.TelemetryConfigs)
|
||||||
|
{
|
||||||
|
if(!string.IsNullOrWhiteSpace(item.TelemetryConfigurationIsmsId) && item.TelemetryConfigurationIsmsId.StartsWith("YC"))
|
||||||
|
_ycIds.AddId(item.TelemetryConfigurationIsmsId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//事件巡检配置
|
||||||
|
public void AddEventPlanYcIds(SecondaryCircuitEventDrivenConfigOutput[] planList)
|
||||||
|
{
|
||||||
|
foreach (var plan in planList)
|
||||||
|
{
|
||||||
|
foreach(var item in plan.TelemetryConfigs)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(item.TelemetryConfigurationIsmsId) && item.TelemetryConfigurationIsmsId.StartsWith("YC"))
|
||||||
|
_ycIds.AddId(item.TelemetryConfigurationIsmsId);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var inspection in plan.SecondaryCircuitInspectionEventItems)
|
||||||
|
{
|
||||||
|
foreach (var item in inspection.TelemetryConfigs)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(item.TelemetryConfigurationIsmsId) && item.TelemetryConfigurationIsmsId.StartsWith("YC"))
|
||||||
|
_ycIds.AddId(item.TelemetryConfigurationIsmsId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int _sendCnt = 0;
|
||||||
|
private async Task SendYcCmd()
|
||||||
|
{
|
||||||
|
var ids = _ycIds.GetIds(null);
|
||||||
|
var cmds = GetValidZzCmd("CallYCByDataID", ids);
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var cmd in cmds)
|
||||||
|
{
|
||||||
|
await _zTcpService.SendTcpMessageAsync(cmd, CancellationToken.None);
|
||||||
|
|
||||||
|
if(_sendCnt % 60 == 0)
|
||||||
|
_logger.LogWarning($"发送命令:{ids.Count}个id");
|
||||||
|
|
||||||
|
_sendCnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task SendVaCmd()
|
||||||
|
{
|
||||||
|
string cmd = "CallVAByStat|B001";
|
||||||
|
await _zTcpService.SendTcpMessageAsync(cmd, CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user