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,59 +18,6 @@ public interface IotDeviceUpstreamApi { | ||
| 18 | 18 | ||
| 19 | String PREFIX = ApiConstants.PREFIX + "/device/upstream"; | 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 | // TODO @芋艿:考虑 http 认证 | 21 | // TODO @芋艿:考虑 http 认证 |
| 75 | /** | 22 | /** |
| 76 | * 认证 Emqx 连接 | 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,7 +30,7 @@ public interface ErrorCodeConstants { | ||
| 30 | ErrorCode DEVICE_GATEWAY_NOT_EXISTS = new ErrorCode(1_050_003_004, "网关设备不存在"); | 30 | ErrorCode DEVICE_GATEWAY_NOT_EXISTS = new ErrorCode(1_050_003_004, "网关设备不存在"); |
| 31 | ErrorCode DEVICE_NOT_GATEWAY = new ErrorCode(1_050_003_005, "设备不是网关设备"); | 31 | ErrorCode DEVICE_NOT_GATEWAY = new ErrorCode(1_050_003_005, "设备不是网关设备"); |
| 32 | ErrorCode DEVICE_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_050_003_006, "导入设备数据不能为空!"); | 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 | // ========== 产品分类 1-050-004-000 ========== | 35 | // ========== 产品分类 1-050-004-000 ========== |
| 36 | ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_050_004_000, "产品分类不存在"); | 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,44 +21,6 @@ public class IoTDeviceUpstreamApiImpl implements IotDeviceUpstreamApi { | ||
| 21 | @Resource | 21 | @Resource |
| 22 | private IotDeviceUpstreamService deviceUpstreamService; | 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 | @Override | 24 | @Override |
| 63 | public CommonResult<Boolean> authenticateEmqxConnection(IotDeviceEmqxAuthReqDTO authReqDTO) { | 25 | public CommonResult<Boolean> authenticateEmqxConnection(IotDeviceEmqxAuthReqDTO authReqDTO) { |
| 64 | boolean result = deviceUpstreamService.authenticateEmqxConnection(authReqDTO); | 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,7 +2,7 @@ package cn.iocoder.yudao.module.iot.controller.admin.device.vo.device; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 4 | import cn.iocoder.yudao.framework.common.validation.InEnum; | 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 | import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum; | 6 | import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum; |
| 7 | import io.swagger.v3.oas.annotations.media.Schema; | 7 | import io.swagger.v3.oas.annotations.media.Schema; |
| 8 | import lombok.Data; | 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,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageSummaryRespVO; | 4 | import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsDeviceMessageSummaryRespVO; |
| 5 | import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsReqVO; | 5 | import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsReqVO; |
| 6 | import cn.iocoder.yudao.module.iot.controller.admin.statistics.vo.IotStatisticsSummaryRespVO; | 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 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | 8 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 9 | import cn.iocoder.yudao.module.iot.service.device.data.IotDeviceLogService; | 9 | import cn.iocoder.yudao.module.iot.service.device.data.IotDeviceLogService; |
| 10 | import cn.iocoder.yudao.module.iot.service.product.IotProductCategoryService; | 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,7 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.type.LongSetTypeHandler; | ||
| 4 | import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; | 4 | import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; |
| 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO; | 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.ota.IotOtaFirmwareDO; |
| 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | 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 | import com.baomidou.mybatisplus.annotation.KeySequence; | 8 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 9 | import com.baomidou.mybatisplus.annotation.TableField; | 9 | import com.baomidou.mybatisplus.annotation.TableField; |
| 10 | import com.baomidou.mybatisplus.annotation.TableId; | 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 | package cn.iocoder.yudao.module.iot.dal.dataobject.rule; | 1 | package cn.iocoder.yudao.module.iot.dal.dataobject.rule; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | ||
| 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 6 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 7 | import com.baomidou.mybatisplus.annotation.KeySequence; | 7 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 8 | import com.baomidou.mybatisplus.annotation.TableField; | 8 | import com.baomidou.mybatisplus.annotation.TableField; |
| 9 | import com.baomidou.mybatisplus.annotation.TableName; | 9 | import com.baomidou.mybatisplus.annotation.TableName; |
| 10 | import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | 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 | * IoT 告警记录 DO | 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,7 +145,7 @@ public class IotRuleSceneDO extends TenantBaseDO { | ||
| 145 | public static class TriggerConditionParameter { | 145 | public static class TriggerConditionParameter { |
| 146 | 146 | ||
| 147 | // TODO @芋艿: identifier0 存事件和服务的 identifier 属性的情况 identifier0 就为 null 解决前端回显问题 | 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,11 +19,10 @@ public interface RedisKeyConstants { | ||
| 19 | */ | 19 | */ |
| 20 | String DEVICE_PROPERTY = "iot:device_property:%s"; | 20 | String DEVICE_PROPERTY = "iot:device_property:%s"; |
| 21 | 21 | ||
| 22 | - // TODO @芋艿:弱化 deviceKey;使用 product_key + device_name 替代 | ||
| 23 | /** | 22 | /** |
| 24 | * 设备的最后上报时间,采用 ZSET 结构 | 23 | * 设备的最后上报时间,采用 ZSET 结构 |
| 25 | * | 24 | * |
| 26 | - * KEY 格式:{deviceKey} | 25 | + * KEY 格式:{productKey},${deviceName} |
| 27 | * SCORE:上报时间 | 26 | * SCORE:上报时间 |
| 28 | */ | 27 | */ |
| 29 | String DEVICE_REPORT_TIMES = "iot:device_report_times"; | 28 | String DEVICE_REPORT_TIMES = "iot:device_report_times"; |
| @@ -44,4 +43,13 @@ public interface RedisKeyConstants { | @@ -44,4 +43,13 @@ public interface RedisKeyConstants { | ||
| 44 | */ | 43 | */ |
| 45 | String THING_MODEL_LIST = "iot:thing_model_list"; | 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 | package cn.iocoder.yudao.module.iot.dal.redis.device; | 1 | package cn.iocoder.yudao.module.iot.dal.redis.device; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.date.LocalDateTimeUtil; | 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 | import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants; | 6 | import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants; |
| 5 | import jakarta.annotation.Resource; | 7 | import jakarta.annotation.Resource; |
| 6 | import org.springframework.data.redis.core.StringRedisTemplate; | 8 | import org.springframework.data.redis.core.StringRedisTemplate; |
| @@ -20,14 +22,17 @@ public class DeviceReportTimeRedisDAO { | @@ -20,14 +22,17 @@ public class DeviceReportTimeRedisDAO { | ||
| 20 | @Resource | 22 | @Resource |
| 21 | private StringRedisTemplate stringRedisTemplate; | 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 | LocalDateTimeUtil.toEpochMilli(reportTime)); | 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 | LocalDateTimeUtil.toEpochMilli(maxReportTime)); | 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 | \ No newline at end of file | 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 | package cn.iocoder.yudao.module.iot.job.device; | 1 | package cn.iocoder.yudao.module.iot.job.device; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | -import cn.hutool.core.util.IdUtil; | 4 | +import cn.hutool.core.util.StrUtil; |
| 5 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 5 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 6 | import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; | 6 | import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; |
| 7 | import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 11 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 10 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | ||
| 11 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | 12 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 12 | import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; | 13 | import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; |
| 13 | -import cn.iocoder.yudao.module.iot.service.device.control.IotDeviceUpstreamService; | ||
| 14 | import jakarta.annotation.Resource; | 14 | import jakarta.annotation.Resource; |
| 15 | import org.springframework.stereotype.Component; | 15 | import org.springframework.stereotype.Component; |
| 16 | 16 | ||
| @@ -20,10 +20,12 @@ import java.util.Collections; | @@ -20,10 +20,12 @@ import java.util.Collections; | ||
| 20 | import java.util.List; | 20 | import java.util.List; |
| 21 | import java.util.Set; | 21 | import java.util.Set; |
| 22 | 22 | ||
| 23 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | ||
| 24 | + | ||
| 23 | /** | 25 | /** |
| 24 | * IoT 设备离线检查 Job | 26 | * IoT 设备离线检查 Job |
| 25 | * | 27 | * |
| 26 | - * 检测逻辑:设备最后一条 {@link cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage} 消息超过一定时间,则认为设备离线 | 28 | + * 检测逻辑:设备最后一条 {@link IotDeviceMessage} 消息超过一定时间,则认为设备离线 |
| 27 | * | 29 | * |
| 28 | * @author 芋道源码 | 30 | * @author 芋道源码 |
| 29 | */ | 31 | */ |
| @@ -41,8 +43,9 @@ public class IotDeviceOfflineCheckJob implements JobHandler { | @@ -41,8 +43,9 @@ public class IotDeviceOfflineCheckJob implements JobHandler { | ||
| 41 | private IotDeviceService deviceService; | 43 | private IotDeviceService deviceService; |
| 42 | @Resource | 44 | @Resource |
| 43 | private IotDevicePropertyService devicePropertyService; | 45 | private IotDevicePropertyService devicePropertyService; |
| 46 | + | ||
| 44 | @Resource | 47 | @Resource |
| 45 | - private IotDeviceUpstreamService deviceUpstreamService; | 48 | + private IotDeviceMessageProducer deviceMessageProducer; |
| 46 | 49 | ||
| 47 | @Override | 50 | @Override |
| 48 | @TenantJob | 51 | @TenantJob |
| @@ -52,22 +55,22 @@ public class IotDeviceOfflineCheckJob implements JobHandler { | @@ -52,22 +55,22 @@ public class IotDeviceOfflineCheckJob implements JobHandler { | ||
| 52 | if (CollUtil.isEmpty(devices)) { | 55 | if (CollUtil.isEmpty(devices)) { |
| 53 | return JsonUtils.toJsonString(Collections.emptyList()); | 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 | LocalDateTime.now().minus(OFFLINE_TIMEOUT)); | 60 | LocalDateTime.now().minus(OFFLINE_TIMEOUT)); |
| 61 | + Set<String> timeoutDevices2 = convertSet(timeoutDevices, item -> item[0] + StrUtil.COMMA + item[1]); | ||
| 58 | 62 | ||
| 59 | // 2. 下线设备 | 63 | // 2. 下线设备 |
| 60 | - List<String> offlineDeviceKeys = CollUtil.newArrayList(); | 64 | + List<String[]> offlineDeviceKeys = CollUtil.newArrayList(); |
| 61 | for (IotDeviceDO device : devices) { | 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 | continue; | 68 | continue; |
| 64 | } | 69 | } |
| 65 | - offlineDeviceKeys.add(device.getDeviceKey()); | 70 | + offlineDeviceKeys.add(new String[]{device.getProductKey(), device.getDeviceName()}); |
| 66 | // 为什么不直接更新状态呢?因为通过 IotDeviceMessage 可以经过一系列的处理,例如说记录日志等等 | 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 | return JsonUtils.toJsonString(offlineDeviceKeys); | 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
| @@ -10,7 +10,7 @@ import lombok.extern.slf4j.Slf4j; | @@ -10,7 +10,7 @@ import lombok.extern.slf4j.Slf4j; | ||
| 10 | import org.springframework.stereotype.Component; | 10 | import org.springframework.stereotype.Component; |
| 11 | 11 | ||
| 12 | /** | 12 | /** |
| 13 | - * 针对 {@link IotDeviceMessage} 的消费者,记录设备日志 | 13 | + * 针对 {@link IotDeviceMessage} 的消费者:记录设备日志 |
| 14 | * | 14 | * |
| 15 | * @author 芋道源码 | 15 | * @author 芋道源码 |
| 16 | */ | 16 | */ |
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 | \ No newline at end of file | 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 | package cn.iocoder.yudao.module.iot.mq.consumer.device; | 1 | package cn.iocoder.yudao.module.iot.mq.consumer.device; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.ObjectUtil; | 3 | import cn.hutool.core.util.ObjectUtil; |
| 4 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | ||
| 4 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; | 5 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; |
| 5 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; | 6 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; |
| 6 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 7 | import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; | 7 | import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; |
| 8 | import lombok.extern.slf4j.Slf4j; | 8 | import lombok.extern.slf4j.Slf4j; |
| 9 | import org.springframework.context.event.EventListener; | 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 | \ No newline at end of file | 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 | package cn.iocoder.yudao.module.iot.mq.consumer.rule; | 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 | import cn.iocoder.yudao.module.iot.service.rule.IotRuleSceneService; | 4 | import cn.iocoder.yudao.module.iot.service.rule.IotRuleSceneService; |
| 5 | import jakarta.annotation.Resource; | 5 | import jakarta.annotation.Resource; |
| 6 | import lombok.extern.slf4j.Slf4j; | 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,7 +3,7 @@ package cn.iocoder.yudao.module.iot.service.device; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*; | 4 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.device.*; |
| 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 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 | import jakarta.validation.Valid; | 7 | import jakarta.validation.Valid; |
| 8 | import jakarta.validation.constraints.NotEmpty; | 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,7 +17,7 @@ import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceGroupDO; | ||
| 17 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | 17 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 18 | import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper; | 18 | import cn.iocoder.yudao.module.iot.dal.mysql.device.IotDeviceMapper; |
| 19 | import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants; | 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 | import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum; | 21 | import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum; |
| 22 | import cn.iocoder.yudao.module.iot.service.product.IotProductService; | 22 | import cn.iocoder.yudao.module.iot.service.product.IotProductService; |
| 23 | import cn.iocoder.yudao.module.iot.util.MqttSignUtils; | 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 | package cn.iocoder.yudao.module.iot.service.device.control; | 1 | package cn.iocoder.yudao.module.iot.service.device.control; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO; | 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 | import jakarta.validation.Valid; | 5 | import jakarta.validation.Valid; |
| 6 | 6 | ||
| 7 | /** | 7 | /** |
| 8 | * IoT 设备下行 Service 接口 | 8 | * IoT 设备下行 Service 接口 |
| 9 | * | 9 | * |
| 10 | - * 目的:服务端 -> 插件 -> 设备 | 10 | + * 目的:服务端 -> 网关 -> 设备 |
| 11 | * | 11 | * |
| 12 | * @author 芋道源码 | 12 | * @author 芋道源码 |
| 13 | */ | 13 | */ |
| @@ -17,7 +17,7 @@ public interface IotDeviceDownstreamService { | @@ -17,7 +17,7 @@ public interface IotDeviceDownstreamService { | ||
| 17 | * 设备下行,可用于设备模拟 | 17 | * 设备下行,可用于设备模拟 |
| 18 | * | 18 | * |
| 19 | * @param downstreamReqVO 设备下行请求 VO | 19 | * @param downstreamReqVO 设备下行请求 VO |
| 20 | - * @return 下发消息 | 20 | + * @return 下行消息 |
| 21 | */ | 21 | */ |
| 22 | IotDeviceMessage downstreamDevice(@Valid IotDeviceDownstreamReqVO downstreamReqVO); | 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 | package cn.iocoder.yudao.module.iot.service.device.control; | 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 | import cn.iocoder.yudao.framework.common.exception.ServiceException; | 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 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO; | 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 | import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; | 7 | import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; |
| 13 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 8 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 14 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; | 9 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; |
| 15 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; | 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 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | 11 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 12 | +import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; | ||
| 19 | import jakarta.annotation.Resource; | 13 | import jakarta.annotation.Resource; |
| 20 | import lombok.extern.slf4j.Slf4j; | 14 | import lombok.extern.slf4j.Slf4j; |
| 21 | import org.springframework.stereotype.Service; | 15 | import org.springframework.stereotype.Service; |
| 22 | import org.springframework.validation.annotation.Validated; | 16 | import org.springframework.validation.annotation.Validated; |
| 23 | 17 | ||
| 24 | -import java.time.LocalDateTime; | ||
| 25 | -import java.util.List; | ||
| 26 | import java.util.Map; | 18 | import java.util.Map; |
| 27 | import java.util.Objects; | 19 | import java.util.Objects; |
| 28 | 20 | ||
| 29 | import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; | 21 | import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; |
| 30 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 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 | * IoT 设备下行 Service 实现类 | 26 | * IoT 设备下行 Service 实现类 |
| @@ -42,255 +34,234 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | @@ -42,255 +34,234 @@ public class IotDeviceDownstreamServiceImpl implements IotDeviceDownstreamServic | ||
| 42 | 34 | ||
| 43 | @Resource | 35 | @Resource |
| 44 | private IotDeviceService deviceService; | 36 | private IotDeviceService deviceService; |
| 45 | - | ||
| 46 | @Resource | 37 | @Resource |
| 47 | - private IotDeviceProducer deviceProducer; | 38 | + private IotDevicePropertyService devicePropertyService; |
| 39 | + | ||
| 48 | @Resource | 40 | @Resource |
| 49 | private IotDeviceMessageProducer deviceMessageProducer; | 41 | private IotDeviceMessageProducer deviceMessageProducer; |
| 50 | 42 | ||
| 51 | @Override | 43 | @Override |
| 52 | public IotDeviceMessage downstreamDevice(IotDeviceDownstreamReqVO downstreamReqVO) { | 44 | public IotDeviceMessage downstreamDevice(IotDeviceDownstreamReqVO downstreamReqVO) { |
| 53 | - // 校验设备是否存在 | 45 | + // 1. 校验设备是否存在 |
| 54 | IotDeviceDO device = deviceService.validateDeviceExists(downstreamReqVO.getId()); | 46 | IotDeviceDO device = deviceService.validateDeviceExists(downstreamReqVO.getId()); |
| 55 | - // TODO @芋艿:离线设备,不允许推送 | ||
| 56 | // TODO 芋艿:父设备的处理 | 47 | // TODO 芋艿:父设备的处理 |
| 57 | IotDeviceDO parentDevice = null; | 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 | if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.SERVICE.getType())) { | 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 | if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.PROPERTY.getType())) { | 76 | if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.PROPERTY.getType())) { |
| 65 | // 属性设置 | 77 | // 属性设置 |
| 66 | if (Objects.equals(downstreamReqVO.getIdentifier(), | 78 | if (Objects.equals(downstreamReqVO.getIdentifier(), |
| 67 | IotDeviceMessageIdentifierEnum.PROPERTY_SET.getIdentifier())) { | 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 | if (Objects.equals(downstreamReqVO.getIdentifier(), | 86 | if (Objects.equals(downstreamReqVO.getIdentifier(), |
| 72 | IotDeviceMessageIdentifierEnum.PROPERTY_GET.getIdentifier())) { | 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 | if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.CONFIG.getType()) | 93 | if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.CONFIG.getType()) |
| 78 | && Objects.equals(downstreamReqVO.getIdentifier(), | 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 | // OTA 升级 | 99 | // OTA 升级 |
| 83 | if (Objects.equals(downstreamReqVO.getType(), IotDeviceMessageTypeEnum.OTA.getType())) { | 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 | // TODO @芋艿:取消设备的网关的时,要不要下发 REGISTER_UNREGISTER_SUB ? | 104 | // TODO @芋艿:取消设备的网关的时,要不要下发 REGISTER_UNREGISTER_SUB ? |
| 87 | throw new IllegalArgumentException("不支持的下行消息类型:" + downstreamReqVO); | 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 | private String getDeviceName(IotDeviceDO device, IotDeviceDO parentDevice) { | 266 | private String getDeviceName(IotDeviceDO device, IotDeviceDO parentDevice) { |
| 296 | return parentDevice != null ? parentDevice.getDeviceName() : device.getDeviceName(); | 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 +7,7 @@ import jakarta.validation.Valid; | ||
| 7 | /** | 7 | /** |
| 8 | * IoT 设备上行 Service 接口 | 8 | * IoT 设备上行 Service 接口 |
| 9 | * | 9 | * |
| 10 | - * 目的:设备 -> 插件 -> 服务端 | 10 | + * 目的:设备 -> 网关 -> 服务端 |
| 11 | * | 11 | * |
| 12 | * @author 芋道源码 | 12 | * @author 芋道源码 |
| 13 | */ | 13 | */ |
| @@ -20,47 +20,33 @@ public interface IotDeviceUpstreamService { | @@ -20,47 +20,33 @@ public interface IotDeviceUpstreamService { | ||
| 20 | */ | 20 | */ |
| 21 | void upstreamDevice(@Valid IotDeviceUpstreamReqVO simulatorReqVO); | 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 | * Emqx 连接认证 | 52 | * Emqx 连接认证 |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceUpstreamServiceImpl.java
| 1 | package cn.iocoder.yudao.module.iot.service.device.control; | 1 | package cn.iocoder.yudao.module.iot.service.device.control; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | -import cn.hutool.core.lang.Assert; | ||
| 5 | import cn.hutool.core.util.IdUtil; | 4 | import cn.hutool.core.util.IdUtil; |
| 6 | import cn.hutool.core.util.ObjUtil; | 5 | import cn.hutool.core.util.ObjUtil; |
| 7 | import cn.hutool.core.util.StrUtil; | 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 | import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; | 7 | import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; |
| 11 | import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.*; | 8 | import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.*; |
| 12 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceUpstreamReqVO; | 9 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceUpstreamReqVO; |
| 13 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 10 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 14 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; | ||
| 15 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; | 11 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageTypeEnum; |
| 16 | -import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum; | ||
| 17 | import cn.iocoder.yudao.module.iot.enums.product.IotProductDeviceTypeEnum; | 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 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | 13 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 21 | import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; | 14 | import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService; |
| 22 | import cn.iocoder.yudao.module.iot.util.MqttSignUtils; | 15 | import cn.iocoder.yudao.module.iot.util.MqttSignUtils; |
| @@ -45,9 +38,7 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | @@ -45,9 +38,7 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | ||
| 45 | @Resource | 38 | @Resource |
| 46 | private IotDevicePropertyService devicePropertyService; | 39 | private IotDevicePropertyService devicePropertyService; |
| 47 | 40 | ||
| 48 | - @Resource | ||
| 49 | - private IotDeviceProducer deviceProducer; | ||
| 50 | - | 41 | + // TODO @芋艿:需要重新实现下; |
| 51 | @Override | 42 | @Override |
| 52 | @SuppressWarnings("unchecked") | 43 | @SuppressWarnings("unchecked") |
| 53 | public void upstreamDevice(IotDeviceUpstreamReqVO simulatorReqVO) { | 44 | public void upstreamDevice(IotDeviceUpstreamReqVO simulatorReqVO) { |
| @@ -74,53 +65,13 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | @@ -74,53 +65,13 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | ||
| 74 | } | 65 | } |
| 75 | // 2.3 情况三:状态变更 | 66 | // 2.3 情况三:状态变更 |
| 76 | if (Objects.equals(simulatorReqVO.getType(), IotDeviceMessageTypeEnum.STATE.getType())) { | 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 | return; | 69 | return; |
| 82 | } | 70 | } |
| 83 | throw new IllegalArgumentException("未知的类型:" + simulatorReqVO.getType()); | 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 | public void reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO) { | 75 | public void reportDeviceProperty(IotDevicePropertyReportReqDTO reportReqDTO) { |
| 125 | // 1.1 获得设备 | 76 | // 1.1 获得设备 |
| 126 | log.info("[reportDeviceProperty][上报设备属性: {}]", reportReqDTO); | 77 | log.info("[reportDeviceProperty][上报设备属性: {}]", reportReqDTO); |
| @@ -131,18 +82,16 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | @@ -131,18 +82,16 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | ||
| 131 | reportReqDTO.getProductKey(), reportReqDTO.getDeviceName()); | 82 | reportReqDTO.getProductKey(), reportReqDTO.getDeviceName()); |
| 132 | return; | 83 | return; |
| 133 | } | 84 | } |
| 134 | - // 1.2 记录设备的最后时间 | ||
| 135 | - updateDeviceLastTime(device, reportReqDTO); | ||
| 136 | 85 | ||
| 137 | // 2. 发送设备消息 | 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 | public void reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO) { | 95 | public void reportDeviceEvent(IotDeviceEventReportReqDTO reportReqDTO) { |
| 147 | // 1.1 获得设备 | 96 | // 1.1 获得设备 |
| 148 | log.info("[reportDeviceEvent][上报设备事件: {}]", reportReqDTO); | 97 | log.info("[reportDeviceEvent][上报设备事件: {}]", reportReqDTO); |
| @@ -153,18 +102,16 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | @@ -153,18 +102,16 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | ||
| 153 | reportReqDTO.getProductKey(), reportReqDTO.getDeviceName()); | 102 | reportReqDTO.getProductKey(), reportReqDTO.getDeviceName()); |
| 154 | return; | 103 | return; |
| 155 | } | 104 | } |
| 156 | - // 1.2 记录设备的最后时间 | ||
| 157 | - updateDeviceLastTime(device, reportReqDTO); | ||
| 158 | 105 | ||
| 159 | // 2. 发送设备消息 | 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 | public void registerDevice(IotDeviceRegisterReqDTO registerReqDTO) { | 115 | public void registerDevice(IotDeviceRegisterReqDTO registerReqDTO) { |
| 169 | log.info("[registerDevice][注册设备: {}]", registerReqDTO); | 116 | log.info("[registerDevice][注册设备: {}]", registerReqDTO); |
| 170 | registerDevice0(registerReqDTO.getProductKey(), registerReqDTO.getDeviceName(), null, registerReqDTO); | 117 | registerDevice0(registerReqDTO.getProductKey(), registerReqDTO.getDeviceName(), null, registerReqDTO); |
| @@ -186,18 +133,18 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | @@ -186,18 +133,18 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | ||
| 186 | registerReqDTO, productKey, device, gatewayId); | 133 | registerReqDTO, productKey, device, gatewayId); |
| 187 | } | 134 | } |
| 188 | // 1.2 记录设备的最后时间 | 135 | // 1.2 记录设备的最后时间 |
| 189 | - updateDeviceLastTime(device, registerReqDTO); | 136 | +// updateDeviceLastTime(device, registerReqDTO); |
| 190 | 137 | ||
| 191 | // 2. 发送设备消息 | 138 | // 2. 发送设备消息 |
| 192 | if (registerNew) { | 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 | public void registerSubDevice(IotDeviceRegisterSubReqDTO registerReqDTO) { | 148 | public void registerSubDevice(IotDeviceRegisterSubReqDTO registerReqDTO) { |
| 202 | // 1.1 注册子设备 | 149 | // 1.1 注册子设备 |
| 203 | log.info("[registerSubDevice][注册子设备: {}]", registerReqDTO); | 150 | log.info("[registerSubDevice][注册子设备: {}]", registerReqDTO); |
| @@ -214,7 +161,7 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | @@ -214,7 +161,7 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | ||
| 214 | return; | 161 | return; |
| 215 | } | 162 | } |
| 216 | // 1.2 记录设备的最后时间 | 163 | // 1.2 记录设备的最后时间 |
| 217 | - updateDeviceLastTime(device, registerReqDTO); | 164 | +// updateDeviceLastTime(device, registerReqDTO); |
| 218 | 165 | ||
| 219 | // 2. 处理子设备 | 166 | // 2. 处理子设备 |
| 220 | if (CollUtil.isNotEmpty(registerReqDTO.getParams())) { | 167 | if (CollUtil.isNotEmpty(registerReqDTO.getParams())) { |
| @@ -224,14 +171,14 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | @@ -224,14 +171,14 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | ||
| 224 | } | 171 | } |
| 225 | 172 | ||
| 226 | // 3. 发送设备消息 | 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 | public void addDeviceTopology(IotDeviceTopologyAddReqDTO addReqDTO) { | 182 | public void addDeviceTopology(IotDeviceTopologyAddReqDTO addReqDTO) { |
| 236 | // 1.1 获得设备 | 183 | // 1.1 获得设备 |
| 237 | log.info("[addDeviceTopology][添加设备拓扑: {}]", addReqDTO); | 184 | log.info("[addDeviceTopology][添加设备拓扑: {}]", addReqDTO); |
| @@ -247,8 +194,6 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | @@ -247,8 +194,6 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | ||
| 247 | addReqDTO.getProductKey(), addReqDTO.getDeviceName(), device); | 194 | addReqDTO.getProductKey(), addReqDTO.getDeviceName(), device); |
| 248 | return; | 195 | return; |
| 249 | } | 196 | } |
| 250 | - // 1.2 记录设备的最后时间 | ||
| 251 | - updateDeviceLastTime(device, addReqDTO); | ||
| 252 | 197 | ||
| 253 | // 2. 处理拓扑 | 198 | // 2. 处理拓扑 |
| 254 | if (CollUtil.isNotEmpty(addReqDTO.getParams())) { | 199 | if (CollUtil.isNotEmpty(addReqDTO.getParams())) { |
| @@ -270,11 +215,11 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | @@ -270,11 +215,11 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | ||
| 270 | } | 215 | } |
| 271 | 216 | ||
| 272 | // 3. 发送设备消息 | 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 | // TODO @芋艿:后续需要考虑,http 的认证 | 225 | // TODO @芋艿:后续需要考虑,http 的认证 |
| @@ -310,33 +255,4 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | @@ -310,33 +255,4 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService { | ||
| 310 | return false; | 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,8 +3,8 @@ package cn.iocoder.yudao.module.iot.service.device.data; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyHistoryPageReqVO; | 4 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyHistoryPageReqVO; |
| 5 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; |
| 7 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 8 | import jakarta.validation.Valid; | 8 | import jakarta.validation.Valid; |
| 9 | 9 | ||
| 10 | import java.time.LocalDateTime; | 10 | import java.time.LocalDateTime; |
| @@ -56,16 +56,43 @@ public interface IotDevicePropertyService { | @@ -56,16 +56,43 @@ public interface IotDevicePropertyService { | ||
| 56 | * 获得最后上报时间小于指定时间的设备标识 | 56 | * 获得最后上报时间小于指定时间的设备标识 |
| 57 | * | 57 | * |
| 58 | * @param maxReportTime 最大上报时间 | 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 | * @param reportTime 上报时间 | 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 | \ No newline at end of file | 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,17 +9,18 @@ import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; | ||
| 9 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyHistoryPageReqVO; | 9 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyHistoryPageReqVO; |
| 10 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO; | 10 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.data.IotDevicePropertyRespVO; |
| 11 | import cn.iocoder.yudao.module.iot.controller.admin.thingmodel.model.dataType.ThingModelDateOrTextDataSpecs; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 13 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 13 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; | 14 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO; |
| 14 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; | 15 | import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO; |
| 15 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; | 16 | import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO; |
| 16 | import cn.iocoder.yudao.module.iot.dal.redis.device.DevicePropertyRedisDAO; | 17 | import cn.iocoder.yudao.module.iot.dal.redis.device.DevicePropertyRedisDAO; |
| 17 | import cn.iocoder.yudao.module.iot.dal.redis.device.DeviceReportTimeRedisDAO; | 18 | import cn.iocoder.yudao.module.iot.dal.redis.device.DeviceReportTimeRedisDAO; |
| 19 | +import cn.iocoder.yudao.module.iot.dal.redis.device.DeviceServerIdRedisDAO; | ||
| 18 | import cn.iocoder.yudao.module.iot.dal.tdengine.IotDevicePropertyMapper; | 20 | import cn.iocoder.yudao.module.iot.dal.tdengine.IotDevicePropertyMapper; |
| 19 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum; | 21 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum; |
| 20 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; | 22 | import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum; |
| 21 | import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField; | 23 | import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField; |
| 22 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 23 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | 24 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 24 | import cn.iocoder.yudao.module.iot.service.product.IotProductService; | 25 | import cn.iocoder.yudao.module.iot.service.product.IotProductService; |
| 25 | import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; | 26 | import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService; |
| @@ -27,7 +28,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage; | @@ -27,7 +28,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage; | ||
| 27 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 28 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| 28 | import jakarta.annotation.Resource; | 29 | import jakarta.annotation.Resource; |
| 29 | import lombok.extern.slf4j.Slf4j; | 30 | import lombok.extern.slf4j.Slf4j; |
| 30 | -import org.springframework.scheduling.annotation.Async; | ||
| 31 | import org.springframework.stereotype.Service; | 31 | import org.springframework.stereotype.Service; |
| 32 | 32 | ||
| 33 | import java.time.LocalDateTime; | 33 | import java.time.LocalDateTime; |
| @@ -70,6 +70,8 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | @@ -70,6 +70,8 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | ||
| 70 | private DevicePropertyRedisDAO deviceDataRedisDAO; | 70 | private DevicePropertyRedisDAO deviceDataRedisDAO; |
| 71 | @Resource | 71 | @Resource |
| 72 | private DeviceReportTimeRedisDAO deviceReportTimeRedisDAO; | 72 | private DeviceReportTimeRedisDAO deviceReportTimeRedisDAO; |
| 73 | + @Resource | ||
| 74 | + private DeviceServerIdRedisDAO deviceServerIdRedisDAO; | ||
| 73 | 75 | ||
| 74 | @Resource | 76 | @Resource |
| 75 | private IotDevicePropertyMapper devicePropertyMapper; | 77 | private IotDevicePropertyMapper devicePropertyMapper; |
| @@ -153,7 +155,8 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | @@ -153,7 +155,8 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | ||
| 153 | LocalDateTimeUtil.toEpochMilli(message.getReportTime())); | 155 | LocalDateTimeUtil.toEpochMilli(message.getReportTime())); |
| 154 | 156 | ||
| 155 | // 3.2 保存设备属性【日志】 | 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 | entry -> IotDevicePropertyDO.builder().value(entry.getValue()).updateTime(message.getReportTime()).build())); | 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,14 +190,31 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService { | ||
| 187 | // ========== 设备时间相关操作 ========== | 190 | // ========== 设备时间相关操作 ========== |
| 188 | 191 | ||
| 189 | @Override | 192 | @Override |
| 190 | - public Set<String> getDeviceKeysByReportTime(LocalDateTime maxReportTime) { | 193 | + public Set<String[]> getProductKeyDeviceNameListByReportTime(LocalDateTime maxReportTime) { |
| 191 | return deviceReportTimeRedisDAO.range(maxReportTime); | 194 | return deviceReportTimeRedisDAO.range(maxReportTime); |
| 192 | } | 195 | } |
| 193 | 196 | ||
| 194 | @Override | 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 | \ No newline at end of file | 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,9 +3,9 @@ package cn.iocoder.yudao.module.iot.service.rule; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO; | 4 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO; |
| 5 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 7 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; | 8 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; |
| 8 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 9 | import jakarta.validation.Valid; | 9 | import jakarta.validation.Valid; |
| 10 | 10 | ||
| 11 | import java.util.List; | 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,6 +17,7 @@ import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; | ||
| 17 | import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; | 17 | import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils; |
| 18 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO; | 18 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleScenePageReqVO; |
| 19 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.scene.IotRuleSceneSaveReqVO; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | 21 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 21 | import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotRuleSceneMapper; | 22 | import cn.iocoder.yudao.module.iot.dal.mysql.rule.IotRuleSceneMapper; |
| 22 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; | 23 | import cn.iocoder.yudao.module.iot.enums.device.IotDeviceMessageIdentifierEnum; |
| @@ -26,7 +27,6 @@ import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerConditionParame | @@ -26,7 +27,6 @@ import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerConditionParame | ||
| 26 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; | 27 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneTriggerTypeEnum; |
| 27 | import cn.iocoder.yudao.module.iot.framework.job.core.IotSchedulerManager; | 28 | import cn.iocoder.yudao.module.iot.framework.job.core.IotSchedulerManager; |
| 28 | import cn.iocoder.yudao.module.iot.job.rule.IotRuleSceneJob; | 29 | import cn.iocoder.yudao.module.iot.job.rule.IotRuleSceneJob; |
| 29 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 30 | import cn.iocoder.yudao.module.iot.service.rule.action.IotRuleSceneAction; | 30 | import cn.iocoder.yudao.module.iot.service.rule.action.IotRuleSceneAction; |
| 31 | import jakarta.annotation.Resource; | 31 | import jakarta.annotation.Resource; |
| 32 | import lombok.SneakyThrows; | 32 | import lombok.SneakyThrows; |
| @@ -240,16 +240,17 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | @@ -240,16 +240,17 @@ public class IotRuleSceneServiceImpl implements IotRuleSceneService { | ||
| 240 | 240 | ||
| 241 | @Override | 241 | @Override |
| 242 | public void executeRuleSceneByDevice(IotDeviceMessage message) { | 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 | @Override | 256 | @Override |
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/action/IotRuleSceneAction.java
| 1 | package cn.iocoder.yudao.module.iot.service.rule.action; | 1 | package cn.iocoder.yudao.module.iot.service.rule.action; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | ||
| 3 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 4 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; | 5 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 6 | 6 | ||
| 7 | import javax.annotation.Nullable; | 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 | package cn.iocoder.yudao.module.iot.service.rule.action; | 1 | package cn.iocoder.yudao.module.iot.service.rule.action; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | ||
| 3 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 4 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; | 5 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 6 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
| 7 | 7 | ||
| 8 | import javax.annotation.Nullable; | 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,10 +2,10 @@ package cn.iocoder.yudao.module.iot.service.rule.action; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.lang.Assert; | 3 | import cn.hutool.core.lang.Assert; |
| 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 5 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | ||
| 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 7 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; | 8 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; |
| 8 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 9 | import cn.iocoder.yudao.module.iot.service.rule.IotDataBridgeService; | 9 | import cn.iocoder.yudao.module.iot.service.rule.IotDataBridgeService; |
| 10 | import cn.iocoder.yudao.module.iot.service.rule.action.databridge.IotDataBridgeExecute; | 10 | import cn.iocoder.yudao.module.iot.service.rule.action.databridge.IotDataBridgeExecute; |
| 11 | import jakarta.annotation.Resource; | 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,10 +2,10 @@ package cn.iocoder.yudao.module.iot.service.rule.action; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.lang.Assert; | 3 | import cn.hutool.core.lang.Assert; |
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.device.vo.control.IotDeviceDownstreamReqVO; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO; |
| 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; | 7 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotRuleSceneDO; |
| 7 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; | 8 | import cn.iocoder.yudao.module.iot.enums.rule.IotRuleSceneActionTypeEnum; |
| 8 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 9 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; | 9 | import cn.iocoder.yudao.module.iot.service.device.IotDeviceService; |
| 10 | import cn.iocoder.yudao.module.iot.service.device.control.IotDeviceDownstreamService; | 10 | import cn.iocoder.yudao.module.iot.service.device.control.IotDeviceDownstreamService; |
| 11 | import jakarta.annotation.Resource; | 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 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.ObjUtil; | 3 | import cn.hutool.core.util.ObjUtil; |
| 4 | +import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | ||
| 4 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | 5 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 5 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 6 | import com.google.common.cache.CacheBuilder; | 6 | import com.google.common.cache.CacheBuilder; |
| 7 | import com.google.common.cache.CacheLoader; | 7 | import com.google.common.cache.CacheLoader; |
| 8 | import com.google.common.cache.LoadingCache; | 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 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | 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 | * IoT 数据桥梁的执行器 execute 接口 | 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,8 +4,8 @@ import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; | 4 | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; |
| 5 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | 5 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 6 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeHttpConfig; | 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 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; | 8 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 8 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 9 | import jakarta.annotation.Resource; | 9 | import jakarta.annotation.Resource; |
| 10 | import lombok.extern.slf4j.Slf4j; | 10 | import lombok.extern.slf4j.Slf4j; |
| 11 | import org.springframework.http.*; | 11 | import org.springframework.http.*; |
| @@ -16,8 +16,6 @@ import org.springframework.web.util.UriComponentsBuilder; | @@ -16,8 +16,6 @@ import org.springframework.web.util.UriComponentsBuilder; | ||
| 16 | import java.util.HashMap; | 16 | import java.util.HashMap; |
| 17 | import java.util.Map; | 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 | * Http 的 {@link IotDataBridgeExecute} 实现类 | 20 | * Http 的 {@link IotDataBridgeExecute} 实现类 |
| 23 | * | 21 | * |
| @@ -48,7 +46,8 @@ public class IotHttpDataBridgeExecute implements IotDataBridgeExecute<IotDataBri | @@ -48,7 +46,8 @@ public class IotHttpDataBridgeExecute implements IotDataBridgeExecute<IotDataBri | ||
| 48 | if (CollUtil.isNotEmpty(config.getHeaders())) { | 46 | if (CollUtil.isNotEmpty(config.getHeaders())) { |
| 49 | config.getHeaders().putAll(config.getHeaders()); | 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 | // 1.2 构建 URL | 51 | // 1.2 构建 URL |
| 53 | UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(config.getUrl()); | 52 | UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(config.getUrl()); |
| 54 | if (CollUtil.isNotEmpty(config.getQuery())) { | 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 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeKafkaMQConfig; | 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 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; | 5 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 6 | import lombok.extern.slf4j.Slf4j; | 6 | import lombok.extern.slf4j.Slf4j; |
| 7 | import org.apache.kafka.clients.producer.ProducerConfig; | 7 | import org.apache.kafka.clients.producer.ProducerConfig; |
| 8 | import org.apache.kafka.common.serialization.StringSerializer; | 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 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeRabbitMQConfig; | 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 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; | 5 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 6 | import com.rabbitmq.client.Channel; | 6 | import com.rabbitmq.client.Channel; |
| 7 | import com.rabbitmq.client.Connection; | 7 | import com.rabbitmq.client.Connection; |
| 8 | import com.rabbitmq.client.ConnectionFactory; | 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,8 +2,8 @@ package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.StrUtil; | 3 | import cn.hutool.core.util.StrUtil; |
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeRedisStreamConfig; | 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 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; | 6 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 6 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 7 | import lombok.extern.slf4j.Slf4j; | 7 | import lombok.extern.slf4j.Slf4j; |
| 8 | import org.redisson.Redisson; | 8 | import org.redisson.Redisson; |
| 9 | import org.redisson.api.RedissonClient; | 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 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | 1 | package cn.iocoder.yudao.module.iot.service.rule.action.databridge; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.IotDataBridgeRocketMQConfig; | 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 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; | 5 | import cn.iocoder.yudao.module.iot.enums.rule.IotDataBridgeTypeEnum; |
| 5 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 6 | import lombok.extern.slf4j.Slf4j; | 6 | import lombok.extern.slf4j.Slf4j; |
| 7 | import org.apache.rocketmq.client.producer.DefaultMQProducer; | 7 | import org.apache.rocketmq.client.producer.DefaultMQProducer; |
| 8 | import org.apache.rocketmq.client.producer.SendResult; | 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,8 +2,8 @@ package cn.iocoder.yudao.module.iot.service.rule.action.databridge; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; | 3 | import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; |
| 4 | import cn.iocoder.yudao.module.iot.controller.admin.rule.vo.databridge.config.*; | 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 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; | 6 | import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataBridgeDO; |
| 6 | -import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage; | ||
| 7 | import lombok.extern.slf4j.Slf4j; | 7 | import lombok.extern.slf4j.Slf4j; |
| 8 | import org.junit.jupiter.api.BeforeEach; | 8 | import org.junit.jupiter.api.BeforeEach; |
| 9 | import org.junit.jupiter.api.Disabled; | 9 | import org.junit.jupiter.api.Disabled; |
| @@ -41,8 +41,8 @@ public class IotDataBridgeExecuteTest extends BaseMockitoUnitTest { | @@ -41,8 +41,8 @@ public class IotDataBridgeExecuteTest extends BaseMockitoUnitTest { | ||
| 41 | @BeforeEach | 41 | @BeforeEach |
| 42 | public void setUp() { | 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 | .type("property").identifier("temperature").data("{\"value\": 60}") | 46 | .type("property").identifier("temperature").data("{\"value\": 60}") |
| 47 | .build(); | 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,7 +2,7 @@ package cn.iocoder.yudao.module.iot.core.mq.message; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageIdentifierEnum; | 3 | import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageIdentifierEnum; |
| 4 | import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageTypeEnum; | 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 | import lombok.AllArgsConstructor; | 6 | import lombok.AllArgsConstructor; |
| 7 | import lombok.Builder; | 7 | import lombok.Builder; |
| 8 | import lombok.Data; | 8 | import lombok.Data; |
| @@ -79,7 +79,7 @@ public class IotDeviceMessage { | @@ -79,7 +79,7 @@ public class IotDeviceMessage { | ||
| 79 | private LocalDateTime reportTime; | 79 | private LocalDateTime reportTime; |
| 80 | 80 | ||
| 81 | /** | 81 | /** |
| 82 | - * 服务编号,该消息由哪个消息发送 | 82 | + * 服务编号,该消息由哪个 server 服务进行消费 |
| 83 | */ | 83 | */ |
| 84 | private String serverId; | 84 | private String serverId; |
| 85 | 85 | ||
| @@ -97,6 +97,18 @@ public class IotDeviceMessage { | @@ -97,6 +97,18 @@ public class IotDeviceMessage { | ||
| 97 | return this; | 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 | public static IotDeviceMessage of(String productKey, String deviceName) { | 112 | public static IotDeviceMessage of(String productKey, String deviceName) { |
| 101 | return of(productKey, deviceName, | 113 | return of(productKey, deviceName, |
| 102 | null, null); | 114 | null, null); |
| @@ -113,17 +125,11 @@ public class IotDeviceMessage { | @@ -113,17 +125,11 @@ public class IotDeviceMessage { | ||
| 113 | if (reportTime == null) { | 125 | if (reportTime == null) { |
| 114 | reportTime = LocalDateTime.now(); | 126 | reportTime = LocalDateTime.now(); |
| 115 | } | 127 | } |
| 116 | - String messageId = IotCoreUtils.generateMessageId(); | 128 | + String messageId = IotDeviceMessageUtils.generateMessageId(); |
| 117 | return IotDeviceMessage.builder() | 129 | return IotDeviceMessage.builder() |
| 118 | .messageId(messageId).reportTime(reportTime) | 130 | .messageId(messageId).reportTime(reportTime) |
| 119 | .productKey(productKey).deviceName(deviceName) | 131 | .productKey(productKey).deviceName(deviceName) |
| 120 | .serverId(serverId).build(); | 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,6 +2,7 @@ package cn.iocoder.yudao.module.iot.core.mq.producer; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus; | 3 | import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus; |
| 4 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | 4 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; |
| 5 | +import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; | ||
| 5 | import lombok.RequiredArgsConstructor; | 6 | import lombok.RequiredArgsConstructor; |
| 6 | 7 | ||
| 7 | /** | 8 | /** |
| @@ -30,7 +31,7 @@ public class IotDeviceMessageProducer { | @@ -30,7 +31,7 @@ public class IotDeviceMessageProducer { | ||
| 30 | * @param message 设备消息 | 31 | * @param message 设备消息 |
| 31 | */ | 32 | */ |
| 32 | public void sendGatewayDeviceMessage(String serverId, Object message) { | 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 | package cn.iocoder.yudao.module.iot.core.util; | 1 | package cn.iocoder.yudao.module.iot.core.util; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.IdUtil; | 3 | import cn.hutool.core.util.IdUtil; |
| 4 | +import cn.hutool.core.util.StrUtil; | ||
| 4 | import cn.hutool.system.SystemUtil; | 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 | * @author 芋道源码 | 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,8 +46,4 @@ public class IotCoreUtils { | ||
| 22 | return serverId.replaceAll("\\.", "_"); | 46 | return serverId.replaceAll("\\.", "_"); |
| 23 | } | 47 | } |
| 24 | 48 | ||
| 25 | - public static String generateMessageId() { | ||
| 26 | - return IdUtil.fastSimpleUUID(); | ||
| 27 | - } | ||
| 28 | - | ||
| 29 | } | 49 | } |
| 30 | \ No newline at end of file | 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,6 +3,7 @@ package cn.iocoder.yudao.module.iot.gateway.protocol.http; | ||
| 3 | import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus; | 3 | import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageBus; |
| 4 | import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageSubscriber; | 4 | import cn.iocoder.yudao.module.iot.core.messagebus.core.IotMessageSubscriber; |
| 5 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; | 5 | import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; |
| 6 | +import cn.iocoder.yudao.module.iot.core.util.IotDeviceMessageUtils; | ||
| 6 | import jakarta.annotation.PostConstruct; | 7 | import jakarta.annotation.PostConstruct; |
| 7 | import lombok.RequiredArgsConstructor; | 8 | import lombok.RequiredArgsConstructor; |
| 8 | import lombok.extern.slf4j.Slf4j; | 9 | import lombok.extern.slf4j.Slf4j; |
| @@ -27,7 +28,7 @@ public class IotHttpDownstreamSubscriber implements IotMessageSubscriber<IotDevi | @@ -27,7 +28,7 @@ public class IotHttpDownstreamSubscriber implements IotMessageSubscriber<IotDevi | ||
| 27 | 28 | ||
| 28 | @Override | 29 | @Override |
| 29 | public String getTopic() { | 30 | public String getTopic() { |
| 30 | - return IotDeviceMessage.buildMessageBusGatewayDeviceMessageTopic(protocol.getServerId()); | 31 | + return IotDeviceMessageUtils.buildMessageBusGatewayDeviceMessageTopic(protocol.getServerId()); |
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | @Override | 34 | @Override |
yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/IotHttpUpstreamProtocol.java
| 1 | package cn.iocoder.yudao.module.iot.gateway.protocol.http; | 1 | package cn.iocoder.yudao.module.iot.gateway.protocol.http; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.iot.core.mq.producer.IotDeviceMessageProducer; | 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 | import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties; | 5 | import cn.iocoder.yudao.module.iot.gateway.config.IotGatewayProperties; |
| 6 | import cn.iocoder.yudao.module.iot.gateway.protocol.http.router.IotHttpUpstreamHandler; | 6 | import cn.iocoder.yudao.module.iot.gateway.protocol.http.router.IotHttpUpstreamHandler; |
| 7 | import io.vertx.core.AbstractVerticle; | 7 | import io.vertx.core.AbstractVerticle; |
| @@ -70,7 +70,7 @@ public class IotHttpUpstreamProtocol extends AbstractVerticle { | @@ -70,7 +70,7 @@ public class IotHttpUpstreamProtocol extends AbstractVerticle { | ||
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | public String getServerId() { | 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,38 +19,8 @@ public class IotDeviceUpstreamClient implements IotDeviceUpstreamApi { | ||
| 19 | private IotDeviceUpstreamApi deviceUpstreamApi; | 19 | private IotDeviceUpstreamApi deviceUpstreamApi; |
| 20 | 20 | ||
| 21 | @Override | 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 | public CommonResult<Boolean> authenticateEmqxConnection(IotDeviceEmqxAuthReqDTO authReqDTO) { | 22 | public CommonResult<Boolean> authenticateEmqxConnection(IotDeviceEmqxAuthReqDTO authReqDTO) { |
| 48 | return deviceUpstreamApi.authenticateEmqxConnection(authReqDTO); | 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,7 +4,7 @@ import cn.hutool.core.util.StrUtil; | ||
| 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; | 5 | import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi; |
| 6 | import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceStateUpdateReqDTO; | 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 | import cn.iocoder.yudao.module.iot.net.component.core.util.IotNetComponentCommonUtils; | 8 | import cn.iocoder.yudao.module.iot.net.component.core.util.IotNetComponentCommonUtils; |
| 9 | import io.vertx.core.Handler; | 9 | import io.vertx.core.Handler; |
| 10 | import io.vertx.core.json.JsonObject; | 10 | import io.vertx.core.json.JsonObject; |