Commit 0bb01eaeeb1c7431b981f14484a79c95ed69ae7c
1 parent
ac624b74
feat:【IoT 物联网】消息下行时,增加 serverId 的接入
Showing
51 changed files
with
624 additions
and
822 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/IotDeviceUpstreamApi.java
| ... | ... | @@ -18,59 +18,6 @@ public interface IotDeviceUpstreamApi { |
| 18 | 18 | |
| 19 | 19 | String PREFIX = ApiConstants.PREFIX + "/device/upstream"; |
| 20 | 20 | |
| 21 | - // ========== 设备相关 ========== | |
| 22 | - | |
| 23 | - /** | |
| 24 | - * 更新设备状态 | |
| 25 | - * | |
| 26 | - * @param updateReqDTO 更新设备状态 DTO | |
| 27 | - */ | |
| 28 | - @PostMapping(PREFIX + "/update-state") | |
| 29 | - CommonResult<Boolean> updateDeviceState(@Valid @RequestBody IotDeviceStateUpdateReqDTO updateReqDTO); | |
| 30 | - | |
| 31 | - /** | |
| 32 | - * 上报设备属性数据 | |
| 33 | - * | |
| 34 | - * @param reportReqDTO 上报设备属性数据 DTO | |
| 35 | - */ | |
| 36 | - @PostMapping(PREFIX + "/report-property") | |
| 37 | - CommonResult<Boolean> reportDeviceProperty(@Valid @RequestBody IotDevicePropertyReportReqDTO reportReqDTO); | |
| 38 | - | |
| 39 | - /** | |
| 40 | - * 上报设备事件数据 | |
| 41 | - * | |
| 42 | - * @param reportReqDTO 设备事件 | |
| 43 | - */ | |
| 44 | - @PostMapping(PREFIX + "/report-event") | |
| 45 | - CommonResult<Boolean> reportDeviceEvent(@Valid @RequestBody IotDeviceEventReportReqDTO reportReqDTO); | |
| 46 | - | |
| 47 | - // TODO @芋艿:这个需要 plugins 接入下 | |
| 48 | - /** | |
| 49 | - * 注册设备 | |
| 50 | - * | |
| 51 | - * @param registerReqDTO 注册设备 DTO | |
| 52 | - */ | |
| 53 | - @PostMapping(PREFIX + "/register") | |
| 54 | - CommonResult<Boolean> registerDevice(@Valid @RequestBody IotDeviceRegisterReqDTO registerReqDTO); | |
| 55 | - | |
| 56 | - // TODO @芋艿:这个需要 plugins 接入下 | |
| 57 | - /** | |
| 58 | - * 注册子设备 | |
| 59 | - * | |
| 60 | - * @param registerReqDTO 注册子设备 DTO | |
| 61 | - */ | |
| 62 | - @PostMapping(PREFIX + "/register-sub") | |
| 63 | - CommonResult<Boolean> registerSubDevice(@Valid @RequestBody IotDeviceRegisterSubReqDTO registerReqDTO); | |
| 64 | - | |
| 65 | - // TODO @芋艿:这个需要 plugins 接入下 | |
| 66 | - /** | |
| 67 | - * 注册设备拓扑 | |
| 68 | - * | |
| 69 | - * @param addReqDTO 注册设备拓扑 DTO | |
| 70 | - */ | |
| 71 | - @PostMapping(PREFIX + "/add-topology") | |
| 72 | - CommonResult<Boolean> addDeviceTopology(@Valid @RequestBody IotDeviceTopologyAddReqDTO addReqDTO); | |
| 73 | - | |
| 74 | 21 | // TODO @芋艿:考虑 http 认证 |
| 75 | 22 | /** |
| 76 | 23 | * 认证 Emqx 连接 | ... | ... |
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/dto/control/upstream/IotDeviceStateUpdateReqDTO.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.api.device.dto.control.upstream; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 4 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | |
| 5 | -import jakarta.validation.constraints.NotNull; | |
| 6 | -import lombok.Data; | |
| 7 | - | |
| 8 | -/** | |
| 9 | - * IoT 设备【状态】更新 Request DTO | |
| 10 | - * | |
| 11 | - * @author 芋道源码 | |
| 12 | - */ | |
| 13 | -@Data | |
| 14 | -public class IotDeviceStateUpdateReqDTO extends IotDeviceUpstreamAbstractReqDTO { | |
| 15 | - | |
| 16 | - /** | |
| 17 | - * 设备状态 | |
| 18 | - */ | |
| 19 | - @NotNull(message = "设备状态不能为空") | |
| 20 | - @InEnum(IotDeviceStateEnum.class) // 只使用:在线、离线 | |
| 21 | - private Integer state; | |
| 22 | - | |
| 23 | -} |
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/ErrorCodeConstants.java
| ... | ... | @@ -30,7 +30,7 @@ public interface ErrorCodeConstants { |
| 30 | 30 | ErrorCode DEVICE_GATEWAY_NOT_EXISTS = new ErrorCode(1_050_003_004, "网关设备不存在"); |
| 31 | 31 | ErrorCode DEVICE_NOT_GATEWAY = new ErrorCode(1_050_003_005, "设备不是网关设备"); |
| 32 | 32 | ErrorCode DEVICE_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_050_003_006, "导入设备数据不能为空!"); |
| 33 | - ErrorCode DEVICE_DOWNSTREAM_FAILED = new ErrorCode(1_050_003_007, "执行失败,原因:{}"); | |
| 33 | + ErrorCode DEVICE_DOWNSTREAM_FAILED_SERVER_ID_NULL = new ErrorCode(1_050_003_007, "下行设备消息失败,原因:设备未连接网关"); | |
| 34 | 34 | |
| 35 | 35 | // ========== 产品分类 1-050-004-000 ========== |
| 36 | 36 | ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_050_004_000, "产品分类不存在"); | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/api/device/IoTDeviceUpstreamApiImpl.java
| ... | ... | @@ -21,44 +21,6 @@ public class IoTDeviceUpstreamApiImpl implements IotDeviceUpstreamApi { |
| 21 | 21 | @Resource |
| 22 | 22 | private IotDeviceUpstreamService deviceUpstreamService; |
| 23 | 23 | |
| 24 | - // ========== 设备相关 ========== | |
| 25 | - | |
| 26 | - @Override | |
| 27 | - public CommonResult<Boolean> updateDeviceState(IotDeviceStateUpdateReqDTO updateReqDTO) { | |
| 28 | - deviceUpstreamService.updateDeviceState(updateReqDTO); | |
| 29 | - return success(true); | |
| 30 | - } | |
| 31 | - | |
| 32 | - @Override | |
| 33 | - public CommonResult<Boolean> reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO) { | |
| 34 | - deviceUpstreamService.reportDeviceProperty(reportReqDTO); | |
| 35 | - return success(true); | |
| 36 | - } | |
| 37 | - | |
| 38 | - @Override | |
| 39 | - public CommonResult<Boolean> reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO) { | |
| 40 | - deviceUpstreamService.reportDeviceEvent(reportReqDTO); | |
| 41 | - return success(true); | |
| 42 | - } | |
| 43 | - | |
| 44 | - @Override | |
| 45 | - public CommonResult<Boolean> registerDevice(IotDeviceRegisterReqDTO registerReqDTO) { | |
| 46 | - deviceUpstreamService.registerDevice(registerReqDTO); | |
| 47 | - return success(true); | |
| 48 | - } | |
| 49 | - | |
| 50 | - @Override | |
| 51 | - public CommonResult<Boolean> registerSubDevice(IotDeviceRegisterSubReqDTO registerReqDTO) { | |
| 52 | - deviceUpstreamService.registerSubDevice(registerReqDTO); | |
| 53 | - return success(true); | |
| 54 | - } | |
| 55 | - | |
| 56 | - @Override | |
| 57 | - public CommonResult<Boolean> addDeviceTopology(IotDeviceTopologyAddReqDTO addReqDTO) { | |
| 58 | - deviceUpstreamService.addDeviceTopology(addReqDTO); | |
| 59 | - return success(true); | |
| 60 | - } | |
| 61 | - | |
| 62 | 24 | @Override |
| 63 | 25 | public CommonResult<Boolean> authenticateEmqxConnection(IotDeviceEmqxAuthReqDTO authReqDTO) { |
| 64 | 26 | boolean result = deviceUpstreamService.authenticateEmqxConnection(authReqDTO); | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/vo/device/IotDevicePageReqVO.java
| ... | ... | @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.validation.InEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | |
| 5 | +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum; | |
| 6 | 6 | import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum; |
| 7 | 7 | import io.swagger.v3.oas.annotations.media.Schema; |
| 8 | 8 | import lombok.Data; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/statistics/IotStatisticsController.java
| ... | ... | @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 4 | import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageSummaryRespVO; |
| 5 | 5 | import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsReqVO; |
| 6 | 6 | import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsSummaryRespVO; |
| 7 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | |
| 7 | +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum; | |
| 8 | 8 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 9 | 9 | import cn.iocoder.yudao.module.iot.service.device.data.IotDeviceLogService; |
| 10 | 10 | import cn.iocoder.yudao.module.iot.service.product.IotProductCategoryService; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/device/IotDeviceDO.java
| ... | ... | @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.type.LongSetTypeHandler; |
| 4 | 4 | import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; |
| 5 | 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO; |
| 6 | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 7 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | |
| 7 | +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum; | |
| 8 | 8 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 9 | 9 | import com.baomidou.mybatisplus.annotation.TableField; |
| 10 | 10 | import com.baomidou.mybatisplus.annotation.TableId; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/rule/IotAlertRecordDO.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.dal.dataobject.rule; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 4 | 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 5 | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 6 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 7 | 7 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 8 | 8 | import com.baomidou.mybatisplus.annotation.TableField; |
| 9 | 9 | import com.baomidou.mybatisplus.annotation.TableName; |
| 10 | 10 | import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; |
| 11 | -import lombok.*; | |
| 11 | +import lombok.AllArgsConstructor; | |
| 12 | +import lombok.Builder; | |
| 13 | +import lombok.Data; | |
| 14 | +import lombok.NoArgsConstructor; | |
| 12 | 15 | |
| 13 | 16 | /** |
| 14 | 17 | * IoT 告警记录 DO | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/rule/IotRuleSceneDO.java
| ... | ... | @@ -145,7 +145,7 @@ public class IotRuleSceneDO extends TenantBaseDO { |
| 145 | 145 | public static class TriggerConditionParameter { |
| 146 | 146 | |
| 147 | 147 | // TODO @芋艿: identifier0 存事件和服务的 identifier 属性的情况 identifier0 就为 null 解决前端回显问题 |
| 148 | - // TODO @haohao:可以根据 TriggerCondition.type 判断,是服务、还是事件、还是属性么? | |
| 148 | + // TODO @puhui999:可以根据 TriggerCondition.type 判断,是服务、还是事件、还是属性么? | |
| 149 | 149 | /** |
| 150 | 150 | * 标识符(事件、服务) |
| 151 | 151 | * | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/RedisKeyConstants.java
| ... | ... | @@ -19,11 +19,10 @@ public interface RedisKeyConstants { |
| 19 | 19 | */ |
| 20 | 20 | String DEVICE_PROPERTY = "iot:device_property:%s"; |
| 21 | 21 | |
| 22 | - // TODO @芋艿:弱化 deviceKey;使用 product_key + device_name 替代 | |
| 23 | 22 | /** |
| 24 | 23 | * 设备的最后上报时间,采用 ZSET 结构 |
| 25 | 24 | * |
| 26 | - * KEY 格式:{deviceKey} | |
| 25 | + * KEY 格式:{productKey},${deviceName} | |
| 27 | 26 | * SCORE:上报时间 |
| 28 | 27 | */ |
| 29 | 28 | String DEVICE_REPORT_TIMES = "iot:device_report_times"; |
| ... | ... | @@ -44,4 +43,13 @@ public interface RedisKeyConstants { |
| 44 | 43 | */ |
| 45 | 44 | String THING_MODEL_LIST = "iot:thing_model_list"; |
| 46 | 45 | |
| 46 | + /** | |
| 47 | + * 设备关联的网关 serverId 缓存,采用 HASH 结构 | |
| 48 | + * | |
| 49 | + * KEY 格式:device_server_id | |
| 50 | + * HASH KEY:{productKey},{deviceName} | |
| 51 | + * VALUE 数据类型:String serverId | |
| 52 | + */ | |
| 53 | + String DEVICE_SERVER_ID = "iot:device_server_id"; | |
| 54 | + | |
| 47 | 55 | } | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/device/DeviceReportTimeRedisDAO.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.dal.redis.device; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.date.LocalDateTimeUtil; |
| 4 | +import cn.hutool.core.util.StrUtil; | |
| 5 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 4 | 6 | import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants; |
| 5 | 7 | import jakarta.annotation.Resource; |
| 6 | 8 | import org.springframework.data.redis.core.StringRedisTemplate; |
| ... | ... | @@ -20,14 +22,17 @@ public class DeviceReportTimeRedisDAO { |
| 20 | 22 | @Resource |
| 21 | 23 | private StringRedisTemplate stringRedisTemplate; |
| 22 | 24 | |
| 23 | - public void update(String deviceKey, LocalDateTime reportTime) { | |
| 24 | - stringRedisTemplate.opsForZSet().add(RedisKeyConstants.DEVICE_REPORT_TIMES, deviceKey, | |
| 25 | + public void update(String productKey, String deviceName, LocalDateTime reportTime) { | |
| 26 | + String value = productKey + StrUtil.COMMA + deviceName; // 使用 , 分隔 | |
| 27 | + stringRedisTemplate.opsForZSet().add(RedisKeyConstants.DEVICE_REPORT_TIMES, value, | |
| 25 | 28 | LocalDateTimeUtil.toEpochMilli(reportTime)); |
| 26 | 29 | } |
| 27 | 30 | |
| 28 | - public Set<String> range(LocalDateTime maxReportTime) { | |
| 29 | - return stringRedisTemplate.opsForZSet().rangeByScore(RedisKeyConstants.DEVICE_REPORT_TIMES, 0, | |
| 31 | + public Set<String[]> range(LocalDateTime maxReportTime) { | |
| 32 | + Set<String> values = stringRedisTemplate.opsForZSet().rangeByScore(RedisKeyConstants.DEVICE_REPORT_TIMES, 0, | |
| 30 | 33 | LocalDateTimeUtil.toEpochMilli(maxReportTime)); |
| 34 | + return CollectionUtils.convertSet(values, | |
| 35 | + value -> value.split(StrUtil.COMMA)); // 使用, 分隔 | |
| 31 | 36 | } |
| 32 | 37 | |
| 33 | 38 | } | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/device/DeviceServerIdRedisDAO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.dal.redis.device; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.StrUtil; | |
| 4 | +import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants; | |
| 5 | +import jakarta.annotation.Resource; | |
| 6 | +import org.springframework.data.redis.core.StringRedisTemplate; | |
| 7 | +import org.springframework.stereotype.Repository; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * 设备关联的网关 serverId 的 Redis DAO | |
| 11 | + * | |
| 12 | + * @author 芋道源码 | |
| 13 | + */ | |
| 14 | +@Repository | |
| 15 | +public class DeviceServerIdRedisDAO { | |
| 16 | + | |
| 17 | + @Resource | |
| 18 | + private StringRedisTemplate stringRedisTemplate; | |
| 19 | + | |
| 20 | + /** | |
| 21 | + * 更新设备关联的网关 serverId | |
| 22 | + * | |
| 23 | + * @param productKey 产品标识 | |
| 24 | + * @param deviceName 设备名称 | |
| 25 | + * @param serverId 网关 serverId | |
| 26 | + */ | |
| 27 | + public void update(String productKey, String deviceName, String serverId) { | |
| 28 | + String hashKey = buildHashKey(productKey, deviceName); | |
| 29 | + stringRedisTemplate.opsForHash().put(RedisKeyConstants.DEVICE_SERVER_ID, hashKey, serverId); | |
| 30 | + } | |
| 31 | + | |
| 32 | + /** | |
| 33 | + * 获得设备关联的网关 serverId | |
| 34 | + * | |
| 35 | + * @param productKey 产品标识 | |
| 36 | + * @param deviceName 设备名称 | |
| 37 | + * @return 网关 serverId | |
| 38 | + */ | |
| 39 | + public String get(String productKey, String deviceName) { | |
| 40 | + String hashKey = buildHashKey(productKey, deviceName); | |
| 41 | + Object value = stringRedisTemplate.opsForHash().get(RedisKeyConstants.DEVICE_SERVER_ID, hashKey); | |
| 42 | + return value != null ? (String) value : null; | |
| 43 | + } | |
| 44 | + | |
| 45 | + /** | |
| 46 | + * 删除设备关联的网关 serverId | |
| 47 | + * | |
| 48 | + * @param productKey 产品标识 | |
| 49 | + * @param deviceName 设备名称 | |
| 50 | + */ | |
| 51 | + public void delete(String productKey, String deviceName) { | |
| 52 | + String hashKey = buildHashKey(productKey, deviceName); | |
| 53 | + stringRedisTemplate.opsForHash().delete(RedisKeyConstants.DEVICE_SERVER_ID, hashKey); | |
| 54 | + } | |
| 55 | + | |
| 56 | + /** | |
| 57 | + * 构建 HASH KEY | |
| 58 | + * | |
| 59 | + * @param productKey 产品标识 | |
| 60 | + * @param deviceName 设备名称 | |
| 61 | + * @return HASH KEY | |
| 62 | + */ | |
| 63 | + private String buildHashKey(String productKey, String deviceName) { | |
| 64 | + return productKey + StrUtil.COMMA + deviceName; | |
| 65 | + } | |
| 66 | + | |
| 67 | +} | |
| 0 | 68 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/job/device/IotDeviceOfflineCheckJob.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.job.device; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | -import cn.hutool.core.util.IdUtil; | |
| 4 | +import cn.hutool.core.util.StrUtil; | |
| 5 | 5 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 6 | 6 | import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; |
| 7 | 7 | import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; |
| 8 | -import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceStateUpdateReqDTO; | |
| 8 | +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum; | |
| 9 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 10 | +import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; | |
| 9 | 11 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 10 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | |
| 11 | 12 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 12 | 13 | import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; |
| 13 | -import cn.iocoder.yudao.module.iot.service.device.control.IotDeviceUpstreamService; | |
| 14 | 14 | import jakarta.annotation.Resource; |
| 15 | 15 | import org.springframework.stereotype.Component; |
| 16 | 16 | |
| ... | ... | @@ -20,10 +20,12 @@ import java.util.Collections; |
| 20 | 20 | import java.util.List; |
| 21 | 21 | import java.util.Set; |
| 22 | 22 | |
| 23 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 24 | + | |
| 23 | 25 | /** |
| 24 | 26 | * IoT 设备离线检查 Job |
| 25 | 27 | * |
| 26 | - * 检测逻辑:设备最后一条 {@link cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage} 消息超过一定时间,则认为设备离线 | |
| 28 | + * 检测逻辑:设备最后一条 {@link IotDeviceMessage} 消息超过一定时间,则认为设备离线 | |
| 27 | 29 | * |
| 28 | 30 | * @author 芋道源码 |
| 29 | 31 | */ |
| ... | ... | @@ -41,8 +43,9 @@ public class IotDeviceOfflineCheckJob implements JobHandler { |
| 41 | 43 | private IotDeviceService deviceService; |
| 42 | 44 | @Resource |
| 43 | 45 | private IotDevicePropertyService devicePropertyService; |
| 46 | + | |
| 44 | 47 | @Resource |
| 45 | - private IotDeviceUpstreamService deviceUpstreamService; | |
| 48 | + private IotDeviceMessageProducer deviceMessageProducer; | |
| 46 | 49 | |
| 47 | 50 | @Override |
| 48 | 51 | @TenantJob |
| ... | ... | @@ -52,22 +55,22 @@ public class IotDeviceOfflineCheckJob implements JobHandler { |
| 52 | 55 | if (CollUtil.isEmpty(devices)) { |
| 53 | 56 | return JsonUtils.toJsonString(Collections.emptyList()); |
| 54 | 57 | } |
| 55 | - // 1.2 获取超时的 deviceKey 集合 | |
| 56 | - Set<String> timeoutDeviceKeys = devicePropertyService.getDeviceKeysByReportTime( | |
| 58 | + // 1.2 获取超时的设备集合 | |
| 59 | + Set<String[]> timeoutDevices = devicePropertyService.getProductKeyDeviceNameListByReportTime( | |
| 57 | 60 | LocalDateTime.now().minus(OFFLINE_TIMEOUT)); |
| 61 | + Set<String> timeoutDevices2 = convertSet(timeoutDevices, item -> item[0] + StrUtil.COMMA + item[1]); | |
| 58 | 62 | |
| 59 | 63 | // 2. 下线设备 |
| 60 | - List<String> offlineDeviceKeys = CollUtil.newArrayList(); | |
| 64 | + List<String[]> offlineDeviceKeys = CollUtil.newArrayList(); | |
| 61 | 65 | for (IotDeviceDO device : devices) { |
| 62 | - if (!timeoutDeviceKeys.contains(device.getDeviceKey())) { | |
| 66 | + String timeoutDeviceKey = device.getProductKey() + StrUtil.COMMA + device.getDeviceName(); | |
| 67 | + if (!timeoutDevices2.contains(timeoutDeviceKey)) { | |
| 63 | 68 | continue; |
| 64 | 69 | } |
| 65 | - offlineDeviceKeys.add(device.getDeviceKey()); | |
| 70 | + offlineDeviceKeys.add(new String[]{device.getProductKey(), device.getDeviceName()}); | |
| 66 | 71 | // 为什么不直接更新状态呢?因为通过 IotDeviceMessage 可以经过一系列的处理,例如说记录日志等等 |
| 67 | - deviceUpstreamService.updateDeviceState(((IotDeviceStateUpdateReqDTO) | |
| 68 | - new IotDeviceStateUpdateReqDTO().setRequestId(IdUtil.fastSimpleUUID()).setReportTime(LocalDateTime.now()) | |
| 69 | - .setProductKey(device.getProductKey()).setDeviceName(device.getDeviceName())) | |
| 70 | - .setState((IotDeviceStateEnum.OFFLINE.getState()))); | |
| 72 | + deviceMessageProducer.sendDeviceMessage(IotDeviceMessage.of(device.getProductKey(), device.getDeviceName()) | |
| 73 | + .ofStateOffline()); | |
| 71 | 74 | } |
| 72 | 75 | return JsonUtils.toJsonString(offlineDeviceKeys); |
| 73 | 76 | } | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/device/IotDeviceLogMessageSubscriber.java
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/device/IotDeviceOnlineMessageConsumer.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.mq.consumer.device; | |
| 2 | - | |
| 3 | -import cn.hutool.core.util.IdUtil; | |
| 4 | -import cn.hutool.core.util.StrUtil; | |
| 5 | -import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceStateUpdateReqDTO; | |
| 6 | -import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | |
| 7 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; | |
| 8 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; | |
| 9 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | |
| 10 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 11 | -import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | |
| 12 | -import cn.iocoder.yudao.module.iot.service.device.control.IotDeviceUpstreamService; | |
| 13 | -import jakarta.annotation.Resource; | |
| 14 | -import lombok.extern.slf4j.Slf4j; | |
| 15 | -import org.springframework.context.event.EventListener; | |
| 16 | -import org.springframework.scheduling.annotation.Async; | |
| 17 | -import org.springframework.stereotype.Component; | |
| 18 | - | |
| 19 | -import java.time.LocalDateTime; | |
| 20 | -import java.util.Objects; | |
| 21 | - | |
| 22 | -/** | |
| 23 | - * 针对 {@link IotDeviceMessage} 的消费者,将离线的设备,自动标记为上线 | |
| 24 | - * | |
| 25 | - * 注意:只有设备上行消息,才会触发该逻辑 | |
| 26 | - * | |
| 27 | - * @author 芋道源码 | |
| 28 | - */ | |
| 29 | -@Component | |
| 30 | -@Slf4j | |
| 31 | -public class IotDeviceOnlineMessageConsumer { | |
| 32 | - | |
| 33 | - @Resource | |
| 34 | - private IotDeviceService deviceService; | |
| 35 | - | |
| 36 | - @Resource | |
| 37 | - private IotDeviceUpstreamService deviceUpstreamService; | |
| 38 | - | |
| 39 | - @EventListener | |
| 40 | - @Async | |
| 41 | - public void onMessage(IotDeviceMessage message) { | |
| 42 | - // 1.1 只处理上行消息。因为,只有设备上行的消息,才会触发设备上线的逻辑 | |
| 43 | - if (!isUpstreamMessage(message)) { | |
| 44 | - return; | |
| 45 | - } | |
| 46 | - // 1.2 如果设备已在线,则不做处理 | |
| 47 | - log.info("[onMessage][消息内容({})]", message); | |
| 48 | - IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceNameFromCache( | |
| 49 | - message.getProductKey(), message.getDeviceName()); | |
| 50 | - if (device == null) { | |
| 51 | - log.error("[onMessage][消息({}) 对应的设备部存在]", message); | |
| 52 | - return; | |
| 53 | - } | |
| 54 | - if (IotDeviceStateEnum.isOnline(device.getState())) { | |
| 55 | - return; | |
| 56 | - } | |
| 57 | - | |
| 58 | - // 2. 标记设备为在线 | |
| 59 | - // 为什么不直接更新状态呢?因为通过 IotDeviceMessage 可以经过一系列的处理,例如说记录日志等等 | |
| 60 | - deviceUpstreamService.updateDeviceState(((IotDeviceStateUpdateReqDTO) | |
| 61 | - new IotDeviceStateUpdateReqDTO().setRequestId(IdUtil.fastSimpleUUID()).setReportTime(LocalDateTime.now()) | |
| 62 | - .setProductKey(device.getProductKey()).setDeviceName(device.getDeviceName())) | |
| 63 | - .setState((IotDeviceStateEnum.ONLINE.getState()))); | |
| 64 | - } | |
| 65 | - | |
| 66 | - private boolean isUpstreamMessage(IotDeviceMessage message) { | |
| 67 | - // 设备属性 | |
| 68 | - if (Objects.equals(message.getType(), IotDeviceMessageTypeEnum.PROPERTY.getType()) | |
| 69 | - && Objects.equals(message.getIdentifier(), IotDeviceMessageIdentifierEnum.PROPERTY_REPORT.getIdentifier())) { | |
| 70 | - return true; | |
| 71 | - } | |
| 72 | - // 设备事件 | |
| 73 | - if (Objects.equals(message.getType(), IotDeviceMessageTypeEnum.EVENT.getType())) { | |
| 74 | - return true; | |
| 75 | - } | |
| 76 | - // 设备服务 | |
| 77 | - // noinspection RedundantIfStatement | |
| 78 | - if (Objects.equals(message.getType(), IotDeviceMessageTypeEnum.SERVICE.getType()) | |
| 79 | - && !StrUtil.endWith(message.getIdentifier(), IotDeviceMessageIdentifierEnum.SERVICE_REPLY_SUFFIX.getIdentifier())) { | |
| 80 | - return true; | |
| 81 | - } | |
| 82 | - return false; | |
| 83 | - } | |
| 84 | - | |
| 85 | -} | |
| 86 | 0 | \ No newline at end of file |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/device/IotDevicePropertyMessageConsumer.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.mq.consumer.device; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.util.ObjectUtil; |
| 4 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 4 | 5 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; |
| 5 | 6 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; |
| 6 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 7 | 7 | import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; |
| 8 | 8 | import lombok.extern.slf4j.Slf4j; |
| 9 | 9 | import org.springframework.context.event.EventListener; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/device/IotDeviceStateMessageSubscriber.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.iot.mq.consumer.device; | |
| 2 | + | |
| 3 | +import cn.hutool.core.util.ObjectUtil; | |
| 4 | +import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; | |
| 5 | +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageIdentifierEnum; | |
| 6 | +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageTypeEnum; | |
| 7 | +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum; | |
| 8 | +import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus; | |
| 9 | +import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageSubscriber; | |
| 10 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 11 | +import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; | |
| 12 | +import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; | |
| 13 | +import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | |
| 14 | +import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | |
| 15 | +import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; | |
| 16 | +import jakarta.annotation.PostConstruct; | |
| 17 | +import jakarta.annotation.Resource; | |
| 18 | +import lombok.extern.slf4j.Slf4j; | |
| 19 | +import org.springframework.stereotype.Component; | |
| 20 | + | |
| 21 | +import java.time.LocalDateTime; | |
| 22 | +import java.util.Objects; | |
| 23 | + | |
| 24 | +/** | |
| 25 | + * 针对 {@link IotDeviceMessage} 的消费者:记录设备状态 | |
| 26 | + * | |
| 27 | + * 特殊:如果是离线的设备,将自动上线 | |
| 28 | + * | |
| 29 | + * @author 芋道源码 | |
| 30 | + */ | |
| 31 | +@Component | |
| 32 | +@Slf4j | |
| 33 | +public class IotDeviceStateMessageSubscriber implements IotMessageSubscriber<IotDeviceMessage> { | |
| 34 | + | |
| 35 | + @Resource | |
| 36 | + private IotDeviceService deviceService; | |
| 37 | + @Resource | |
| 38 | + private IotDevicePropertyService devicePropertyService; | |
| 39 | + | |
| 40 | + @Resource | |
| 41 | + private IotMessageBus messageBus; | |
| 42 | + @Resource | |
| 43 | + private IotDeviceMessageProducer deviceMessageProducer; | |
| 44 | + | |
| 45 | + @PostConstruct | |
| 46 | + public void init() { | |
| 47 | + messageBus.register(this); | |
| 48 | + } | |
| 49 | + | |
| 50 | + @Override | |
| 51 | + public String getTopic() { | |
| 52 | + return IotDeviceMessage.MESSAGE_BUS_DEVICE_MESSAGE_TOPIC; | |
| 53 | + } | |
| 54 | + | |
| 55 | + @Override | |
| 56 | + public String getGroup() { | |
| 57 | + return "iot_device_state_consumer"; | |
| 58 | + } | |
| 59 | + | |
| 60 | + @Override | |
| 61 | + public void onMessage(IotDeviceMessage message) { | |
| 62 | + // 1.1 只处理上行消息,或者是 STATE 相关的消息 | |
| 63 | + if (!IotDeviceMessageUtils.isUpstreamMessage(message) | |
| 64 | + && ObjectUtil.notEqual(message.getType(), IotDeviceMessageTypeEnum.STATE.getType())) { | |
| 65 | + return; | |
| 66 | + } | |
| 67 | + // 1.2 校验设备是否存在 | |
| 68 | + IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceNameFromCache( | |
| 69 | + message.getProductKey(), message.getDeviceName()); | |
| 70 | + if (device == null) { | |
| 71 | + log.error("[onMessage][消息({}) 对应的设备部存在]", message); | |
| 72 | + return; | |
| 73 | + } | |
| 74 | + | |
| 75 | + // 2. 处理消息 | |
| 76 | + TenantUtils.execute(device.getTenantId(), () -> onMessage(message, device)); | |
| 77 | + } | |
| 78 | + | |
| 79 | + private void onMessage(IotDeviceMessage message, IotDeviceDO device) { | |
| 80 | + // 更新设备的最后时间 | |
| 81 | + devicePropertyService.updateDeviceReportTime(device.getProductKey(), device.getDeviceName(), LocalDateTime.now()); | |
| 82 | + | |
| 83 | + // 情况一:STATE 相关的消息 | |
| 84 | + if (Objects.equals(message.getType(), IotDeviceMessageTypeEnum.STATE.getType())) { | |
| 85 | + if (Objects.equals(message.getIdentifier(), IotDeviceMessageIdentifierEnum.STATE_ONLINE.getIdentifier())) { | |
| 86 | + deviceService.updateDeviceState(device.getId(), IotDeviceStateEnum.ONLINE.getState()); | |
| 87 | + devicePropertyService.updateDeviceServerId(device.getProductKey(), device.getDeviceName(), message.getServerId()); | |
| 88 | + } else { | |
| 89 | + deviceService.updateDeviceState(device.getId(), IotDeviceStateEnum.OFFLINE.getState()); | |
| 90 | + devicePropertyService.deleteDeviceServerId(device.getProductKey(), device.getDeviceName()); | |
| 91 | + } | |
| 92 | + // TODO 芋艿:子设备的关联 | |
| 93 | + return; | |
| 94 | + } | |
| 95 | + | |
| 96 | + // 情况二:非 STATE 相关的消息 | |
| 97 | + devicePropertyService.updateDeviceServerId(device.getProductKey(), device.getDeviceName(), message.getServerId()); | |
| 98 | + // 特殊:设备非在线时,主动标记设备为在线 | |
| 99 | + // 为什么不直接更新状态呢?因为通过 IotDeviceMessage 可以经过一系列的处理,例如说记录日志等等 | |
| 100 | + if (ObjectUtil.notEqual(device.getState(), IotDeviceStateEnum.ONLINE.getState())) { | |
| 101 | + deviceMessageProducer.sendDeviceMessage(IotDeviceMessage.of(message.getProductKey(), message.getDeviceName()) | |
| 102 | + .ofStateOnline()); | |
| 103 | + } | |
| 104 | + } | |
| 105 | + | |
| 106 | +} | |
| 0 | 107 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/consumer/rule/IotRuleSceneMessageHandler.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.mq.consumer.rule; |
| 2 | 2 | |
| 3 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 3 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 4 | 4 | import cn.iocoder.yudao.module.iot.service.rule.IotRuleSceneService; |
| 5 | 5 | import jakarta.annotation.Resource; |
| 6 | 6 | import lombok.extern.slf4j.Slf4j; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/message/IotDeviceMessage.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.mq.message; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; | |
| 4 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; | |
| 5 | -import lombok.AllArgsConstructor; | |
| 6 | -import lombok.Builder; | |
| 7 | -import lombok.Data; | |
| 8 | -import lombok.NoArgsConstructor; | |
| 9 | - | |
| 10 | -import java.time.LocalDateTime; | |
| 11 | - | |
| 12 | -// TODO @芋艿:参考阿里云的物模型,优化 IoT 上下行消息的设计,尽量保持一致(渐进式,不要一口气)! | |
| 13 | -/** | |
| 14 | - * IoT 设备消息 | |
| 15 | - */ | |
| 16 | -@Data | |
| 17 | -@NoArgsConstructor | |
| 18 | -@AllArgsConstructor | |
| 19 | -@Builder | |
| 20 | -@Deprecated | |
| 21 | -public class IotDeviceMessage { | |
| 22 | - | |
| 23 | - /** | |
| 24 | - * 请求编号 | |
| 25 | - */ | |
| 26 | - private String requestId; | |
| 27 | - | |
| 28 | - /** | |
| 29 | - * 设备信息 | |
| 30 | - */ | |
| 31 | - private String productKey; | |
| 32 | - /** | |
| 33 | - * 设备名称 | |
| 34 | - */ | |
| 35 | - private String deviceName; | |
| 36 | - /** | |
| 37 | - * 设备标识 | |
| 38 | - */ | |
| 39 | - private String deviceKey; | |
| 40 | - | |
| 41 | - /** | |
| 42 | - * 消息类型 | |
| 43 | - * | |
| 44 | - * 枚举 {@link IotDeviceMessageTypeEnum} | |
| 45 | - */ | |
| 46 | - private String type; | |
| 47 | - /** | |
| 48 | - * 标识符 | |
| 49 | - * | |
| 50 | - * 枚举 {@link IotDeviceMessageIdentifierEnum} | |
| 51 | - */ | |
| 52 | - private String identifier; | |
| 53 | - | |
| 54 | - /** | |
| 55 | - * 请求参数 | |
| 56 | - * | |
| 57 | - * 例如说:属性上报的 properties、事件上报的 params | |
| 58 | - */ | |
| 59 | - private Object data; | |
| 60 | - /** | |
| 61 | - * 响应码 | |
| 62 | - * | |
| 63 | - * 目前只有 server 下行消息给 device 设备时,才会有响应码 | |
| 64 | - */ | |
| 65 | - private Integer code; | |
| 66 | - | |
| 67 | - /** | |
| 68 | - * 上报时间 | |
| 69 | - */ | |
| 70 | - private LocalDateTime reportTime; | |
| 71 | - | |
| 72 | - /** | |
| 73 | - * 租户编号 | |
| 74 | - */ | |
| 75 | - private Long tenantId; | |
| 76 | - | |
| 77 | -} |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/producer/device/IotDeviceProducer.java deleted
| 1 | -package cn.iocoder.yudao.module.iot.mq.producer.device; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 4 | -import jakarta.annotation.Resource; | |
| 5 | -import lombok.extern.slf4j.Slf4j; | |
| 6 | -import org.springframework.context.ApplicationContext; | |
| 7 | -import org.springframework.stereotype.Component; | |
| 8 | - | |
| 9 | -/** | |
| 10 | - * IoT 设备相关消息的 Producer | |
| 11 | - * | |
| 12 | - * @author alwayssuper | |
| 13 | - * @since 2024/12/17 16:35 | |
| 14 | - */ | |
| 15 | -@Slf4j | |
| 16 | -@Component | |
| 17 | -public class IotDeviceProducer { | |
| 18 | - | |
| 19 | - @Resource | |
| 20 | - private ApplicationContext applicationContext; | |
| 21 | - | |
| 22 | - /** | |
| 23 | - * 发送 {@link IotDeviceMessage} 消息 | |
| 24 | - * | |
| 25 | - * @param thingModelMessage 物模型消息 | |
| 26 | - */ | |
| 27 | - public void sendDeviceMessage(IotDeviceMessage thingModelMessage) { | |
| 28 | - applicationContext.publishEvent(thingModelMessage); | |
| 29 | - } | |
| 30 | - | |
| 31 | -} |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/mq/producer/package-info.java
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceService.java
| ... | ... | @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.iot.service.device; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*; |
| 5 | 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 6 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | |
| 6 | +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum; | |
| 7 | 7 | import jakarta.validation.Valid; |
| 8 | 8 | import jakarta.validation.constraints.NotEmpty; |
| 9 | 9 | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/IotDeviceServiceImpl.java
| ... | ... | @@ -17,7 +17,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceGroupDO; |
| 17 | 17 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 18 | 18 | import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper; |
| 19 | 19 | import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants; |
| 20 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | |
| 20 | +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum; | |
| 21 | 21 | import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum; |
| 22 | 22 | import cn.iocoder.yudao.module.iot.service.product.IotProductService; |
| 23 | 23 | import cn.iocoder.yudao.module.iot.util.MqttSignUtils; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceDownstreamService.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.device.control; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO; |
| 4 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 4 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 5 | 5 | import jakarta.validation.Valid; |
| 6 | 6 | |
| 7 | 7 | /** |
| 8 | 8 | * IoT 设备下行 Service 接口 |
| 9 | 9 | * |
| 10 | - * 目的:服务端 -> 插件 -> 设备 | |
| 10 | + * 目的:服务端 -> 网关 -> 设备 | |
| 11 | 11 | * |
| 12 | 12 | * @author 芋道源码 |
| 13 | 13 | */ |
| ... | ... | @@ -17,7 +17,7 @@ public interface IotDeviceDownstreamService { |
| 17 | 17 | * 设备下行,可用于设备模拟 |
| 18 | 18 | * |
| 19 | 19 | * @param downstreamReqVO 设备下行请求 VO |
| 20 | - * @return 下发消息 | |
| 20 | + * @return 下行消息 | |
| 21 | 21 | */ |
| 22 | 22 | IotDeviceMessage downstreamDevice(@Valid IotDeviceDownstreamReqVO downstreamReqVO); |
| 23 | 23 | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceDownstreamServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.device.control; |
| 2 | 2 | |
| 3 | -import cn.hutool.core.lang.Assert; | |
| 3 | +import cn.hutool.core.util.StrUtil; | |
| 4 | 4 | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| 5 | -import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 6 | -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | |
| 7 | -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceConfigSetReqDTO; | |
| 8 | -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceOtaUpgradeReqDTO; | |
| 9 | -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDevicePropertyGetReqDTO; | |
| 10 | -import cn.iocoder.yudao.module.iot.api.device.dto.control.downstream.IotDeviceServiceInvokeReqDTO; | |
| 11 | 5 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO; |
| 6 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 12 | 7 | import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; |
| 13 | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 14 | 9 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; |
| 15 | 10 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; |
| 16 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 17 | -import cn.iocoder.yudao.module.iot.mq.producer.device.IotDeviceProducer; | |
| 18 | 11 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 12 | +import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; | |
| 19 | 13 | import jakarta.annotation.Resource; |
| 20 | 14 | import lombok.extern.slf4j.Slf4j; |
| 21 | 15 | import org.springframework.stereotype.Service; |
| 22 | 16 | import org.springframework.validation.annotation.Validated; |
| 23 | 17 | |
| 24 | -import java.time.LocalDateTime; | |
| 25 | -import java.util.List; | |
| 26 | 18 | import java.util.Map; |
| 27 | 19 | import java.util.Objects; |
| 28 | 20 | |
| 29 | 21 | import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; |
| 30 | 22 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 31 | -import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_DOWNSTREAM_FAILED; | |
| 23 | +import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_DOWNSTREAM_FAILED_SERVER_ID_NULL; | |
| 32 | 24 | |
| 33 | 25 | /** |
| 34 | 26 | * IoT 设备下行 Service 实现类 |
| ... | ... | @@ -42,255 +34,234 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic |
| 42 | 34 | |
| 43 | 35 | @Resource |
| 44 | 36 | private IotDeviceService deviceService; |
| 45 | - | |
| 46 | 37 | @Resource |
| 47 | - private IotDeviceProducer deviceProducer; | |
| 38 | + private IotDevicePropertyService devicePropertyService; | |
| 39 | + | |
| 48 | 40 | @Resource |
| 49 | 41 | private IotDeviceMessageProducer deviceMessageProducer; |
| 50 | 42 | |
| 51 | 43 | @Override |
| 52 | 44 | public IotDeviceMessage downstreamDevice(IotDeviceDownstreamReqVO downstreamReqVO) { |
| 53 | - // 校验设备是否存在 | |
| 45 | + // 1. 校验设备是否存在 | |
| 54 | 46 | IotDeviceDO device = deviceService.validateDeviceExists(downstreamReqVO.getId()); |
| 55 | - // TODO @芋艿:离线设备,不允许推送 | |
| 56 | 47 | // TODO 芋艿:父设备的处理 |
| 57 | 48 | IotDeviceDO parentDevice = null; |
| 58 | 49 | |
| 50 | + // 2. 构建消息 | |
| 51 | + IotDeviceMessage message = buildDownstreamDeviceMessage(downstreamReqVO, device, parentDevice); | |
| 52 | + | |
| 53 | + // 3.1 发送给网关 | |
| 54 | + String serverId = devicePropertyService.getDeviceServerId(message.getProductKey(), message.getDeviceName()); | |
| 55 | + if (StrUtil.isEmpty(serverId)) { | |
| 56 | + throw exception(DEVICE_DOWNSTREAM_FAILED_SERVER_ID_NULL); | |
| 57 | + } | |
| 58 | + deviceMessageProducer.sendGatewayDeviceMessage(serverId, message); | |
| 59 | + | |
| 60 | + // 3.2 发送给服务器(用于设备日志等的记录) | |
| 61 | + deviceMessageProducer.sendDeviceMessage(message); | |
| 62 | + return message; | |
| 63 | + } | |
| 64 | + | |
| 65 | + @SuppressWarnings("unchecked") | |
| 66 | + private IotDeviceMessage buildDownstreamDeviceMessage(IotDeviceDownstreamReqVO downstreamReqVO, | |
| 67 | + IotDeviceDO device, IotDeviceDO parentDevice) { | |
| 68 | + IotDeviceMessage message = IotDeviceMessage.of(getProductKey(device, parentDevice), | |
| 69 | + getDeviceName(device, parentDevice)); | |
| 59 | 70 | // 服务调用 |
| 60 | 71 | if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.SERVICE.getType())) { |
| 61 | - return invokeDeviceService(downstreamReqVO, device, parentDevice); | |
| 72 | + // TODO @芋艿:待实现 | |
| 73 | +// return invokeDeviceService(downstreamReqVO, device, parentDevice); | |
| 62 | 74 | } |
| 63 | 75 | // 属性相关 |
| 64 | 76 | if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.PROPERTY.getType())) { |
| 65 | 77 | // 属性设置 |
| 66 | 78 | if (Objects.equals(downstreamReqVO.getIdentifier(), |
| 67 | 79 | IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier())) { |
| 68 | - return setDeviceProperty(downstreamReqVO, device, parentDevice); | |
| 80 | + if (!(downstreamReqVO.getData() instanceof Map<?, ?>)) { | |
| 81 | + throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型"); | |
| 82 | + } | |
| 83 | + return message.ofPropertySet((Map<String, Object>) downstreamReqVO.getData()); | |
| 69 | 84 | } |
| 70 | - // 属性设置 | |
| 85 | + // 属性获取 | |
| 71 | 86 | if (Objects.equals(downstreamReqVO.getIdentifier(), |
| 72 | 87 | IotDeviceMessageIdentifierEnum.PROPERTY_GET.getIdentifier())) { |
| 73 | - return getDeviceProperty(downstreamReqVO, device, parentDevice); | |
| 88 | + // TODO @芋艿:待实现 | |
| 89 | +// return getDeviceProperty(downstreamReqVO, device, parentDevice); | |
| 74 | 90 | } |
| 75 | 91 | } |
| 76 | 92 | // 配置下发 |
| 77 | 93 | if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.CONFIG.getType()) |
| 78 | 94 | && Objects.equals(downstreamReqVO.getIdentifier(), |
| 79 | - IotDeviceMessageIdentifierEnum.CONFIG_SET.getIdentifier())) { | |
| 80 | - return setDeviceConfig(downstreamReqVO, device, parentDevice); | |
| 95 | + IotDeviceMessageIdentifierEnum.CONFIG_SET.getIdentifier())) { | |
| 96 | + // TODO @芋艿:待实现 | |
| 97 | +// return setDeviceConfig(downstreamReqVO, device, parentDevice); | |
| 81 | 98 | } |
| 82 | 99 | // OTA 升级 |
| 83 | 100 | if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.OTA.getType())) { |
| 84 | - return otaUpgrade(downstreamReqVO, device, parentDevice); | |
| 101 | + // TODO @芋艿:待实现 | |
| 102 | +// return otaUpgrade(downstreamReqVO, device, parentDevice); | |
| 85 | 103 | } |
| 86 | 104 | // TODO @芋艿:取消设备的网关的时,要不要下发 REGISTER_UNREGISTER_SUB ? |
| 87 | 105 | throw new IllegalArgumentException("不支持的下行消息类型:" + downstreamReqVO); |
| 88 | 106 | } |
| 89 | 107 | |
| 90 | - /** | |
| 91 | - * 调用设备服务 | |
| 92 | - * | |
| 93 | - * @param downstreamReqVO 下行请求 | |
| 94 | - * @param device 设备 | |
| 95 | - * @param parentDevice 父设备 | |
| 96 | - * @return 下发消息 | |
| 97 | - */ | |
| 98 | - @SuppressWarnings("unchecked") | |
| 99 | - private IotDeviceMessage invokeDeviceService(IotDeviceDownstreamReqVO downstreamReqVO, | |
| 100 | - IotDeviceDO device, IotDeviceDO parentDevice) { | |
| 101 | - // 1. 参数校验 | |
| 102 | - if (!(downstreamReqVO.getData() instanceof Map<?, ?>)) { | |
| 103 | - throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型"); | |
| 104 | - } | |
| 105 | - // TODO @super:【可优化】过滤掉不合法的服务 | |
| 108 | +// /** | |
| 109 | +// * 调用设备服务 | |
| 110 | +// * | |
| 111 | +// * @param downstreamReqVO 下行请求 | |
| 112 | +// * @param device 设备 | |
| 113 | +// * @param parentDevice 父设备 | |
| 114 | +// * @return 下发消息 | |
| 115 | +// */ | |
| 116 | +// @SuppressWarnings("unchecked") | |
| 117 | +// private IotDeviceMessage invokeDeviceService(IotDeviceDownstreamReqVO downstreamReqVO, | |
| 118 | +// IotDeviceDO device, IotDeviceDO parentDevice) { | |
| 119 | +// // 1. 参数校验 | |
| 120 | +// if (!(downstreamReqVO.getData() instanceof Map<?, ?>)) { | |
| 121 | +// throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型"); | |
| 122 | +// } | |
| 123 | +// // TODO @super:【可优化】过滤掉不合法的服务 | |
| 124 | +// | |
| 125 | +// // 2. 发送请求 | |
| 126 | +// String url = String.format("sys/%s/%s/thing/service/%s", | |
| 127 | +// getProductKey(device, parentDevice), getDeviceName(device, parentDevice), | |
| 128 | +// downstreamReqVO.getIdentifier()); | |
| 129 | +// IotDeviceServiceInvokeReqDTO reqDTO = new IotDeviceServiceInvokeReqDTO() | |
| 130 | +// .setParams((Map<String, Object>) downstreamReqVO.getData()); | |
| 131 | +//// CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); | |
| 132 | +// CommonResult<Boolean> result = null; | |
| 133 | +// | |
| 134 | +// // 3. 发送设备消息 | |
| 135 | +// IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) | |
| 136 | +// .setType(IotDeviceMessageTypeEnum.SERVICE.getType()).setIdentifier(reqDTO.getIdentifier()) | |
| 137 | +// .setData(reqDTO.getParams()); | |
| 138 | +// sendDeviceMessage(message, device, result.getCode()); | |
| 139 | +// | |
| 140 | +// // 4. 如果不成功,抛出异常,提示用户 | |
| 141 | +// if (result.isError()) { | |
| 142 | +// log.error("[invokeDeviceService][设备({})服务调用失败,请求参数:({}),响应结果:({})]", | |
| 143 | +// device.getDeviceKey(), reqDTO, result); | |
| 144 | +// throw exception(DEVICE_DOWNSTREAM_FAILED, result.getMsg()); | |
| 145 | +// } | |
| 146 | +// return message; | |
| 147 | +// } | |
| 106 | 148 | |
| 107 | - // 2. 发送请求 | |
| 108 | - String url = String.format("sys/%s/%s/thing/service/%s", | |
| 109 | - getProductKey(device, parentDevice), getDeviceName(device, parentDevice), | |
| 110 | - downstreamReqVO.getIdentifier()); | |
| 111 | - IotDeviceServiceInvokeReqDTO reqDTO = new IotDeviceServiceInvokeReqDTO() | |
| 112 | - .setParams((Map<String, Object>) downstreamReqVO.getData()); | |
| 113 | -// CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); | |
| 114 | - CommonResult<Boolean> result = null; | |
| 149 | +// /** | |
| 150 | +// * 获取设备属性 | |
| 151 | +// * | |
| 152 | +// * @param downstreamReqVO 下行请求 | |
| 153 | +// * @param device 设备 | |
| 154 | +// * @param parentDevice 父设备 | |
| 155 | +// * @return 下发消息 | |
| 156 | +// */ | |
| 157 | +// @SuppressWarnings("unchecked") | |
| 158 | +// private IotDeviceMessage getDeviceProperty(IotDeviceDownstreamReqVO downstreamReqVO, | |
| 159 | +// IotDeviceDO device, IotDeviceDO parentDevice) { | |
| 160 | +// // 1. 参数校验 | |
| 161 | +// if (!(downstreamReqVO.getData() instanceof List<?>)) { | |
| 162 | +// throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 List 类型"); | |
| 163 | +// } | |
| 164 | +// // TODO @super:【可优化】过滤掉不合法的属性 | |
| 165 | +// | |
| 166 | +// // 2. 发送请求 | |
| 167 | +// String url = String.format("sys/%s/%s/thing/service/property/get", | |
| 168 | +// getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); | |
| 169 | +// IotDevicePropertyGetReqDTO reqDTO = new IotDevicePropertyGetReqDTO() | |
| 170 | +// .setIdentifiers((List<String>) downstreamReqVO.getData()); | |
| 171 | +//// CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); | |
| 172 | +// CommonResult<Boolean> result = null; | |
| 173 | +// | |
| 174 | +// // 3. 发送设备消息 | |
| 175 | +// IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) | |
| 176 | +// .setType(IotDeviceMessageTypeEnum.PROPERTY.getType()) | |
| 177 | +// .setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier()) | |
| 178 | +// .setData(reqDTO.getIdentifiers()); | |
| 179 | +// sendDeviceMessage(message, device, result.getCode()); | |
| 180 | +// | |
| 181 | +// // 4. 如果不成功,抛出异常,提示用户 | |
| 182 | +// if (result.isError()) { | |
| 183 | +// log.error("[getDeviceProperty][设备({})属性获取失败,请求参数:({}),响应结果:({})]", | |
| 184 | +// device.getDeviceKey(), reqDTO, result); | |
| 185 | +// throw exception(DEVICE_DOWNSTREAM_FAILED, result.getMsg()); | |
| 186 | +// } | |
| 187 | +// return message; | |
| 188 | +// } | |
| 115 | 189 | |
| 116 | - // 3. 发送设备消息 | |
| 117 | - IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) | |
| 118 | - .setType(IotDeviceMessageTypeEnum.SERVICE.getType()).setIdentifier(reqDTO.getIdentifier()) | |
| 119 | - .setData(reqDTO.getParams()); | |
| 120 | - sendDeviceMessage(message, device, result.getCode()); | |
| 190 | +// /** | |
| 191 | +// * 设置设备配置 | |
| 192 | +// * | |
| 193 | +// * @param downstreamReqVO 下行请求 | |
| 194 | +// * @param device 设备 | |
| 195 | +// * @param parentDevice 父设备 | |
| 196 | +// * @return 下发消息 | |
| 197 | +// */ | |
| 198 | +// @SuppressWarnings({ "unchecked", "unused" }) | |
| 199 | +// private IotDeviceMessage setDeviceConfig(IotDeviceDownstreamReqVO downstreamReqVO, | |
| 200 | +// IotDeviceDO device, IotDeviceDO parentDevice) { | |
| 201 | +// // 1. 参数转换,无需校验 | |
| 202 | +// Map<String, Object> config = JsonUtils.parseObject(device.getConfig(), Map.class); | |
| 203 | +// | |
| 204 | +// // 2. 发送请求 | |
| 205 | +// String url = String.format("sys/%s/%s/thing/service/config/set", | |
| 206 | +// getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); | |
| 207 | +// IotDeviceConfigSetReqDTO reqDTO = new IotDeviceConfigSetReqDTO() | |
| 208 | +// .setConfig(config); | |
| 209 | +//// CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); | |
| 210 | +// CommonResult<Boolean> result = null; | |
| 211 | +// | |
| 212 | +// // 3. 发送设备消息 | |
| 213 | +// IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) | |
| 214 | +// .setType(IotDeviceMessageTypeEnum.CONFIG.getType()) | |
| 215 | +// .setIdentifier(IotDeviceMessageIdentifierEnum.CONFIG_SET.getIdentifier()) | |
| 216 | +// .setData(reqDTO.getConfig()); | |
| 217 | +// sendDeviceMessage(message, device, result.getCode()); | |
| 218 | +// | |
| 219 | +// // 4. 如果不成功,抛出异常,提示用户 | |
| 220 | +// if (result.isError()) { | |
| 221 | +// log.error("[setDeviceConfig][设备({})配置下发失败,请求参数:({}),响应结果:({})]", | |
| 222 | +// device.getDeviceKey(), reqDTO, result); | |
| 223 | +// throw exception(DEVICE_DOWNSTREAM_FAILED, result.getMsg()); | |
| 224 | +// } | |
| 225 | +// return message; | |
| 226 | +// } | |
| 121 | 227 | |
| 122 | - // 4. 如果不成功,抛出异常,提示用户 | |
| 123 | - if (result.isError()) { | |
| 124 | - log.error("[invokeDeviceService][设备({})服务调用失败,请求参数:({}),响应结果:({})]", | |
| 125 | - device.getDeviceKey(), reqDTO, result); | |
| 126 | - throw exception(DEVICE_DOWNSTREAM_FAILED, result.getMsg()); | |
| 127 | - } | |
| 128 | - return message; | |
| 129 | - } | |
| 130 | - | |
| 131 | - /** | |
| 132 | - * 设置设备属性 | |
| 133 | - * | |
| 134 | - * @param downstreamReqVO 下行请求 | |
| 135 | - * @param device 设备 | |
| 136 | - * @param parentDevice 父设备 | |
| 137 | - * @return 下发消息 | |
| 138 | - */ | |
| 139 | - @SuppressWarnings("unchecked") | |
| 140 | - private IotDeviceMessage setDeviceProperty(IotDeviceDownstreamReqVO downstreamReqVO, | |
| 141 | - IotDeviceDO device, IotDeviceDO parentDevice) { | |
| 142 | - // 1. 参数校验 | |
| 143 | - if (!(downstreamReqVO.getData() instanceof Map<?, ?>)) { | |
| 144 | - throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型"); | |
| 145 | - } | |
| 146 | - // TODO @super:【可优化】过滤掉不合法的属性 | |
| 147 | - | |
| 148 | - // 2. 发送请求 | |
| 149 | - cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage message = cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage | |
| 150 | - .of(getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); | |
| 151 | - String serverId = "192_168_64_1_8092"; | |
| 152 | - deviceMessageProducer.sendGatewayDeviceMessage(serverId, message); | |
| 153 | - deviceMessageProducer.sendDeviceMessage(message); | |
| 154 | - // TODO @芋艿:后续可以清理掉 | |
| 155 | - return null; | |
| 156 | - } | |
| 157 | - | |
| 158 | - /** | |
| 159 | - * 获取设备属性 | |
| 160 | - * | |
| 161 | - * @param downstreamReqVO 下行请求 | |
| 162 | - * @param device 设备 | |
| 163 | - * @param parentDevice 父设备 | |
| 164 | - * @return 下发消息 | |
| 165 | - */ | |
| 166 | - @SuppressWarnings("unchecked") | |
| 167 | - private IotDeviceMessage getDeviceProperty(IotDeviceDownstreamReqVO downstreamReqVO, | |
| 168 | - IotDeviceDO device, IotDeviceDO parentDevice) { | |
| 169 | - // 1. 参数校验 | |
| 170 | - if (!(downstreamReqVO.getData() instanceof List<?>)) { | |
| 171 | - throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 List 类型"); | |
| 172 | - } | |
| 173 | - // TODO @super:【可优化】过滤掉不合法的属性 | |
| 174 | - | |
| 175 | - // 2. 发送请求 | |
| 176 | - String url = String.format("sys/%s/%s/thing/service/property/get", | |
| 177 | - getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); | |
| 178 | - IotDevicePropertyGetReqDTO reqDTO = new IotDevicePropertyGetReqDTO() | |
| 179 | - .setIdentifiers((List<String>) downstreamReqVO.getData()); | |
| 180 | -// CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); | |
| 181 | - CommonResult<Boolean> result = null; | |
| 182 | - | |
| 183 | - // 3. 发送设备消息 | |
| 184 | - IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) | |
| 185 | - .setType(IotDeviceMessageTypeEnum.PROPERTY.getType()) | |
| 186 | - .setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier()) | |
| 187 | - .setData(reqDTO.getIdentifiers()); | |
| 188 | - sendDeviceMessage(message, device, result.getCode()); | |
| 189 | - | |
| 190 | - // 4. 如果不成功,抛出异常,提示用户 | |
| 191 | - if (result.isError()) { | |
| 192 | - log.error("[getDeviceProperty][设备({})属性获取失败,请求参数:({}),响应结果:({})]", | |
| 193 | - device.getDeviceKey(), reqDTO, result); | |
| 194 | - throw exception(DEVICE_DOWNSTREAM_FAILED, result.getMsg()); | |
| 195 | - } | |
| 196 | - return message; | |
| 197 | - } | |
| 198 | - | |
| 199 | - /** | |
| 200 | - * 设置设备配置 | |
| 201 | - * | |
| 202 | - * @param downstreamReqVO 下行请求 | |
| 203 | - * @param device 设备 | |
| 204 | - * @param parentDevice 父设备 | |
| 205 | - * @return 下发消息 | |
| 206 | - */ | |
| 207 | - @SuppressWarnings({ "unchecked", "unused" }) | |
| 208 | - private IotDeviceMessage setDeviceConfig(IotDeviceDownstreamReqVO downstreamReqVO, | |
| 209 | - IotDeviceDO device, IotDeviceDO parentDevice) { | |
| 210 | - // 1. 参数转换,无需校验 | |
| 211 | - Map<String, Object> config = JsonUtils.parseObject(device.getConfig(), Map.class); | |
| 212 | - | |
| 213 | - // 2. 发送请求 | |
| 214 | - String url = String.format("sys/%s/%s/thing/service/config/set", | |
| 215 | - getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); | |
| 216 | - IotDeviceConfigSetReqDTO reqDTO = new IotDeviceConfigSetReqDTO() | |
| 217 | - .setConfig(config); | |
| 218 | -// CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); | |
| 219 | - CommonResult<Boolean> result = null; | |
| 220 | - | |
| 221 | - // 3. 发送设备消息 | |
| 222 | - IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) | |
| 223 | - .setType(IotDeviceMessageTypeEnum.CONFIG.getType()) | |
| 224 | - .setIdentifier(IotDeviceMessageIdentifierEnum.CONFIG_SET.getIdentifier()) | |
| 225 | - .setData(reqDTO.getConfig()); | |
| 226 | - sendDeviceMessage(message, device, result.getCode()); | |
| 227 | - | |
| 228 | - // 4. 如果不成功,抛出异常,提示用户 | |
| 229 | - if (result.isError()) { | |
| 230 | - log.error("[setDeviceConfig][设备({})配置下发失败,请求参数:({}),响应结果:({})]", | |
| 231 | - device.getDeviceKey(), reqDTO, result); | |
| 232 | - throw exception(DEVICE_DOWNSTREAM_FAILED, result.getMsg()); | |
| 233 | - } | |
| 234 | - return message; | |
| 235 | - } | |
| 236 | - | |
| 237 | - /** | |
| 238 | - * 设备 OTA 升级 | |
| 239 | - * | |
| 240 | - * @param downstreamReqVO 下行请求 | |
| 241 | - * @param device 设备 | |
| 242 | - * @param parentDevice 父设备 | |
| 243 | - * @return 下发消息 | |
| 244 | - */ | |
| 245 | - private IotDeviceMessage otaUpgrade(IotDeviceDownstreamReqVO downstreamReqVO, | |
| 246 | - IotDeviceDO device, IotDeviceDO parentDevice) { | |
| 247 | - // 1. 参数校验 | |
| 248 | - if (!(downstreamReqVO.getData() instanceof Map<?, ?> data)) { | |
| 249 | - throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型"); | |
| 250 | - } | |
| 251 | - | |
| 252 | - // 2. 发送请求 | |
| 253 | - String url = String.format("ota/%s/%s/upgrade", | |
| 254 | - getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); | |
| 255 | - IotDeviceOtaUpgradeReqDTO reqDTO = IotDeviceOtaUpgradeReqDTO.build(data); | |
| 256 | -// CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); | |
| 257 | - CommonResult<Boolean> result = null; | |
| 258 | - | |
| 259 | - // 3. 发送设备消息 | |
| 260 | - IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) | |
| 261 | - .setType(IotDeviceMessageTypeEnum.OTA.getType()) | |
| 262 | - .setIdentifier(IotDeviceMessageIdentifierEnum.OTA_UPGRADE.getIdentifier()) | |
| 263 | - .setData(downstreamReqVO.getData()); | |
| 264 | - sendDeviceMessage(message, device, result.getCode()); | |
| 265 | - | |
| 266 | - // 4. 如果不成功,抛出异常,提示用户 | |
| 267 | - if (result.isError()) { | |
| 268 | - log.error("[otaUpgrade][设备({}) OTA 升级失败,请求参数:({}),响应结果:({})]", | |
| 269 | - device.getDeviceKey(), reqDTO, result); | |
| 270 | - throw exception(DEVICE_DOWNSTREAM_FAILED, result.getMsg()); | |
| 271 | - } | |
| 272 | - return message; | |
| 273 | - } | |
| 274 | - | |
| 275 | - private void sendDeviceMessage(IotDeviceMessage message, IotDeviceDO device, Integer code) { | |
| 276 | - // 1. 完善消息 | |
| 277 | - message.setProductKey(device.getProductKey()).setDeviceName(device.getDeviceName()) | |
| 278 | - .setDeviceKey(device.getDeviceKey()) | |
| 279 | - .setTenantId(device.getTenantId()); | |
| 280 | - Assert.notNull(message.getRequestId(), "requestId 不能为空"); | |
| 281 | - if (message.getReportTime() == null) { | |
| 282 | - message.setReportTime(LocalDateTime.now()); | |
| 283 | - } | |
| 284 | - message.setCode(code); | |
| 285 | - | |
| 286 | - // 2. 发送消息 | |
| 287 | - try { | |
| 288 | - deviceProducer.sendDeviceMessage(message); | |
| 289 | - log.info("[sendDeviceMessage][message({}) 发送消息成功]", message); | |
| 290 | - } catch (Exception e) { | |
| 291 | - log.error("[sendDeviceMessage][message({}) 发送消息失败]", message, e); | |
| 292 | - } | |
| 293 | - } | |
| 228 | +// /** | |
| 229 | +// * 设备 OTA 升级 | |
| 230 | +// * | |
| 231 | +// * @param downstreamReqVO 下行请求 | |
| 232 | +// * @param device 设备 | |
| 233 | +// * @param parentDevice 父设备 | |
| 234 | +// * @return 下发消息 | |
| 235 | +// */ | |
| 236 | +// private IotDeviceMessage otaUpgrade(IotDeviceDownstreamReqVO downstreamReqVO, | |
| 237 | +// IotDeviceDO device, IotDeviceDO parentDevice) { | |
| 238 | +// // 1. 参数校验 | |
| 239 | +// if (!(downstreamReqVO.getData() instanceof Map<?, ?> data)) { | |
| 240 | +// throw new ServiceException(BAD_REQUEST.getCode(), "data 不是 Map 类型"); | |
| 241 | +// } | |
| 242 | +// | |
| 243 | +// // 2. 发送请求 | |
| 244 | +// String url = String.format("ota/%s/%s/upgrade", | |
| 245 | +// getProductKey(device, parentDevice), getDeviceName(device, parentDevice)); | |
| 246 | +// IotDeviceOtaUpgradeReqDTO reqDTO = IotDeviceOtaUpgradeReqDTO.build(data); | |
| 247 | +//// CommonResult<Boolean> result = requestPlugin(url, reqDTO, device); | |
| 248 | +// CommonResult<Boolean> result = null; | |
| 249 | +// | |
| 250 | +// // 3. 发送设备消息 | |
| 251 | +// IotDeviceMessage message = new IotDeviceMessage().setRequestId(reqDTO.getRequestId()) | |
| 252 | +// .setType(IotDeviceMessageTypeEnum.OTA.getType()) | |
| 253 | +// .setIdentifier(IotDeviceMessageIdentifierEnum.OTA_UPGRADE.getIdentifier()) | |
| 254 | +// .setData(downstreamReqVO.getData()); | |
| 255 | +// sendDeviceMessage(message, device, result.getCode()); | |
| 256 | +// | |
| 257 | +// // 4. 如果不成功,抛出异常,提示用户 | |
| 258 | +// if (result.isError()) { | |
| 259 | +// log.error("[otaUpgrade][设备({}) OTA 升级失败,请求参数:({}),响应结果:({})]", | |
| 260 | +// device.getDeviceKey(), reqDTO, result); | |
| 261 | +// throw exception(DEVICE_DOWNSTREAM_FAILED, result.getMsg()); | |
| 262 | +// } | |
| 263 | +// return message; | |
| 264 | +// } | |
| 294 | 265 | |
| 295 | 266 | private String getDeviceName(IotDeviceDO device, IotDeviceDO parentDevice) { |
| 296 | 267 | return parentDevice != null ? parentDevice.getDeviceName() : device.getDeviceName(); | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceUpstreamService.java
| ... | ... | @@ -7,7 +7,7 @@ import jakarta.validation.Valid; |
| 7 | 7 | /** |
| 8 | 8 | * IoT 设备上行 Service 接口 |
| 9 | 9 | * |
| 10 | - * 目的:设备 -> 插件 -> 服务端 | |
| 10 | + * 目的:设备 -> 网关 -> 服务端 | |
| 11 | 11 | * |
| 12 | 12 | * @author 芋道源码 |
| 13 | 13 | */ |
| ... | ... | @@ -20,47 +20,33 @@ public interface IotDeviceUpstreamService { |
| 20 | 20 | */ |
| 21 | 21 | void upstreamDevice(@Valid IotDeviceUpstreamReqVO simulatorReqVO); |
| 22 | 22 | |
| 23 | - /** | |
| 24 | - * 更新设备状态 | |
| 25 | - * | |
| 26 | - * @param updateReqDTO 更新设备状态 DTO | |
| 27 | - */ | |
| 28 | - void updateDeviceState(IotDeviceStateUpdateReqDTO updateReqDTO); | |
| 29 | - | |
| 30 | - /** | |
| 31 | - * 上报设备属性数据 | |
| 32 | - * | |
| 33 | - * @param reportReqDTO 上报设备属性数据 DTO | |
| 34 | - */ | |
| 35 | - void reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO); | |
| 36 | - | |
| 37 | - /** | |
| 38 | - * 上报设备事件数据 | |
| 39 | - * | |
| 40 | - * @param reportReqDTO 设备事件 | |
| 41 | - */ | |
| 42 | - void reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO); | |
| 43 | - | |
| 44 | - /** | |
| 45 | - * 注册设备 | |
| 46 | - * | |
| 47 | - * @param registerReqDTO 注册设备 DTO | |
| 48 | - */ | |
| 49 | - void registerDevice(IotDeviceRegisterReqDTO registerReqDTO); | |
| 50 | - | |
| 51 | - /** | |
| 52 | - * 注册子设备 | |
| 53 | - * | |
| 54 | - * @param registerReqDTO 注册子设备 DTO | |
| 55 | - */ | |
| 56 | - void registerSubDevice(IotDeviceRegisterSubReqDTO registerReqDTO); | |
| 57 | - | |
| 58 | - /** | |
| 59 | - * 添加设备拓扑 | |
| 60 | - * | |
| 61 | - * @param addReqDTO 添加设备拓扑 DTO | |
| 62 | - */ | |
| 63 | - void addDeviceTopology(IotDeviceTopologyAddReqDTO addReqDTO); | |
| 23 | +// /** | |
| 24 | +// * 上报设备事件数据 | |
| 25 | +// * | |
| 26 | +// * @param reportReqDTO 设备事件 | |
| 27 | +// */ | |
| 28 | +// void reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO); | |
| 29 | +// | |
| 30 | +// /** | |
| 31 | +// * 注册设备 | |
| 32 | +// * | |
| 33 | +// * @param registerReqDTO 注册设备 DTO | |
| 34 | +// */ | |
| 35 | +// void registerDevice(IotDeviceRegisterReqDTO registerReqDTO); | |
| 36 | +// | |
| 37 | +// /** | |
| 38 | +// * 注册子设备 | |
| 39 | +// * | |
| 40 | +// * @param registerReqDTO 注册子设备 DTO | |
| 41 | +// */ | |
| 42 | +// void registerSubDevice(IotDeviceRegisterSubReqDTO registerReqDTO); | |
| 43 | +// | |
| 44 | +// /** | |
| 45 | +// * 添加设备拓扑 | |
| 46 | +// * | |
| 47 | +// * @param addReqDTO 添加设备拓扑 DTO | |
| 48 | +// */ | |
| 49 | +// void addDeviceTopology(IotDeviceTopologyAddReqDTO addReqDTO); | |
| 64 | 50 | |
| 65 | 51 | /** |
| 66 | 52 | * Emqx 连接认证 | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceUpstreamServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.device.control; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | -import cn.hutool.core.lang.Assert; | |
| 5 | 4 | import cn.hutool.core.util.IdUtil; |
| 6 | 5 | import cn.hutool.core.util.ObjUtil; |
| 7 | 6 | import cn.hutool.core.util.StrUtil; |
| 8 | -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | |
| 9 | -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | |
| 10 | 7 | import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; |
| 11 | 8 | import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.*; |
| 12 | 9 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceUpstreamReqVO; |
| 13 | 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 14 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; | |
| 15 | 11 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; |
| 16 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | |
| 17 | 12 | import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum; |
| 18 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 19 | -import cn.iocoder.yudao.module.iot.mq.producer.device.IotDeviceProducer; | |
| 20 | 13 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 21 | 14 | import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; |
| 22 | 15 | import cn.iocoder.yudao.module.iot.util.MqttSignUtils; |
| ... | ... | @@ -45,9 +38,7 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { |
| 45 | 38 | @Resource |
| 46 | 39 | private IotDevicePropertyService devicePropertyService; |
| 47 | 40 | |
| 48 | - @Resource | |
| 49 | - private IotDeviceProducer deviceProducer; | |
| 50 | - | |
| 41 | + // TODO @芋艿:需要重新实现下; | |
| 51 | 42 | @Override |
| 52 | 43 | @SuppressWarnings("unchecked") |
| 53 | 44 | public void upstreamDevice(IotDeviceUpstreamReqVO simulatorReqVO) { |
| ... | ... | @@ -74,53 +65,13 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { |
| 74 | 65 | } |
| 75 | 66 | // 2.3 情况三:状态变更 |
| 76 | 67 | if (Objects.equals(simulatorReqVO.getType(), IotDeviceMessageTypeEnum.STATE.getType())) { |
| 77 | - updateDeviceState(((IotDeviceStateUpdateReqDTO) new IotDeviceStateUpdateReqDTO() | |
| 78 | - .setRequestId(IdUtil.fastSimpleUUID()).setReportTime(LocalDateTime.now()) | |
| 79 | - .setProductKey(device.getProductKey()).setDeviceName(device.getDeviceName())) | |
| 80 | - .setState((Integer) simulatorReqVO.getData())); | |
| 68 | + // TODO @芋艿:这里未搞完 | |
| 81 | 69 | return; |
| 82 | 70 | } |
| 83 | 71 | throw new IllegalArgumentException("未知的类型:" + simulatorReqVO.getType()); |
| 84 | 72 | } |
| 85 | 73 | |
| 86 | - @Override | |
| 87 | - public void updateDeviceState(IotDeviceStateUpdateReqDTO updateReqDTO) { | |
| 88 | - Assert.isTrue(ObjectUtils.equalsAny(updateReqDTO.getState(), | |
| 89 | - IotDeviceStateEnum.ONLINE.getState(), IotDeviceStateEnum.OFFLINE.getState()), | |
| 90 | - "状态不合法"); | |
| 91 | - // 1.1 获得设备 | |
| 92 | - log.info("[updateDeviceState][更新设备状态: {}]", updateReqDTO); | |
| 93 | - IotDeviceDO device = deviceService.getDeviceByProductKeyAndDeviceNameFromCache( | |
| 94 | - updateReqDTO.getProductKey(), updateReqDTO.getDeviceName()); | |
| 95 | - if (device == null) { | |
| 96 | - log.error("[updateDeviceState][设备({}/{}) 不存在]", | |
| 97 | - updateReqDTO.getProductKey(), updateReqDTO.getDeviceName()); | |
| 98 | - return; | |
| 99 | - } | |
| 100 | - TenantUtils.execute(device.getTenantId(), () -> { | |
| 101 | - // 1.2 记录设备的最后时间 | |
| 102 | - updateDeviceLastTime(device, updateReqDTO); | |
| 103 | - // 1.3 当前状态一致,不处理 | |
| 104 | - if (Objects.equals(device.getState(), updateReqDTO.getState())) { | |
| 105 | - return; | |
| 106 | - } | |
| 107 | - | |
| 108 | - // 2. 更新设备状态 | |
| 109 | - deviceService.updateDeviceState(device.getId(), updateReqDTO.getState()); | |
| 110 | - | |
| 111 | - // 3. TODO 芋艿:子设备的关联 | |
| 112 | - | |
| 113 | - // 4. 发送设备消息 | |
| 114 | - IotDeviceMessage message = BeanUtils.toBean(updateReqDTO, IotDeviceMessage.class) | |
| 115 | - .setType(IotDeviceMessageTypeEnum.STATE.getType()) | |
| 116 | - .setIdentifier(ObjUtil.equals(updateReqDTO.getState(), IotDeviceStateEnum.ONLINE.getState()) | |
| 117 | - ? IotDeviceMessageIdentifierEnum.STATE_ONLINE.getIdentifier() | |
| 118 | - : IotDeviceMessageIdentifierEnum.STATE_OFFLINE.getIdentifier()); | |
| 119 | - sendDeviceMessage(message, device); | |
| 120 | - }); | |
| 121 | - } | |
| 122 | - | |
| 123 | - @Override | |
| 74 | +// @Override TODO 芋艿:待重新实现 | |
| 124 | 75 | public void reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO) { |
| 125 | 76 | // 1.1 获得设备 |
| 126 | 77 | log.info("[reportDeviceProperty][上报设备属性: {}]", reportReqDTO); |
| ... | ... | @@ -131,18 +82,16 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { |
| 131 | 82 | reportReqDTO.getProductKey(), reportReqDTO.getDeviceName()); |
| 132 | 83 | return; |
| 133 | 84 | } |
| 134 | - // 1.2 记录设备的最后时间 | |
| 135 | - updateDeviceLastTime(device, reportReqDTO); | |
| 136 | 85 | |
| 137 | 86 | // 2. 发送设备消息 |
| 138 | - IotDeviceMessage message = BeanUtils.toBean(reportReqDTO, IotDeviceMessage.class) | |
| 139 | - .setType(IotDeviceMessageTypeEnum.PROPERTY.getType()) | |
| 140 | - .setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_REPORT.getIdentifier()) | |
| 141 | - .setData(reportReqDTO.getProperties()); | |
| 142 | - sendDeviceMessage(message, device); | |
| 87 | +// IotDeviceMessage message = BeanUtils.toBean(reportReqDTO, IotDeviceMessage.class) | |
| 88 | +// .setType(IotDeviceMessageTypeEnum.PROPERTY.getType()) | |
| 89 | +// .setIdentifier(IotDeviceMessageIdentifierEnum.PROPERTY_REPORT.getIdentifier()) | |
| 90 | +// .setData(reportReqDTO.getProperties()); | |
| 91 | +// sendDeviceMessage(message, device); | |
| 143 | 92 | } |
| 144 | 93 | |
| 145 | - @Override | |
| 94 | + // @Override TODO 芋艿:待重新实现 | |
| 146 | 95 | public void reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO) { |
| 147 | 96 | // 1.1 获得设备 |
| 148 | 97 | log.info("[reportDeviceEvent][上报设备事件: {}]", reportReqDTO); |
| ... | ... | @@ -153,18 +102,16 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { |
| 153 | 102 | reportReqDTO.getProductKey(), reportReqDTO.getDeviceName()); |
| 154 | 103 | return; |
| 155 | 104 | } |
| 156 | - // 1.2 记录设备的最后时间 | |
| 157 | - updateDeviceLastTime(device, reportReqDTO); | |
| 158 | 105 | |
| 159 | 106 | // 2. 发送设备消息 |
| 160 | - IotDeviceMessage message = BeanUtils.toBean(reportReqDTO, IotDeviceMessage.class) | |
| 161 | - .setType(IotDeviceMessageTypeEnum.EVENT.getType()) | |
| 162 | - .setIdentifier(reportReqDTO.getIdentifier()) | |
| 163 | - .setData(reportReqDTO.getParams()); | |
| 164 | - sendDeviceMessage(message, device); | |
| 107 | +// IotDeviceMessage message = BeanUtils.toBean(reportReqDTO, IotDeviceMessage.class) | |
| 108 | +// .setType(IotDeviceMessageTypeEnum.EVENT.getType()) | |
| 109 | +// .setIdentifier(reportReqDTO.getIdentifier()) | |
| 110 | +// .setData(reportReqDTO.getParams()); | |
| 111 | +// sendDeviceMessage(message, device); | |
| 165 | 112 | } |
| 166 | 113 | |
| 167 | - @Override | |
| 114 | + // @Override TODO 芋艿:待重新实现 | |
| 168 | 115 | public void registerDevice(IotDeviceRegisterReqDTO registerReqDTO) { |
| 169 | 116 | log.info("[registerDevice][注册设备: {}]", registerReqDTO); |
| 170 | 117 | registerDevice0(registerReqDTO.getProductKey(), registerReqDTO.getDeviceName(), null, registerReqDTO); |
| ... | ... | @@ -186,18 +133,18 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { |
| 186 | 133 | registerReqDTO, productKey, device, gatewayId); |
| 187 | 134 | } |
| 188 | 135 | // 1.2 记录设备的最后时间 |
| 189 | - updateDeviceLastTime(device, registerReqDTO); | |
| 136 | +// updateDeviceLastTime(device, registerReqDTO); | |
| 190 | 137 | |
| 191 | 138 | // 2. 发送设备消息 |
| 192 | 139 | if (registerNew) { |
| 193 | - IotDeviceMessage message = BeanUtils.toBean(registerReqDTO, IotDeviceMessage.class) | |
| 194 | - .setType(IotDeviceMessageTypeEnum.REGISTER.getType()) | |
| 195 | - .setIdentifier(IotDeviceMessageIdentifierEnum.REGISTER_REGISTER.getIdentifier()); | |
| 196 | - sendDeviceMessage(message, device); | |
| 140 | +// IotDeviceMessage message = BeanUtils.toBean(registerReqDTO, IotDeviceMessage.class) | |
| 141 | +// .setType(IotDeviceMessageTypeEnum.REGISTER.getType()) | |
| 142 | +// .setIdentifier(IotDeviceMessageIdentifierEnum.REGISTER_REGISTER.getIdentifier()); | |
| 143 | +// sendDeviceMessage(message, device); | |
| 197 | 144 | } |
| 198 | 145 | } |
| 199 | 146 | |
| 200 | - @Override | |
| 147 | + // @Override TODO 芋艿:待重新实现 | |
| 201 | 148 | public void registerSubDevice(IotDeviceRegisterSubReqDTO registerReqDTO) { |
| 202 | 149 | // 1.1 注册子设备 |
| 203 | 150 | log.info("[registerSubDevice][注册子设备: {}]", registerReqDTO); |
| ... | ... | @@ -214,7 +161,7 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { |
| 214 | 161 | return; |
| 215 | 162 | } |
| 216 | 163 | // 1.2 记录设备的最后时间 |
| 217 | - updateDeviceLastTime(device, registerReqDTO); | |
| 164 | +// updateDeviceLastTime(device, registerReqDTO); | |
| 218 | 165 | |
| 219 | 166 | // 2. 处理子设备 |
| 220 | 167 | if (CollUtil.isNotEmpty(registerReqDTO.getParams())) { |
| ... | ... | @@ -224,14 +171,14 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { |
| 224 | 171 | } |
| 225 | 172 | |
| 226 | 173 | // 3. 发送设备消息 |
| 227 | - IotDeviceMessage message = BeanUtils.toBean(registerReqDTO, IotDeviceMessage.class) | |
| 228 | - .setType(IotDeviceMessageTypeEnum.REGISTER.getType()) | |
| 229 | - .setIdentifier(IotDeviceMessageIdentifierEnum.REGISTER_REGISTER_SUB.getIdentifier()) | |
| 230 | - .setData(registerReqDTO.getParams()); | |
| 231 | - sendDeviceMessage(message, device); | |
| 174 | +// IotDeviceMessage message = BeanUtils.toBean(registerReqDTO, IotDeviceMessage.class) | |
| 175 | +// .setType(IotDeviceMessageTypeEnum.REGISTER.getType()) | |
| 176 | +// .setIdentifier(IotDeviceMessageIdentifierEnum.REGISTER_REGISTER_SUB.getIdentifier()) | |
| 177 | +// .setData(registerReqDTO.getParams()); | |
| 178 | +// sendDeviceMessage(message, device); | |
| 232 | 179 | } |
| 233 | 180 | |
| 234 | - @Override | |
| 181 | + // @Override TODO 芋艿:待重新实现 | |
| 235 | 182 | public void addDeviceTopology(IotDeviceTopologyAddReqDTO addReqDTO) { |
| 236 | 183 | // 1.1 获得设备 |
| 237 | 184 | log.info("[addDeviceTopology][添加设备拓扑: {}]", addReqDTO); |
| ... | ... | @@ -247,8 +194,6 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { |
| 247 | 194 | addReqDTO.getProductKey(), addReqDTO.getDeviceName(), device); |
| 248 | 195 | return; |
| 249 | 196 | } |
| 250 | - // 1.2 记录设备的最后时间 | |
| 251 | - updateDeviceLastTime(device, addReqDTO); | |
| 252 | 197 | |
| 253 | 198 | // 2. 处理拓扑 |
| 254 | 199 | if (CollUtil.isNotEmpty(addReqDTO.getParams())) { |
| ... | ... | @@ -270,11 +215,11 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { |
| 270 | 215 | } |
| 271 | 216 | |
| 272 | 217 | // 3. 发送设备消息 |
| 273 | - IotDeviceMessage message = BeanUtils.toBean(addReqDTO, IotDeviceMessage.class) | |
| 274 | - .setType(IotDeviceMessageTypeEnum.TOPOLOGY.getType()) | |
| 275 | - .setIdentifier(IotDeviceMessageIdentifierEnum.TOPOLOGY_ADD.getIdentifier()) | |
| 276 | - .setData(addReqDTO.getParams()); | |
| 277 | - sendDeviceMessage(message, device); | |
| 218 | +// IotDeviceMessage message = BeanUtils.toBean(addReqDTO, IotDeviceMessage.class) | |
| 219 | +// .setType(IotDeviceMessageTypeEnum.TOPOLOGY.getType()) | |
| 220 | +// .setIdentifier(IotDeviceMessageIdentifierEnum.TOPOLOGY_ADD.getIdentifier()) | |
| 221 | +// .setData(addReqDTO.getParams()); | |
| 222 | +// sendDeviceMessage(message, device); | |
| 278 | 223 | } |
| 279 | 224 | |
| 280 | 225 | // TODO @芋艿:后续需要考虑,http 的认证 |
| ... | ... | @@ -310,33 +255,4 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { |
| 310 | 255 | return false; |
| 311 | 256 | } |
| 312 | 257 | |
| 313 | - private void updateDeviceLastTime(IotDeviceDO device, IotDeviceUpstreamAbstractReqDTO reqDTO) { | |
| 314 | - // 1. 【异步】记录设备与插件实例的映射 | |
| 315 | -// pluginInstanceService.updateDevicePluginInstanceProcessIdAsync(device.getDeviceKey(), reqDTO.getProcessId()); | |
| 316 | - // TODO @芋艿:需要单独补充下; | |
| 317 | - | |
| 318 | - // 2. 【异步】更新设备的最后时间 | |
| 319 | - devicePropertyService.updateDeviceReportTimeAsync(device.getDeviceKey(), LocalDateTime.now()); | |
| 320 | - } | |
| 321 | - | |
| 322 | - private void sendDeviceMessage(IotDeviceMessage message, IotDeviceDO device) { | |
| 323 | - // 1. 完善消息 | |
| 324 | - message.setDeviceKey(device.getDeviceKey()) | |
| 325 | - .setTenantId(device.getTenantId()); | |
| 326 | - if (StrUtil.isEmpty(message.getRequestId())) { | |
| 327 | - message.setRequestId(IdUtil.fastSimpleUUID()); | |
| 328 | - } | |
| 329 | - if (message.getReportTime() == null) { | |
| 330 | - message.setReportTime(LocalDateTime.now()); | |
| 331 | - } | |
| 332 | - | |
| 333 | - // 2. 发送消息 | |
| 334 | - try { | |
| 335 | - deviceProducer.sendDeviceMessage(message); | |
| 336 | - log.info("[sendDeviceMessage][message({}) 发送消息成功]", message); | |
| 337 | - } catch (Exception e) { | |
| 338 | - log.error("[sendDeviceMessage][message({}) 发送消息失败]", message, e); | |
| 339 | - } | |
| 340 | - } | |
| 341 | - | |
| 342 | 258 | } | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/data/IotDevicePropertyService.java
| ... | ... | @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.iot.service.device.data; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyHistoryPageReqVO; |
| 5 | 5 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO; |
| 6 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 6 | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; |
| 7 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 8 | 8 | import jakarta.validation.Valid; |
| 9 | 9 | |
| 10 | 10 | import java.time.LocalDateTime; |
| ... | ... | @@ -56,16 +56,43 @@ public interface IotDevicePropertyService { |
| 56 | 56 | * 获得最后上报时间小于指定时间的设备标识 |
| 57 | 57 | * |
| 58 | 58 | * @param maxReportTime 最大上报时间 |
| 59 | - * @return 设备标识列表 | |
| 59 | + * @return [productKey, deviceName] 列表 | |
| 60 | 60 | */ |
| 61 | - Set<String> getDeviceKeysByReportTime(LocalDateTime maxReportTime); | |
| 61 | + Set<String[]> getProductKeyDeviceNameListByReportTime(LocalDateTime maxReportTime); | |
| 62 | 62 | |
| 63 | 63 | /** |
| 64 | - * 异步更新设备上报时间 | |
| 64 | + * 更新设备上报时间 | |
| 65 | 65 | * |
| 66 | - * @param deviceKey 设备标识 | |
| 66 | + * @param productKey 产品标识 | |
| 67 | + * @param deviceName 设备名称 | |
| 67 | 68 | * @param reportTime 上报时间 |
| 68 | 69 | */ |
| 69 | - void updateDeviceReportTimeAsync(String deviceKey, LocalDateTime reportTime); | |
| 70 | + void updateDeviceReportTime(String productKey, String deviceName, LocalDateTime reportTime); | |
| 71 | + | |
| 72 | + /** | |
| 73 | + * 更新设备关联的网关 serverId | |
| 74 | + * | |
| 75 | + * @param productKey 产品标识 | |
| 76 | + * @param deviceName 设备名称 | |
| 77 | + * @param serverId 网关 serverId | |
| 78 | + */ | |
| 79 | + void updateDeviceServerId(String productKey, String deviceName, String serverId); | |
| 80 | + | |
| 81 | + /** | |
| 82 | + * 删除设备关联的网关 serverId | |
| 83 | + * | |
| 84 | + * @param productKey 产品标识 | |
| 85 | + * @param deviceName 设备名称 | |
| 86 | + */ | |
| 87 | + void deleteDeviceServerId(String productKey, String deviceName); | |
| 88 | + | |
| 89 | + /** | |
| 90 | + * 获得设备关联的网关 serverId | |
| 91 | + * | |
| 92 | + * @param productKey 产品标识 | |
| 93 | + * @param deviceName 设备名称 | |
| 94 | + * @return 网关 serverId | |
| 95 | + */ | |
| 96 | + String getDeviceServerId(String productKey, String deviceName); | |
| 70 | 97 | |
| 71 | 98 | } |
| 72 | 99 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/data/IotDevicePropertyServiceImpl.java
| ... | ... | @@ -9,17 +9,18 @@ import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; |
| 9 | 9 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyHistoryPageReqVO; |
| 10 | 10 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO; |
| 11 | 11 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs; |
| 12 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 12 | 13 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 13 | 14 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; |
| 14 | 15 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 15 | 16 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 16 | 17 | import cn.iocoder.yudao.module.iot.dal.redis.device.DevicePropertyRedisDAO; |
| 17 | 18 | import cn.iocoder.yudao.module.iot.dal.redis.device.DeviceReportTimeRedisDAO; |
| 19 | +import cn.iocoder.yudao.module.iot.dal.redis.device.DeviceServerIdRedisDAO; | |
| 18 | 20 | import cn.iocoder.yudao.module.iot.dal.tdengine.IotDevicePropertyMapper; |
| 19 | 21 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum; |
| 20 | 22 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; |
| 21 | 23 | import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField; |
| 22 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 23 | 24 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 24 | 25 | import cn.iocoder.yudao.module.iot.service.product.IotProductService; |
| 25 | 26 | import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; |
| ... | ... | @@ -27,7 +28,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage; |
| 27 | 28 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| 28 | 29 | import jakarta.annotation.Resource; |
| 29 | 30 | import lombok.extern.slf4j.Slf4j; |
| 30 | -import org.springframework.scheduling.annotation.Async; | |
| 31 | 31 | import org.springframework.stereotype.Service; |
| 32 | 32 | |
| 33 | 33 | import java.time.LocalDateTime; |
| ... | ... | @@ -70,6 +70,8 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { |
| 70 | 70 | private DevicePropertyRedisDAO deviceDataRedisDAO; |
| 71 | 71 | @Resource |
| 72 | 72 | private DeviceReportTimeRedisDAO deviceReportTimeRedisDAO; |
| 73 | + @Resource | |
| 74 | + private DeviceServerIdRedisDAO deviceServerIdRedisDAO; | |
| 73 | 75 | |
| 74 | 76 | @Resource |
| 75 | 77 | private IotDevicePropertyMapper devicePropertyMapper; |
| ... | ... | @@ -153,7 +155,8 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { |
| 153 | 155 | LocalDateTimeUtil.toEpochMilli(message.getReportTime())); |
| 154 | 156 | |
| 155 | 157 | // 3.2 保存设备属性【日志】 |
| 156 | - deviceDataRedisDAO.putAll(message.getDeviceKey(), convertMap(properties.entrySet(), Map.Entry::getKey, | |
| 158 | + // TODO @芋艿:这里要调整下; | |
| 159 | + deviceDataRedisDAO.putAll(device.getDeviceKey(), convertMap(properties.entrySet(), Map.Entry::getKey, | |
| 157 | 160 | entry -> IotDevicePropertyDO.builder().value(entry.getValue()).updateTime(message.getReportTime()).build())); |
| 158 | 161 | } |
| 159 | 162 | |
| ... | ... | @@ -187,14 +190,31 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { |
| 187 | 190 | // ========== 设备时间相关操作 ========== |
| 188 | 191 | |
| 189 | 192 | @Override |
| 190 | - public Set<String> getDeviceKeysByReportTime(LocalDateTime maxReportTime) { | |
| 193 | + public Set<String[]> getProductKeyDeviceNameListByReportTime(LocalDateTime maxReportTime) { | |
| 191 | 194 | return deviceReportTimeRedisDAO.range(maxReportTime); |
| 192 | 195 | } |
| 193 | 196 | |
| 194 | 197 | @Override |
| 195 | - @Async | |
| 196 | - public void updateDeviceReportTimeAsync(String deviceKey, LocalDateTime reportTime) { | |
| 197 | - deviceReportTimeRedisDAO.update(deviceKey, reportTime); | |
| 198 | + public void updateDeviceReportTime(String productKey, String deviceName, LocalDateTime reportTime) { | |
| 199 | + deviceReportTimeRedisDAO.update(productKey, deviceName, reportTime); | |
| 200 | + } | |
| 201 | + | |
| 202 | + @Override | |
| 203 | + public void updateDeviceServerId(String productKey, String deviceName, String serverId) { | |
| 204 | + if (StrUtil.isEmpty(serverId)) { | |
| 205 | + return; | |
| 206 | + } | |
| 207 | + deviceServerIdRedisDAO.update(productKey, deviceName, serverId); | |
| 208 | + } | |
| 209 | + | |
| 210 | + @Override | |
| 211 | + public void deleteDeviceServerId(String productKey, String deviceName) { | |
| 212 | + deviceServerIdRedisDAO.delete(productKey, deviceName); | |
| 213 | + } | |
| 214 | + | |
| 215 | + @Override | |
| 216 | + public String getDeviceServerId(String productKey, String deviceName) { | |
| 217 | + return deviceServerIdRedisDAO.get(productKey, deviceName); | |
| 198 | 218 | } |
| 199 | 219 | |
| 200 | 220 | } |
| 201 | 221 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneService.java
| ... | ... | @@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.iot.service.rule; |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO; |
| 5 | 5 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO; |
| 6 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 6 | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 7 | 8 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; |
| 8 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 9 | 9 | import jakarta.validation.Valid; |
| 10 | 10 | |
| 11 | 11 | import java.util.List; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/IotRuleSceneServiceImpl.java
| ... | ... | @@ -17,6 +17,7 @@ import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; |
| 17 | 17 | import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; |
| 18 | 18 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO; |
| 19 | 19 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO; |
| 20 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 20 | 21 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 21 | 22 | import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotRuleSceneMapper; |
| 22 | 23 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; |
| ... | ... | @@ -26,7 +27,6 @@ import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerConditionParame |
| 26 | 27 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; |
| 27 | 28 | import cn.iocoder.yudao.module.iot.framework.job.core.IotSchedulerManager; |
| 28 | 29 | import cn.iocoder.yudao.module.iot.job.rule.IotRuleSceneJob; |
| 29 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 30 | 30 | import cn.iocoder.yudao.module.iot.service.rule.action.IotRuleSceneAction; |
| 31 | 31 | import jakarta.annotation.Resource; |
| 32 | 32 | import lombok.SneakyThrows; |
| ... | ... | @@ -240,16 +240,17 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { |
| 240 | 240 | |
| 241 | 241 | @Override |
| 242 | 242 | public void executeRuleSceneByDevice(IotDeviceMessage message) { |
| 243 | - TenantUtils.execute(message.getTenantId(), () -> { | |
| 244 | - // 1. 获得设备匹配的规则场景 | |
| 245 | - List<IotRuleSceneDO> ruleScenes = getMatchedRuleSceneListByMessage(message); | |
| 246 | - if (CollUtil.isEmpty(ruleScenes)) { | |
| 247 | - return; | |
| 248 | - } | |
| 249 | - | |
| 250 | - // 2. 执行规则场景 | |
| 251 | - executeRuleSceneAction(message, ruleScenes); | |
| 252 | - }); | |
| 243 | + // TODO @芋艿:这里的 tenantId,通过设备获取; | |
| 244 | +// TenantUtils.execute(message.getTenantId(), () -> { | |
| 245 | +// // 1. 获得设备匹配的规则场景 | |
| 246 | +// List<IotRuleSceneDO> ruleScenes = getMatchedRuleSceneListByMessage(message); | |
| 247 | +// if (CollUtil.isEmpty(ruleScenes)) { | |
| 248 | +// return; | |
| 249 | +// } | |
| 250 | +// | |
| 251 | +// // 2. 执行规则场景 | |
| 252 | +// executeRuleSceneAction(message, ruleScenes); | |
| 253 | +// }); | |
| 253 | 254 | } |
| 254 | 255 | |
| 255 | 256 | @Override | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAction.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.rule.action; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 3 | 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 4 | 5 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 6 | 6 | |
| 7 | 7 | import javax.annotation.Nullable; |
| 8 | 8 | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAlertAction.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.rule.action; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 3 | 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 4 | 5 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 6 | 6 | import org.springframework.stereotype.Component; |
| 7 | 7 | |
| 8 | 8 | import javax.annotation.Nullable; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneDataBridgeAction.java
| ... | ... | @@ -2,10 +2,10 @@ package cn.iocoder.yudao.module.iot.service.rule.action; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.lang.Assert; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 5 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 5 | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 6 | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 7 | 8 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; |
| 8 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 9 | 9 | import cn.iocoder.yudao.module.iot.service.rule.IotDataBridgeService; |
| 10 | 10 | import cn.iocoder.yudao.module.iot.service.rule.action.databridge.IotDataBridgeExecute; |
| 11 | 11 | import jakarta.annotation.Resource; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneDeviceControlAction.java
| ... | ... | @@ -2,10 +2,10 @@ package cn.iocoder.yudao.module.iot.service.rule.action; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.lang.Assert; |
| 4 | 4 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO; |
| 5 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 5 | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 6 | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 7 | 8 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; |
| 8 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 9 | 9 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 10 | 10 | import cn.iocoder.yudao.module.iot.service.device.control.IotDeviceDownstreamService; |
| 11 | 11 | import jakarta.annotation.Resource; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/AbstractCacheableDataBridgeExecute.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.util.ObjUtil; |
| 4 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 4 | 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 5 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 6 | 6 | import com.google.common.cache.CacheBuilder; |
| 7 | 7 | import com.google.common.cache.CacheLoader; |
| 8 | 8 | import com.google.common.cache.LoadingCache; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotDataBridgeExecute.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 3 | 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 4 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 5 | - | |
| 6 | 5 | |
| 7 | 6 | /** |
| 8 | 7 | * IoT 数据桥梁的执行器 execute 接口 | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotHttpDataBridgeExecute.java
| ... | ... | @@ -4,8 +4,8 @@ import cn.hutool.core.collection.CollUtil; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 6 | 6 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeHttpConfig; |
| 7 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 7 | 8 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 8 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 9 | 9 | import jakarta.annotation.Resource; |
| 10 | 10 | import lombok.extern.slf4j.Slf4j; |
| 11 | 11 | import org.springframework.http.*; |
| ... | ... | @@ -16,8 +16,6 @@ import org.springframework.web.util.UriComponentsBuilder; |
| 16 | 16 | import java.util.HashMap; |
| 17 | 17 | import java.util.Map; |
| 18 | 18 | |
| 19 | -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; | |
| 20 | - | |
| 21 | 19 | /** |
| 22 | 20 | * Http 的 {@link IotDataBridgeExecute} 实现类 |
| 23 | 21 | * |
| ... | ... | @@ -48,7 +46,8 @@ public class IotHttpDataBridgeExecute implements IotDataBridgeExecute<IotDataBri |
| 48 | 46 | if (CollUtil.isNotEmpty(config.getHeaders())) { |
| 49 | 47 | config.getHeaders().putAll(config.getHeaders()); |
| 50 | 48 | } |
| 51 | - headers.add(HEADER_TENANT_ID, message.getTenantId().toString()); | |
| 49 | + // TODO @puhui999:@yunai:可能需要通过设备查询到租户,然后 set | |
| 50 | +// headers.add(HEADER_TENANT_ID, message.getTenantId().toString()); | |
| 52 | 51 | // 1.2 构建 URL |
| 53 | 52 | UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(config.getUrl()); |
| 54 | 53 | if (CollUtil.isNotEmpty(config.getQuery())) { | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotKafkaMQDataBridgeExecute.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeKafkaMQConfig; |
| 4 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 4 | 5 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 6 | 6 | import lombok.extern.slf4j.Slf4j; |
| 7 | 7 | import org.apache.kafka.clients.producer.ProducerConfig; |
| 8 | 8 | import org.apache.kafka.common.serialization.StringSerializer; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotRabbitMQDataBridgeExecute.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeRabbitMQConfig; |
| 4 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 4 | 5 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 6 | 6 | import com.rabbitmq.client.Channel; |
| 7 | 7 | import com.rabbitmq.client.Connection; |
| 8 | 8 | import com.rabbitmq.client.ConnectionFactory; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotRedisStreamDataBridgeExecute.java
| ... | ... | @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.util.StrUtil; |
| 4 | 4 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeRedisStreamConfig; |
| 5 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 5 | 6 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 6 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 7 | 7 | import lombok.extern.slf4j.Slf4j; |
| 8 | 8 | import org.redisson.Redisson; |
| 9 | 9 | import org.redisson.api.RedissonClient; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotRocketMQDataBridgeExecute.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeRocketMQConfig; |
| 4 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 4 | 5 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 6 | 6 | import lombok.extern.slf4j.Slf4j; |
| 7 | 7 | import org.apache.rocketmq.client.producer.DefaultMQProducer; |
| 8 | 8 | import org.apache.rocketmq.client.producer.SendResult; | ... | ... |
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/action/databridge/IotDataBridgeExecuteTest.java
| ... | ... | @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; |
| 4 | 4 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.*; |
| 5 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 5 | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 6 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | |
| 7 | 7 | import lombok.extern.slf4j.Slf4j; |
| 8 | 8 | import org.junit.jupiter.api.BeforeEach; |
| 9 | 9 | import org.junit.jupiter.api.Disabled; |
| ... | ... | @@ -41,8 +41,8 @@ public class IotDataBridgeExecuteTest extends BaseMockitoUnitTest { |
| 41 | 41 | @BeforeEach |
| 42 | 42 | public void setUp() { |
| 43 | 43 | // 创建共享的测试消息 |
| 44 | - message = IotDeviceMessage.builder().requestId("TEST-001").reportTime(LocalDateTime.now()).tenantId(1L) | |
| 45 | - .productKey("testProduct").deviceName("testDevice").deviceKey("testDeviceKey") | |
| 44 | + message = IotDeviceMessage.builder().messageId("TEST-001").reportTime(LocalDateTime.now()) | |
| 45 | + .productKey("testProduct").deviceName("testDevice") | |
| 46 | 46 | .type("property").identifier("temperature").data("{\"value\": 60}") |
| 47 | 47 | .build(); |
| 48 | 48 | } | ... | ... |
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/enums/device/IotDeviceStateEnum.java renamed to yudao-module-iot/yudao-module-iot-core/src/main/java/cn/iocoder/yudao/module/iot/core/enums/IotDeviceStateEnum.java
yudao-module-iot/yudao-module-iot-core/src/main/java/cn/iocoder/yudao/module/iot/core/mq/message/IotDeviceMessage.java
| ... | ... | @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.iot.core.mq.message; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageIdentifierEnum; |
| 4 | 4 | import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageTypeEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.core.util.IotCoreUtils; | |
| 5 | +import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; | |
| 6 | 6 | import lombok.AllArgsConstructor; |
| 7 | 7 | import lombok.Builder; |
| 8 | 8 | import lombok.Data; |
| ... | ... | @@ -79,7 +79,7 @@ public class IotDeviceMessage { |
| 79 | 79 | private LocalDateTime reportTime; |
| 80 | 80 | |
| 81 | 81 | /** |
| 82 | - * 服务编号,该消息由哪个消息发送 | |
| 82 | + * 服务编号,该消息由哪个 server 服务进行消费 | |
| 83 | 83 | */ |
| 84 | 84 | private String serverId; |
| 85 | 85 | |
| ... | ... | @@ -97,6 +97,18 @@ public class IotDeviceMessage { |
| 97 | 97 | return this; |
| 98 | 98 | } |
| 99 | 99 | |
| 100 | + public IotDeviceMessage ofStateOnline() { | |
| 101 | + this.setType(IotDeviceMessageTypeEnum.STATE.getType()); | |
| 102 | + this.setIdentifier(IotDeviceMessageIdentifierEnum.STATE_ONLINE.getIdentifier()); | |
| 103 | + return this; | |
| 104 | + } | |
| 105 | + | |
| 106 | + public IotDeviceMessage ofStateOffline() { | |
| 107 | + this.setType(IotDeviceMessageTypeEnum.STATE.getType()); | |
| 108 | + this.setIdentifier(IotDeviceMessageIdentifierEnum.STATE_OFFLINE.getIdentifier()); | |
| 109 | + return this; | |
| 110 | + } | |
| 111 | + | |
| 100 | 112 | public static IotDeviceMessage of(String productKey, String deviceName) { |
| 101 | 113 | return of(productKey, deviceName, |
| 102 | 114 | null, null); |
| ... | ... | @@ -113,17 +125,11 @@ public class IotDeviceMessage { |
| 113 | 125 | if (reportTime == null) { |
| 114 | 126 | reportTime = LocalDateTime.now(); |
| 115 | 127 | } |
| 116 | - String messageId = IotCoreUtils.generateMessageId(); | |
| 128 | + String messageId = IotDeviceMessageUtils.generateMessageId(); | |
| 117 | 129 | return IotDeviceMessage.builder() |
| 118 | 130 | .messageId(messageId).reportTime(reportTime) |
| 119 | 131 | .productKey(productKey).deviceName(deviceName) |
| 120 | 132 | .serverId(serverId).build(); |
| 121 | 133 | } |
| 122 | 134 | |
| 123 | - // ========== Topic 相关 ========== | |
| 124 | - | |
| 125 | - public static String buildMessageBusGatewayDeviceMessageTopic(String serverId) { | |
| 126 | - return String.format(MESSAGE_BUS_GATEWAY_DEVICE_MESSAGE_TOPIC, serverId); | |
| 127 | - } | |
| 128 | - | |
| 129 | 135 | } | ... | ... |
yudao-module-iot/yudao-module-iot-core/src/main/java/cn/iocoder/yudao/module/iot/core/mq/producer/IotDeviceMessageProducer.java
| ... | ... | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.iot.core.mq.producer; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus; |
| 4 | 4 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; |
| 5 | +import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; | |
| 5 | 6 | import lombok.RequiredArgsConstructor; |
| 6 | 7 | |
| 7 | 8 | /** |
| ... | ... | @@ -30,7 +31,7 @@ public class IotDeviceMessageProducer { |
| 30 | 31 | * @param message 设备消息 |
| 31 | 32 | */ |
| 32 | 33 | public void sendGatewayDeviceMessage(String serverId, Object message) { |
| 33 | - messageBus.post(IotDeviceMessage.buildMessageBusGatewayDeviceMessageTopic(serverId), message); | |
| 34 | + messageBus.post(IotDeviceMessageUtils.buildMessageBusGatewayDeviceMessageTopic(serverId), message); | |
| 34 | 35 | } |
| 35 | 36 | |
| 36 | 37 | } | ... | ... |
yudao-module-iot/yudao-module-iot-core/src/main/java/cn/iocoder/yudao/module/iot/core/util/IotCoreUtils.java renamed to yudao-module-iot/yudao-module-iot-core/src/main/java/cn/iocoder/yudao/module/iot/core/util/IotDeviceMessageUtils.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.core.util; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.util.IdUtil; |
| 4 | +import cn.hutool.core.util.StrUtil; | |
| 4 | 5 | import cn.hutool.system.SystemUtil; |
| 6 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | |
| 5 | 7 | |
| 6 | 8 | /** |
| 7 | - * IoT 核心模块的工具类 | |
| 9 | + * IoT 设备消息的工具类 | |
| 8 | 10 | * |
| 9 | 11 | * @author 芋道源码 |
| 10 | 12 | */ |
| 11 | -public class IotCoreUtils { | |
| 13 | +public class IotDeviceMessageUtils { | |
| 14 | + | |
| 15 | + // ========== Message 相关 ========== | |
| 16 | + | |
| 17 | + public static String generateMessageId() { | |
| 18 | + return IdUtil.fastSimpleUUID(); | |
| 19 | + } | |
| 20 | + | |
| 21 | + /** | |
| 22 | + * 是否是上行消息:由设备发送 | |
| 23 | + * | |
| 24 | + * @param message 消息 | |
| 25 | + * @return 是否 | |
| 26 | + */ | |
| 27 | + public static boolean isUpstreamMessage(IotDeviceMessage message) { | |
| 28 | + return StrUtil.isNotEmpty(message.getServerId()); | |
| 29 | + } | |
| 30 | + | |
| 31 | + // ========== Topic 相关 ========== | |
| 32 | + | |
| 33 | + public static String buildMessageBusGatewayDeviceMessageTopic(String serverId) { | |
| 34 | + return String.format(IotDeviceMessage.MESSAGE_BUS_GATEWAY_DEVICE_MESSAGE_TOPIC, serverId); | |
| 35 | + } | |
| 12 | 36 | |
| 13 | 37 | /** |
| 14 | 38 | * 生成服务器编号 |
| ... | ... | @@ -22,8 +46,4 @@ public class IotCoreUtils { |
| 22 | 46 | return serverId.replaceAll("\\.", "_"); |
| 23 | 47 | } |
| 24 | 48 | |
| 25 | - public static String generateMessageId() { | |
| 26 | - return IdUtil.fastSimpleUUID(); | |
| 27 | - } | |
| 28 | - | |
| 29 | 49 | } |
| 30 | 50 | \ No newline at end of file | ... | ... |
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/IotHttpDownstreamSubscriber.java
| ... | ... | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iot.gateway.protocol.http; |
| 3 | 3 | import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus; |
| 4 | 4 | import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageSubscriber; |
| 5 | 5 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; |
| 6 | +import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; | |
| 6 | 7 | import jakarta.annotation.PostConstruct; |
| 7 | 8 | import lombok.RequiredArgsConstructor; |
| 8 | 9 | import lombok.extern.slf4j.Slf4j; |
| ... | ... | @@ -27,7 +28,7 @@ public class IotHttpDownstreamSubscriber implements IotMessageSubscriber<IotDevi |
| 27 | 28 | |
| 28 | 29 | @Override |
| 29 | 30 | public String getTopic() { |
| 30 | - return IotDeviceMessage.buildMessageBusGatewayDeviceMessageTopic(protocol.getServerId()); | |
| 31 | + return IotDeviceMessageUtils.buildMessageBusGatewayDeviceMessageTopic(protocol.getServerId()); | |
| 31 | 32 | } |
| 32 | 33 | |
| 33 | 34 | @Override | ... | ... |
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/IotHttpUpstreamProtocol.java
| 1 | 1 | package cn.iocoder.yudao.module.iot.gateway.protocol.http; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; |
| 4 | -import cn.iocoder.yudao.module.iot.core.util.IotCoreUtils; | |
| 4 | +import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; | |
| 5 | 5 | import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties; |
| 6 | 6 | import cn.iocoder.yudao.module.iot.gateway.protocol.http.router.IotHttpUpstreamHandler; |
| 7 | 7 | import io.vertx.core.AbstractVerticle; |
| ... | ... | @@ -70,7 +70,7 @@ public class IotHttpUpstreamProtocol extends AbstractVerticle { |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | 72 | public String getServerId() { |
| 73 | - return IotCoreUtils.generateServerId(httpProperties.getServerPort()); | |
| 73 | + return IotDeviceMessageUtils.generateServerId(httpProperties.getServerPort()); | |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | 76 | } | ... | ... |
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-core/src/main/java/cn/iocoder/yudao/module/iot/net/component/core/upstream/IotDeviceUpstreamClient.java
| ... | ... | @@ -19,38 +19,8 @@ public class IotDeviceUpstreamClient implements IotDeviceUpstreamApi { |
| 19 | 19 | private IotDeviceUpstreamApi deviceUpstreamApi; |
| 20 | 20 | |
| 21 | 21 | @Override |
| 22 | - public CommonResult<Boolean> updateDeviceState(IotDeviceStateUpdateReqDTO updateReqDTO) { | |
| 23 | - return deviceUpstreamApi.updateDeviceState(updateReqDTO); | |
| 24 | - } | |
| 25 | - | |
| 26 | - @Override | |
| 27 | - public CommonResult<Boolean> reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO) { | |
| 28 | - return deviceUpstreamApi.reportDeviceEvent(reportReqDTO); | |
| 29 | - } | |
| 30 | - | |
| 31 | - @Override | |
| 32 | - public CommonResult<Boolean> registerDevice(IotDeviceRegisterReqDTO registerReqDTO) { | |
| 33 | - return deviceUpstreamApi.registerDevice(registerReqDTO); | |
| 34 | - } | |
| 35 | - | |
| 36 | - @Override | |
| 37 | - public CommonResult<Boolean> registerSubDevice(IotDeviceRegisterSubReqDTO registerReqDTO) { | |
| 38 | - return deviceUpstreamApi.registerSubDevice(registerReqDTO); | |
| 39 | - } | |
| 40 | - | |
| 41 | - @Override | |
| 42 | - public CommonResult<Boolean> addDeviceTopology(IotDeviceTopologyAddReqDTO addReqDTO) { | |
| 43 | - return deviceUpstreamApi.addDeviceTopology(addReqDTO); | |
| 44 | - } | |
| 45 | - | |
| 46 | - @Override | |
| 47 | 22 | public CommonResult<Boolean> authenticateEmqxConnection(IotDeviceEmqxAuthReqDTO authReqDTO) { |
| 48 | 23 | return deviceUpstreamApi.authenticateEmqxConnection(authReqDTO); |
| 49 | 24 | } |
| 50 | 25 | |
| 51 | - @Override | |
| 52 | - public CommonResult<Boolean> reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO) { | |
| 53 | - return deviceUpstreamApi.reportDeviceProperty(reportReqDTO); | |
| 54 | - } | |
| 55 | - | |
| 56 | 26 | } | ... | ... |
yudao-module-iot/yudao-module-iot-net-components/yudao-module-iot-net-component-emqx/src/main/java/cn/iocoder/yudao/module/iot/net/component/emqx/upstream/router/IotDeviceWebhookVertxHandler.java
| ... | ... | @@ -4,7 +4,7 @@ import cn.hutool.core.util.StrUtil; |
| 4 | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | 5 | import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; |
| 6 | 6 | import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceStateUpdateReqDTO; |
| 7 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | |
| 7 | +import cn.iocoder.yudao.module.iot.core.enums.IotDeviceStateEnum; | |
| 8 | 8 | import cn.iocoder.yudao.module.iot.net.component.core.util.IotNetComponentCommonUtils; |
| 9 | 9 | import io.vertx.core.Handler; |
| 10 | 10 | import io.vertx.core.json.JsonObject; | ... | ... |