接收业务系统调用设备服务信息

This commit is contained in:
ChenYi 2026-03-18 17:26:06 +08:00
parent 6da12cbf2d
commit ddd6d2e9e9
3 changed files with 169 additions and 11 deletions

View File

@ -0,0 +1,15 @@
using JiShe.ServicePro.Dto;
namespace JiShe.IoT.BusinessSystemAggregation
{
/// <summary>
/// 业务系统调用设备服务请求参数
/// </summary>
public class CallDeviceServiceRequestInfoDto: ReceiveCommandInfoDto
{
/// <summary>
/// 服务名称
/// </summary>
public string ServiceName { get; set; }
}
}

View File

@ -1,5 +1,6 @@
using JiShe.ServicePro;
using JiShe.ServicePro.ApacheIoTDB.Provider.Model;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Linq;
@ -46,6 +47,12 @@ namespace JiShe.IoT.BusinessSystemAggregation
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<HttpDataResult> BatchCreateDeviceInfoAsync(OpenApiRequest input);
Task<HttpDataResult> BatchCreateDeviceInfoAsync(OpenApiRequest input);
/// <summary>
/// 接收业务系统调用设备服务信息Msg 字段为 CallDeviceServiceRequestInfoDto 实体
/// </summary>
Task<HttpDataResult<Dictionary<string, object>>> CallDeviceServiceToOneNETForApiAsync(OpenApiRequest input);
}
}

View File

