diff --git a/JiShe.ServicePro b/JiShe.ServicePro index f038a3c..7e17249 160000 --- a/JiShe.ServicePro +++ b/JiShe.ServicePro @@ -1 +1 @@ -Subproject commit f038a3c4239c680b512523d7b777c7e73cbc1ebf +Subproject commit 7e17249fcd7a289a03a75d2c59ddefd4b165a36a diff --git a/src/JiShe.IoT.Application.Contracts/DeviceAggregation/Dto/CreateDeviceAggregationInput.cs b/src/JiShe.IoT.Application.Contracts/DeviceAggregation/Dto/CreateDeviceAggregationInput.cs index 512d62a..6097e0a 100644 --- a/src/JiShe.IoT.Application.Contracts/DeviceAggregation/Dto/CreateDeviceAggregationInput.cs +++ b/src/JiShe.IoT.Application.Contracts/DeviceAggregation/Dto/CreateDeviceAggregationInput.cs @@ -21,7 +21,7 @@ namespace JiShe.IoT.DeviceAggregation.Dto public IoTPlatformTypeEnum IoTPlatform { get; set; } /// - /// 集中器在物联网平台中对应的产品Id + /// 设备在物联网平台中对应的产品Id /// [Required(ErrorMessage = "产品Id不能为空")] public string IoTPlatformProductId { get; set; } diff --git a/src/JiShe.IoT.Application.Contracts/DeviceAggregation/Dto/DeviceCommandForApiInput.cs b/src/JiShe.IoT.Application.Contracts/DeviceAggregation/Dto/DeviceCommandForApiInput.cs new file mode 100644 index 0000000..2905958 --- /dev/null +++ b/src/JiShe.IoT.Application.Contracts/DeviceAggregation/Dto/DeviceCommandForApiInput.cs @@ -0,0 +1,36 @@ +using JiShe.ServicePro.Enums; +using System.ComponentModel.DataAnnotations; + +namespace JiShe.IoT.DeviceAggregation +{ + + /// + /// 设备命令 + /// + public class DeviceCommandForApiInput + { + /// + /// 表通信地址 + /// + [Required(ErrorMessage = "设备地址不能为空")] + public string DeviceAddress { get; set; } + + /// + /// 物联网平台类型 + /// + [Required(ErrorMessage = "物联网平台类型不能为空")] + public IoTPlatformTypeEnum IoTPlatform { get; set; } + + /// + /// 设备在物联网平台中对应的产品Id + /// + [Required(ErrorMessage = "产品Id不能为空")] + public string IoTPlatformProductId { get; set; } + + /// + /// 设备在物联网平台中发送的命令内容,JSON格式 + /// + [Required(ErrorMessage = "命令内容不能为空")] + public string CommandContent { get; set; } + } +} \ No newline at end of file diff --git a/src/JiShe.IoT.Application.Contracts/DeviceAggregation/IDeviceAggregationService.cs b/src/JiShe.IoT.Application.Contracts/DeviceAggregation/IDeviceAggregationService.cs index 9aa3655..c089d76 100644 --- a/src/JiShe.IoT.Application.Contracts/DeviceAggregation/IDeviceAggregationService.cs +++ b/src/JiShe.IoT.Application.Contracts/DeviceAggregation/IDeviceAggregationService.cs @@ -38,6 +38,13 @@ namespace JiShe.IoT.DeviceAggregation /// Task BatchCreateDeviceWorkshopAsync(BatchCreateDeviceAggregationInput input); + /// + /// 发送设备指令信息 + /// + /// + /// + Task DeviceCommandForApiAsync(DeviceCommandForApiInput input); + /// /// 删除设备信息 /// diff --git a/src/JiShe.IoT.Application.Contracts/JiShe.IoT.Application.Contracts.csproj b/src/JiShe.IoT.Application.Contracts/JiShe.IoT.Application.Contracts.csproj index b240040..527e95e 100644 --- a/src/JiShe.IoT.Application.Contracts/JiShe.IoT.Application.Contracts.csproj +++ b/src/JiShe.IoT.Application.Contracts/JiShe.IoT.Application.Contracts.csproj @@ -43,4 +43,8 @@ + + + + \ No newline at end of file diff --git a/src/JiShe.IoT.Application/BusinessSystemAggregation/BusinessSystemAggregationService.cs b/src/JiShe.IoT.Application/BusinessSystemAggregation/BusinessSystemAggregationService.cs index 341e7a9..e3e2fa4 100644 --- a/src/JiShe.IoT.Application/BusinessSystemAggregation/BusinessSystemAggregationService.cs +++ b/src/JiShe.IoT.Application/BusinessSystemAggregation/BusinessSystemAggregationService.cs @@ -1,5 +1,8 @@ using JiShe.IoT.OneNETAggregation.Dto; using JiShe.ServicePro; +using JiShe.ServicePro.Core; +using JiShe.ServicePro.DeviceManagement.DeviceInfos; +using JiShe.ServicePro.Dto; using JiShe.ServicePro.Encrypt; using JiShe.ServicePro.Enums; using JiShe.ServicePro.Kafka.Consts; @@ -18,7 +21,7 @@ namespace JiShe.IoT.BusinessSystemAggregation /// /// 业务系统聚合服务 /// - public class BusinessSystemAggregationService(IOptions options, IKafkaProducerService _producerService) :IoTAppService, IBusinessSystemAggregationService + public class BusinessSystemAggregationService(IOptions options, IKafkaProducerService _producerService, IDeviceAppService deviceAppService) : IoTAppService, IBusinessSystemAggregationService { ServerApplicationOptions srverOptions = options.Value; @@ -34,16 +37,38 @@ namespace JiShe.IoT.BusinessSystemAggregation bool verifySignatureReult = EncryptUtil.OpenApiVerifySignature(input.Message, input.Nonce, input.Timestamp, input.Signature, srverOptions.VerifySignatureToken); if (verifySignatureReult == false)//签名校验失败 { - return HttpDataResultExtensions.Failed>("签名校验失败", -101, ResponeResultEnum.NotAllowed); + return HttpDataResultExtensions.Failed("签名校验失败", -101, ResponeResultEnum.NotAllowed); } if (string.IsNullOrWhiteSpace(input.Message)) { - return HttpDataResultExtensions.Failed>("指令下发内容不能为空", -102, ResponeResultEnum.Fail); + return HttpDataResultExtensions.Failed("指令下发内容不能为空", -102, ResponeResultEnum.Fail); } - //将指令存储Kafka中 - await _producerService.ProduceAsync(KafkaTopicConsts.OneNETCommandIssuedEventName, $"{GuidGenerator.Create()}", input); + //查询设备信息,判断设备在哪个平台 + var messageBody = input.Message.Deserialize(); + + //限定来源类型必须为业务系统 + if (messageBody.SourceType != DeviceTelemetrySourceTypeEnum.BusinessSystem) + { + return HttpDataResultExtensions.Failed("设备指令来源类型错误,业务系统传固定值2", -103, ResponeResultEnum.Fail); + } + + var deviceInfo = await deviceAppService.FindByDeviceAddressAsync(messageBody.DeviceAddress); + + //将指令存储Kafka的OneNET主题中 + if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.OneNET) + { + await _producerService.ProduceAsync(KafkaTopicConsts.OneNETCommandIssuedEventName, $"{GuidGenerator.Create()}", input); + } + else if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.CTWing) + { + await _producerService.ProduceAsync(KafkaTopicConsts.CTWingAepCommandIssuedEventName, $"{GuidGenerator.Create()}", input); + } + else + { + return HttpDataResultExtensions.Failed("指令处理失败,当前设备平台类型异常",-104); + } return HttpDataResultExtensions.Success("指令下发Kafka成功"); } diff --git a/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs b/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs index 70f3fbc..e7ceb2a 100644 --- a/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs +++ b/src/JiShe.IoT.Application/DeviceAggregation/DeviceAggregationService.cs @@ -4,8 +4,11 @@ using JiShe.ServicePro.Core; using JiShe.ServicePro.DeviceManagement.DeviceInfos; using JiShe.ServicePro.DeviceManagement.DeviceInfos.Dto; using JiShe.ServicePro.DeviceManagement.Permissions; +using JiShe.ServicePro.Dto; using JiShe.ServicePro.Enums; using JiShe.ServicePro.FreeRedisProvider; +using JiShe.ServicePro.Kafka.Consts; +using JiShe.ServicePro.Kafka.Producer; using JiShe.ServicePro.OneNET.Provider.OpenApiModels.Devices; using JiShe.ServicePro.OneNETManagement.OneNETDevices; using JiShe.ServicePro.OneNETManagement.OneNETProducts; @@ -21,7 +24,8 @@ namespace JiShe.IoT.DeviceAggregation /// /// 设备服务 /// OneNET设备服务 - public class DeviceAggregationService(ILogger logger, IDeviceAppService deviceAppService, IOneNETDeviceService oneNETDeviceService) : IoTAppService, IDeviceAggregationService + /// KafKa生产服务 + public class DeviceAggregationService(ILogger logger, IDeviceAppService deviceAppService, IOneNETDeviceService oneNETDeviceService, IKafkaProducerService producerService) : IoTAppService, IDeviceAggregationService { /// /// 管理后台创建设备信息 @@ -266,6 +270,50 @@ namespace JiShe.IoT.DeviceAggregation return input.Adapt(); } + /// + /// 发送设备指令信息 + /// + /// + /// + public async Task DeviceCommandForApiAsync(DeviceCommandForApiInput input) + { + try + { + var deviceInfo = await deviceAppService.FindByDeviceAddressAsync(input.DeviceAddress); + //将指令存储Kafka的OneNET主题中 + var commandRequest = new OpenApiRequest() + { + Message = new ReceiveCommandInfoDto() + { + DeviceAddress = input.DeviceAddress, + Commands = input.CommandContent.Deserialize>(), + DeviceType = DeviceTypeEnum.Focus,//todo 设备类型 需要跟设备统一什么情况下知道具体设备类型 + SourceType = DeviceTelemetrySourceTypeEnum.AdminSystem, + }.Serialize(), + }; + + if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.OneNET) + { + await producerService.ProduceAsync(KafkaTopicConsts.OneNETCommandIssuedEventName, $"{GuidGenerator.Create()}", commandRequest); + return true; + } + else if (deviceInfo.IoTPlatform == IoTPlatformTypeEnum.CTWing) + { + await producerService.ProduceAsync(KafkaTopicConsts.CTWingAepCommandIssuedEventName, $"{GuidGenerator.Create()}", commandRequest); + return true; + } + else + { + throw new UserFriendlyException($"创建设备失败,未找到对应的产品配置信息。"); + } + } + catch (Exception) + { + + throw; + } + } + #region OneNET 设备操作 /// @@ -465,7 +513,7 @@ namespace JiShe.IoT.DeviceAggregation try { var productInfo = await FreeSqlDbContext.Instance.Select() - .Where(e => e.IsEnabled == true && e.IoTPlatformProductId == input.IoTPlatformProductId) + .Where(e => e.IoTPlatformProductId == input.IoTPlatformProductId) .FirstAsync(); if (productInfo == null)