diff --git a/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs b/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs index f30318b..f4d00b8 100644 --- a/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs +++ b/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs @@ -347,6 +347,115 @@ namespace JiShe.IoT.DeviceAggregation } } + /// + /// 验证并获取固件信息和文件信息 + /// + /// 固件版本数据Id + /// 物联网平台产品Id + /// 固件信息不存在的错误代码(可选,用于批量操作时的错误代码) + /// 文件信息不存在的错误代码(可选,用于批量操作时的错误代码) + /// 返回固件信息和文件信息的元组 + private async Task<(DeviceFirmwareInfoDto FirmwareInfo, FileObjectDto FileInfo)> ValidateAndGetFirmwareInfoAsync(Guid firmwareVersionDataId, string iotPlatformProductId, string firmwareNotFoundErrorCode = null, string fileNotFoundErrorCode = null) + { + var deviceFirmwareVersionInfo = await deviceFirmwareInfoService.FindByIdAsync(new IdInput() { Id = firmwareVersionDataId }); + + if (deviceFirmwareVersionInfo == null) + { + var errorMsg = $"产品Id{iotPlatformProductId}的新固件信息{firmwareVersionDataId}不存在"; + throw new UserFriendlyException(errorMsg, firmwareNotFoundErrorCode ?? string.Empty); + } + + var fileInfo = await fileAppService.GetFileAsync(new IdInput() { Id = deviceFirmwareVersionInfo.FirmwareFileId }); + + if (fileInfo == null) + { + var errorMsg = $"产品Id{iotPlatformProductId}的新固件信息{deviceFirmwareVersionInfo.FirmwareFileName}固件文件不存在"; + throw new UserFriendlyException(errorMsg, fileNotFoundErrorCode ?? string.Empty); + } + + return (deviceFirmwareVersionInfo, fileInfo); + } + + /// + /// 创建接收指令信息Dto + /// + /// 设备信息 + /// 接收指令信息Dto + private ReceiveCommandInfoDto CreateReceiveCommandInfoDto(DeviceManagementInfoDto deviceInfo) + { + return new ReceiveCommandInfoDto() + { + DeviceAddress = deviceInfo.DeviceAddress, + DeviceType = deviceInfo.DeviceType, + SourceType = DeviceTelemetrySourceTypeEnum.AdminSystem, + IoTPlatform = deviceInfo.IoTPlatform, + }; + } + + /// + /// 获取OneNET产品信息和平台端物模型信息 + /// + /// 物联网平台产品Id + /// 设备地址(用于错误信息) + /// 返回产品信息和平台端物模型信息的元组 + private async Task<(dynamic ProductInfo, dynamic PlatformThingModelInfo)> GetOneNETProductAndThingModelInfoAsync(string iotPlatformProductId, string deviceAddress) + { + //获取设备对应的产品信息 + var productInfo = await oneNETProductService.GetProductInfoAsync(new IdInput() { Id = iotPlatformProductId }); + + if (productInfo == null) + { + throw new UserFriendlyException($"{nameof(DeviceUpgradeCommandToOneNET)} OneNET设备升级属性设置失败,产品Id{iotPlatformProductId}未找到对应的产品信息。"); + } + + //获取设备对应的平台端物模型信息,校验前端传入的属性标识集合是否存在不合法的属性标识符 + var platformThingModelInfo = await platformThingModelInfoAppService.FindByPlatformProductIdAsync(new IdInput() { Id = iotPlatformProductId }); + + if (platformThingModelInfo == null) + { + throw new UserFriendlyException($"设备{deviceAddress}的平台端物模型信息不存在。"); + } + + return (productInfo, platformThingModelInfo); + } + + /// + /// 根据平台处理设备升级指令 + /// + /// 设备信息 + /// 接收指令信息Dto + /// 固件版本信息 + /// 文件信息 + /// 升级输入参数 + /// OneNET产品信息(可选,如果已获取则传入以避免重复调用) + /// OneNET平台端物模型信息(可选,如果已获取则传入以避免重复调用) + /// 处理结果 + private async Task ProcessDeviceUpgradeByPlatformAsync(DeviceManagementInfoDto deviceInfo, ReceiveCommandInfoDto receiveCommandInfoDto, DeviceFirmwareInfoDto deviceFirmwareVersionInfo, FileObjectDto fileInfo, DeviceUpgradeForApiInput input, dynamic oneNETProductInfo = null, dynamic oneNETPlatformThingModelInfo = null) + { + if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.OneNET) + { + //如果未传入产品信息和物模型信息,则获取 + if (oneNETProductInfo == null || oneNETPlatformThingModelInfo == null) + { + var (productInfo, platformThingModelInfo) = await GetOneNETProductAndThingModelInfoAsync(deviceInfo.IoTPlatformProductId, deviceInfo.DeviceAddress); + oneNETProductInfo = productInfo; + oneNETPlatformThingModelInfo = platformThingModelInfo; + } + + return await DeviceUpgradeCommandToOneNET(deviceInfo, receiveCommandInfoDto, deviceFirmwareVersionInfo, fileInfo, input, oneNETProductInfo, oneNETPlatformThingModelInfo); + } + else if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.CTWing) + { + //await redisPubSubService.PublishReliableAsync(DistributedMessageCenterConst.CTWingAepCommandIssuedEventName,commandRequest); + //return true; + throw new UserFriendlyException($"发送设备升级指令信息失败,CTWing暂未实现。"); + } + else + { + throw new UserFriendlyException($"发送设备升级指令信息失败,未找到对应的产品配置信息。"); + } + } + /// /// 发送设备升级指令信息 /// @@ -362,45 +471,11 @@ namespace JiShe.IoT.DeviceAggregation throw new UserFriendlyException($"设备{input.Id}不存在"); } - //将指令存储 - var receiveCommandInfoDto = new ReceiveCommandInfoDto() - { - DeviceAddress = deviceInfo.DeviceAddress, - DeviceType = deviceInfo.DeviceType, - SourceType = DeviceTelemetrySourceTypeEnum.AdminSystem, - IoTPlatform = deviceInfo.IoTPlatform, - }; + var receiveCommandInfoDto = CreateReceiveCommandInfoDto(deviceInfo); - //固件信息 - var deviceFirmwareVersionInfo = await deviceFirmwareInfoService.FindByIdAsync(new IdInput() { Id = input.NowFirmwareVersionDataId }); + var (deviceFirmwareVersionInfo, fileInfo) = await ValidateAndGetFirmwareInfoAsync(input.NowFirmwareVersionDataId, input.IoTPlatformProductId); - if (deviceFirmwareVersionInfo == null) - { - throw new UserFriendlyException($"产品Id{input.IoTPlatformProductId}的新固件信息{input.NowFirmwareVersionDataId}不存在"); - } - - var fileInfo = await fileAppService.GetFileAsync(new IdInput() { Id = deviceFirmwareVersionInfo.FirmwareFileId }); - - if (fileInfo == null) - { - throw new UserFriendlyException($"产品Id{input.IoTPlatformProductId}的新固件信息{deviceFirmwareVersionInfo.FirmwareFileName}固件文件不存在"); - } - - //数据写入遥测任务数据存储通道 - if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.OneNET) - { - return await DeviceUpgradeCommandToOneNET(deviceInfo, receiveCommandInfoDto, deviceFirmwareVersionInfo, fileInfo, input); - } - else if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.CTWing) - { - //await redisPubSubService.PublishReliableAsync(DistributedMessageCenterConst.CTWingAepCommandIssuedEventName,commandRequest); - //return true; - throw new UserFriendlyException($"发送设备升级指令信息失败,CTWing暂未实现。"); - } - else - { - throw new UserFriendlyException($"发送设备升级指令信息失败,未找到对应的产品配置信息。"); - } + return await ProcessDeviceUpgradeByPlatformAsync(deviceInfo, receiveCommandInfoDto, deviceFirmwareVersionInfo, fileInfo, input); } catch (Exception) { @@ -427,23 +502,24 @@ namespace JiShe.IoT.DeviceAggregation throw new UserFriendlyException($"{nameof(DeviceBatchUpgradeForApiAsync)} 设备批量升级时地址列表数量不能超过200", "-102"); } - //固件信息 - var deviceFirmwareVersionInfo = await deviceFirmwareInfoService.FindByIdAsync(new IdInput() { Id = input.NowFirmwareVersionDataId }); - - if (deviceFirmwareVersionInfo == null) - { - throw new UserFriendlyException($"产品Id{input.IoTPlatformProductId}的新固件信息{input.NowFirmwareVersionDataId}不存在", "-103"); - } - - var fileInfo = await fileAppService.GetFileAsync(new IdInput() { Id = deviceFirmwareVersionInfo.FirmwareFileId }); - - if (fileInfo == null) - { - throw new UserFriendlyException($"产品Id{input.IoTPlatformProductId}的新固件信息{deviceFirmwareVersionInfo.FirmwareFileName}固件文件不存在", "-104"); - } + var (deviceFirmwareVersionInfo, fileInfo) = await ValidateAndGetFirmwareInfoAsync(input.NowFirmwareVersionDataId, input.IoTPlatformProductId, "-103", "-104"); var deviceInfoList = await deviceAppService.FindByDeviceAddressAsync(new FindByDeviceAddressInput() { AddressList = input.AddressList ,IoTPlatform = input.IoTPlatform,IoTPlatformProductId = input.IoTPlatformProductId}); + //如果是OneNET平台,提前获取产品信息和物模型信息,避免在循环中重复调用 + dynamic oneNETProductInfo = null; + dynamic oneNETPlatformThingModelInfo = null; + if (input.IoTPlatform == IoTPlatformTypeEnum.OneNET && deviceInfoList != null && deviceInfoList.Count > 0) + { + var firstDevice = deviceInfoList.FirstOrDefault(); + if (firstDevice != null) + { + var (productInfo, platformThingModelInfo) = await GetOneNETProductAndThingModelInfoAsync(firstDevice.IoTPlatformProductId, firstDevice.DeviceAddress); + oneNETProductInfo = productInfo; + oneNETPlatformThingModelInfo = platformThingModelInfo; + } + } + List deviceAddress = new List();//异常的设备地址集合 foreach (var item in input.AddressList) @@ -452,41 +528,26 @@ namespace JiShe.IoT.DeviceAggregation if (deviceInfo == null) { deviceAddress.Add(item); - continue; } - //将指令存储 - var receiveCommandInfoDto = new ReceiveCommandInfoDto() - { - DeviceAddress = deviceInfo.DeviceAddress, - DeviceType = deviceInfo.DeviceType, - SourceType = DeviceTelemetrySourceTypeEnum.AdminSystem, - IoTPlatform = deviceInfo.IoTPlatform, - }; + var receiveCommandInfoDto = CreateReceiveCommandInfoDto(deviceInfo); var deviceUpgradeRecordInput = input.Adapt(); deviceUpgradeRecordInput.Id = deviceInfo.Id; - //数据写入遥测任务数据存储通道 - if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.OneNET) + try { - var oneNETHandleResult = await DeviceUpgradeCommandToOneNET(deviceInfo, receiveCommandInfoDto, deviceFirmwareVersionInfo, fileInfo, deviceUpgradeRecordInput); + var oneNETHandleResult = await ProcessDeviceUpgradeByPlatformAsync(deviceInfo, receiveCommandInfoDto, deviceFirmwareVersionInfo, fileInfo, deviceUpgradeRecordInput, oneNETProductInfo, oneNETPlatformThingModelInfo); if (!oneNETHandleResult) { deviceAddress.Add(item); } } - else if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.CTWing) + catch (Exception) { - //await redisPubSubService.PublishReliableAsync(DistributedMessageCenterConst.CTWingAepCommandIssuedEventName,commandRequest); - //return true; - throw new UserFriendlyException($"发送设备升级指令信息失败,CTWing暂未实现。"); - } - else - { - throw new UserFriendlyException($"发送设备升级指令信息失败,未找到对应的产品配置信息。"); + deviceAddress.Add(item); } } @@ -957,9 +1018,11 @@ namespace JiShe.IoT.DeviceAggregation /// 固件数据Id /// 固件文件信息 /// 入参 + /// 产品信息(如果已获取则传入以避免重复调用) + /// 平台端物模型信息(如果已获取则传入以避免重复调用) /// /// - protected async Task DeviceUpgradeCommandToOneNET(DeviceManagementInfoDto deviceInfo, ReceiveCommandInfoDto taskInput, DeviceFirmwareInfoDto deviceFirmwareInfo, FileObjectDto fileObject, DeviceUpgradeForApiInput input) + protected async Task DeviceUpgradeCommandToOneNET(DeviceManagementInfoDto deviceInfo, ReceiveCommandInfoDto taskInput, DeviceFirmwareInfoDto deviceFirmwareInfo, FileObjectDto fileObject, DeviceUpgradeForApiInput input, dynamic productInfo = null, dynamic platformThingModelInfo = null) { try { @@ -973,23 +1036,15 @@ namespace JiShe.IoT.DeviceAggregation throw new UserFriendlyException($"设备{deviceInfo.DeviceAddress}平台产品信息固件中不一致"); } - //获取设备对应的产品信息 - var productInfo = await oneNETProductService.GetProductInfoAsync(new IdInput() { Id = deviceInfo.IoTPlatformProductId }); - - if (productInfo == null) + //如果未传入产品信息和物模型信息,则获取 + if (productInfo == null || platformThingModelInfo == null) { - throw new UserFriendlyException($"{nameof(DeviceUpgradeCommandToOneNET)} OneNET设备升级属性设置失败,产品Id{deviceInfo.IoTPlatformProductId}未找到对应的产品信息。"); + var (productInfoResult, platformThingModelInfoResult) = await GetOneNETProductAndThingModelInfoAsync(deviceInfo.IoTPlatformProductId, deviceInfo.DeviceAddress); + productInfo = productInfoResult; + platformThingModelInfo = platformThingModelInfoResult; } - //获取设备对应的平台端物模型信息,校验前端传入的属性标识集合是否存在不合法的属性标识符 - var platformThingModelInfo = await platformThingModelInfoAppService.FindByPlatformProductIdAsync(new IdInput() { Id = deviceInfo.IoTPlatformProductId }); - - if (platformThingModelInfo == null) - { - throw new UserFriendlyException($"设备{deviceInfo.DeviceAddress}的平台端物模型信息不存在。"); - } - - var upgradeProperty = platformThingModelInfo.Where(d => d.StandardFieldName == ThingModelFixedTypeConst.FIRMWARE_UPGRADE).FirstOrDefault(); + var upgradeProperty = ((List)platformThingModelInfo).Where(d => d.StandardFieldName == ThingModelFixedTypeConst.FIRMWARE_UPGRADE).FirstOrDefault(); if (upgradeProperty == null) { throw new UserFriendlyException($"设备{deviceInfo.DeviceAddress}平台端物模型信息不存在升级属性标识符{ThingModelFixedTypeConst.FIRMWARE_UPGRADE}。");