@ -96,7 +96,7 @@ namespace JiShe.IoT.BusinessSystemAggregation
}
List<DeviceTelemetryCommandTypeEnum> actionTypes = new List<DeviceTelemetryCommandTypeEnum>() {
DeviceTelemetryCommandTypeEnum.OperateBreaker,
DeviceTelemetryCommandTypeEnum.OperateService,
DeviceTelemetryCommandTypeEnum.RoutineOperationSet,
};
@ -118,7 +118,7 @@ namespace JiShe.IoT.BusinessSystemAggregation
{
return HttpDataResultExtensions.Failed("设备不存在", -1041, ResponeResultEnum.Fail);
}
//将指令存储IoTDB数据库和Redis发布通道
if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.OneNET)
{
@ -136,7 +136,7 @@ namespace JiShe.IoT.BusinessSystemAggregation
var tempPlatformThingModelInfo = platformThingModelInfo.Where(d => d.IoTPlatformRawFieldName == item.Key).FirstOrDefault();
if (tempPlatformThingModelInfo == null)
{
_logger.LogError($"业务系统推送指令时设备设备{deviceInfo.DeviceAddress}平台端物模型信息不存在属性标识符{item.Key}。");
_logger.LogError($"业务系统推送指令时设备{deviceInfo.DeviceAddress}平台端物模型信息不存在属性标识符{item.Key}。");
messageBody.Commands.RemoveAll(d => d.Key == item.Key);
continue;
}
@ -213,14 +213,14 @@ namespace JiShe.IoT.BusinessSystemAggregation
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("获取数据失败,设备属性值不能为空", -102, ResponeResultEnum.Fail);
}
var restrictionKey = string.Format(RedisConst.CacheDeviceOpenApiRestrictionKey,nameof(ReceiveGetCommandInfoAsync), messageBody.DeviceAddress);
var openApiDeviceRequest = FreeRedisProvider.Instance.Get(restrictionKey);
var restrictionKey = string.Format(RedisConst.CacheDeviceOpenApiRestrictionKey, nameof(ReceiveGetCommandInfoAsync), messageBody.DeviceAddress);
var openApiDeviceRequest = FreeRedisProvider.Instance.Get(restrictionKey);
if (openApiDeviceRequest != null)
{
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("获取数据失败,设备请求被限制", -103, ResponeResultEnum.Fail);
}
FreeRedisProvider.Instance.Set(restrictionKey,"1",TimeSpan.FromSeconds(5));
FreeRedisProvider.Instance.Set(restrictionKey, "1", TimeSpan.FromSeconds(5));
//限定来源类型必须为业务系统
if (messageBody.SourceType != DeviceTelemetrySourceTypeEnum.BusinessSystem)
@ -240,7 +240,7 @@ namespace JiShe.IoT.BusinessSystemAggregation
{
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("设备不存在", -106, ResponeResultEnum.Fail);
}
//将指令存储IoTDB数据库和Redis发布通道
if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.OneNET)
{
@ -263,7 +263,7 @@ namespace JiShe.IoT.BusinessSystemAggregation
messageBody.Commands.RemoveAll(d => d.Key == item.Key);
continue;
}
if (deviceInfo.IsNeedConfigDeviceModel && deviceInfo.DeviceThingModelDataId.HasValue && item.Key.ToLowerInvariant() == ThingModelFixedTypeConst.SpecialCommand.ToLowerInvariant())
{
_logger.LogError($"业务系统推送指令时设备{deviceInfo.DeviceAddress}平台端物模型属性标识符{item.Key}是特殊指令操作,被禁止。");
@ -278,7 +278,7 @@ namespace JiShe.IoT.BusinessSystemAggregation
messageBody.Commands.RemoveAll(d => d.Key == item.Key);
continue;
}
commands.Add(tempPlatformThingModelInfo.IoTPlatformRawFieldName,item.Key);
commands.Add(tempPlatformThingModelInfo.IoTPlatformRawFieldName, item.Key);
}
if (commands == null || commands.Count <= 0)
@ -292,7 +292,7 @@ namespace JiShe.IoT.BusinessSystemAggregation
//数据写入遥测任务数据存储通道
await ioTDBDataChannelManageService.DeviceTelemetryTaskWriterAsync(DataChannelManage.DeviceTelemetryTaskDataChannel.Writer, (DistributedMessageCenterConst.OneNETCommandIssuedEventName, packetTaskInfo));
var queryResult = await DevicePropertyValueToOneNET(deviceInfo, new DevicePropertyValueForApiInput() { PropertyList = commands.Select(d => d.Key).ToList() });
if (queryResult == null || queryResult.Count <= 0)
@ -616,5 +616,141 @@ namespace JiShe.IoT.BusinessSystemAggregation
!deviceAddress.Contains("*") &&
!deviceAddress.Contains("~");
}
/// <summary>
/// 接收业务系统调用设备服务信息Msg 字段为 CallDeviceServiceRequestInfoDto 实体
/// </summary>
[AllowAnonymous]
public async Task<HttpDataResult<Dictionary<string, object>>> CallDeviceServiceToOneNETForApiAsync(OpenApiRequest input)
{
try
{
var handleResult = HandleOpenApiRequest<CallDeviceServiceRequestInfoDto>(input, serverApplicationOptions);
if (handleResult.Success == false)
{
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("获取数据失败,签名校验异常", -101);
}
var messageBody = handleResult.Data;
if (messageBody == null || messageBody.Commands == null || messageBody.Commands.Count <= 0 || string.IsNullOrWhiteSpace(messageBody.DeviceAddress) || string.IsNullOrWhiteSpace(messageBody.ServiceName))
{
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("服务调用失败,服务调用参数不能为空", -102, ResponeResultEnum.Fail);
}
var restrictionKey = string.Format(RedisConst.CacheDeviceOpenApiRestrictionKey, nameof(ReceiveGetCommandInfoAsync), messageBody.DeviceAddress);
var openApiDeviceRequest = FreeRedisProvider.Instance.Get(restrictionKey);
if (openApiDeviceRequest != null)
{
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("服务调用失败,设备请求被限制", -103, ResponeResultEnum.Fail);
}
FreeRedisProvider.Instance.Set(restrictionKey, "1", TimeSpan.FromSeconds(5));
//限定来源类型必须为业务系统
if (messageBody.SourceType != DeviceTelemetrySourceTypeEnum.BusinessSystem)
{
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("服务调用失败来源类型错误业务系统传固定值2", -104, ResponeResultEnum.Fail);
}
//限定操作类型必须为设备服务调用类型
if (messageBody.TelemetryCommandType != DeviceTelemetryCommandTypeEnum.OperateService)
{
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("服务调用失败,指令操作类型错误", -105, ResponeResultEnum.Fail);
}
var deviceInfo = await deviceAppService.FindByDeviceAddressAsync(messageBody.DeviceAddress);
if (deviceInfo == null)
{
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("设备不存在", -106, ResponeResultEnum.Fail);
}
//将指令存储IoTDB数据库和Redis发布通道
if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.OneNET)
{
//获取设备对应的平台端物模型信息,校验前端传入的属性标识集合是否存在不合法的属性标识符
var platformThingModelInfo = await platformThingModelInfoAppService.FindByPlatformProductIdAsync(new IdInput<string>() { Id = deviceInfo.IoTPlatformProductId });
if (platformThingModelInfo == null)
{
return HttpDataResultExtensions.Failed<Dictionary<string, object>>($"业务系统设备服务调时,{deviceInfo.DeviceAddress}的平台端物模型信息不存在。", -107, ResponeResultEnum.Fail);
}
Dictionary<string, string> commands = new Dictionary<string, string>();
foreach (var item in messageBody.Commands)
{
var tempPlatformThingModelInfo = platformThingModelInfo.Where(d => d.StandardFieldName == item.Key).FirstOrDefault();
if (tempPlatformThingModelInfo == null)
{
_logger.LogError($"业务系统设备服务调时{deviceInfo.DeviceAddress}平台端物模型信息不存在属性标识符{item.Key}。");
messageBody.Commands.RemoveAll(d => d.Key == item.Key);
continue;
}
//排除指令
if (exitCommands.Contains(tempPlatformThingModelInfo.StandardFieldName.ToLowerInvariant()))
{
_logger.LogError($"业务系统设备服务调时{deviceInfo.DeviceAddress}平台端物模型属性标识符{item.Key}是升级指令操作,被禁止。");
messageBody.Commands.RemoveAll(d => d.Key == item.Key);
continue;
}
commands.Add(tempPlatformThingModelInfo.IoTPlatformRawFieldName, item.Key);
}
if (commands == null || commands.Count <= 0)
{
_logger.LogError($"业务系统设备服务调时{deviceInfo.DeviceAddress}未匹配到具体数据模型,被禁止。");
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("业务系统设备服务调失败,未匹配到具体数据模型", -108);
}
var packetTaskInfo = GetDeviceTelemetryPacketTaskInfo(ioTDBOptions, input, deviceInfo.Adapt<DeviceCacheInfos>(), commands.Serialize());
//数据写入遥测任务数据存储通道
await ioTDBDataChannelManageService.DeviceTelemetryTaskWriterAsync(DataChannelManage.DeviceTelemetryTaskDataChannel.Writer, (DistributedMessageCenterConst.OneNETCommandIssuedEventName, packetTaskInfo));
var queryResult = await CallDeviceServiceToOneNET(deviceInfo, new CallDeviceServiceForApiInput()
{
ServiceParams = messageBody.Commands,
ServiceName = messageBody.ServiceName,
});
if (queryResult == null || queryResult.Count <= 0)
{
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("业务系统设备服务调失败OneNET平台未返回数据", -109);
}
Dictionary<string, object> result = new Dictionary<string, object>();
foreach (var item in commands)
{
result.Add(item.Value, queryResult[item.Key]);
}
return HttpDataResultExtensions.Success<Dictionary<string, object>>(result);
}
else if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.CTWing)
{
//await redisPubSubService.PublishReliableAsync(DistributedMessageCenterConst.CTWingAepCommandIssuedEventName, input);
}
else
{
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("指令处理失败,当前设备平台类型异常", -110);
}
return HttpDataResultExtensions.Success<Dictionary<string, object>>("指令下发成功");
}
catch (UserFriendlyException ex)
{
_logger.LogError(ex, "接收业务系统指令信息时发生异常");
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("设备属性数据获取失败,发送异常", -111);
}
catch (Exception ex)
{
_logger.LogError(ex, "接收业务系统指令信息时发生异常");
return HttpDataResultExtensions.Failed<Dictionary<string, object>>("设备属性数据获取失败,发送异常", -112);
}
}
}
}