Commit e650e75271cf241721f19014dadb22b3b51e24f0

Authored by YunaiV
1 parent 30ae986c

【代码优化】IoT:设备上行时,增加 processId,用于设备与插件的映射

Showing 25 changed files with 277 additions and 190 deletions
yudao-module-iot/yudao-module-iot-api/src/main/java/cn/iocoder/yudao/module/iot/api/device/dto/control/upstream/IotDeviceUpstreamAbstractReqDTO.java
... ... @@ -21,9 +21,9 @@ public abstract class IotDeviceUpstreamAbstractReqDTO {
21 21 private String requestId;
22 22  
23 23 /**
24   - * 插件标识
  24 + * 插件实例的进程编号
25 25 */
26   - private String pluginKey;
  26 + private String processId;
27 27  
28 28 /**
29 29 * 产品标识
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/plugin/PluginInfoController.java
... ... @@ -7,8 +7,8 @@ import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoImp
7 7 import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoPageReqVO;
8 8 import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoRespVO;
9 9 import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoSaveReqVO;
10   -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
11   -import cn.iocoder.yudao.module.iot.service.plugin.PluginInfoService;
  10 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO;
  11 +import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInfoService;
12 12 import io.swagger.v3.oas.annotations.Operation;
13 13 import io.swagger.v3.oas.annotations.Parameter;
14 14 import io.swagger.v3.oas.annotations.tags.Tag;
... ... @@ -27,7 +27,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
27 27 public class PluginInfoController {
28 28  
29 29 @Resource
30   - private PluginInfoService pluginInfoService;
  30 + private IotPluginInfoService pluginInfoService;
31 31  
32 32 @PostMapping("/create")
33 33 @Operation(summary = "创建插件信息")
... ... @@ -58,7 +58,7 @@ public class PluginInfoController {
58 58 @Parameter(name = "id", description = "编号", required = true, example = "1024")
59 59 @PreAuthorize("@ss.hasPermission('iot:plugin-info:query')")
60 60 public CommonResult<PluginInfoRespVO> getPluginInfo(@RequestParam("id") Long id) {
61   - PluginInfoDO pluginInfo = pluginInfoService.getPluginInfo(id);
  61 + IotPluginInfoDO pluginInfo = pluginInfoService.getPluginInfo(id);
62 62 return success(BeanUtils.toBean(pluginInfo, PluginInfoRespVO.class));
63 63 }
64 64  
... ... @@ -66,7 +66,7 @@ public class PluginInfoController {
66 66 @Operation(summary = "获得插件信息分页")
67 67 @PreAuthorize("@ss.hasPermission('iot:plugin-info:query')")
68 68 public CommonResult<PageResult<PluginInfoRespVO>> getPluginInfoPage(@Valid PluginInfoPageReqVO pageReqVO) {
69   - PageResult<PluginInfoDO> pageResult = pluginInfoService.getPluginInfoPage(pageReqVO);
  69 + PageResult<IotPluginInfoDO> pageResult = pluginInfoService.getPluginInfoPage(pageReqVO);
70 70 return success(BeanUtils.toBean(pageResult, PluginInfoRespVO.class));
71 71 }
72 72  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/PluginInfoDO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginInfoDO.java
... ... @@ -22,7 +22,7 @@ import lombok.*;
22 22 @Builder
23 23 @NoArgsConstructor
24 24 @AllArgsConstructor
25   -public class PluginInfoDO extends BaseDO {
  25 +public class IotPluginInfoDO extends BaseDO {
26 26  
27 27 /**
28 28 * 主键 ID
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/PluginInstanceDO.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/dataobject/plugin/IotPluginInstanceDO.java
... ... @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
6 6 import com.baomidou.mybatisplus.annotation.TableName;
7 7 import lombok.*;
8 8  
  9 +import java.time.LocalDateTime;
9 10  
10 11 /**
11 12 * IoT 插件实例 DO
... ... @@ -20,40 +21,52 @@ import lombok.*;
20 21 @Builder
21 22 @NoArgsConstructor
22 23 @AllArgsConstructor
23   -public class PluginInstanceDO extends BaseDO {
  24 +public class IotPluginInstanceDO extends BaseDO {
24 25  
25 26 /**
26   - * 主键ID
  27 + * 主键
27 28 */
28 29 @TableId
29 30 private Long id;
30   - // TODO @芋艿:找一个更好的字段名
31 31 /**
32   - * 插件主程序 ID
33   - */
34   - private String mainId;
35   - /**
36   - * 插件 ID
  32 + * 插件编号
37 33 * <p>
38   - * 关联 {@link PluginInfoDO#getId()}
  34 + * 关联 {@link IotPluginInfoDO#getId()}
39 35 */
40 36 private Long pluginId;
  37 + /**
  38 + * 插件进程编号
  39 + *
  40 + * 一般格式是:hostIp@processId@${uuid}
  41 + */
  42 + private String processId;
41 43  
42 44 /**
43   - * 插件主程序所在 IP
  45 + * 插件实例所在 IP
44 46 */
45   - private String ip;
46   - // TODO @芋艿:这个 port 是否有必要记录
  47 + private String hostIp;
47 48 /**
48   - * 插件主程序端口
  49 + * 设备下行端口
49 50 */
50   - private Integer port;
51   - // TODO @芋艿:downstreamPort 增加,目的:用于下行
  51 + private Integer downstreamPort;
52 52  
53   - // TODO @haohao:字段改成 heartbeatTime,LocalDateTime
54 53 /**
55   - * 心跳时间,心路时间超过 30 秒需要剔除
  54 + * 是否在线
  55 + */
  56 + private Boolean online;
  57 + /**
  58 + * 在线时间
  59 + */
  60 + private LocalDateTime onlineTime;
  61 + /**
  62 + * 离线时间
  63 + */
  64 + private LocalDateTime offlineTime;
  65 + /**
  66 + * 心跳时间
  67 + *
  68 + * 目的:心路时间超过一定时间后,会被进行下线处理
56 69 */
57   - private Long heartbeatAt;
  70 + private Long heartbeatTime;
58 71  
59 72 }
60 73 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginInfoMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.dal.mysql.plugin;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoPageReqVO;
  7 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.List;
  11 +
  12 +@Mapper
  13 +public interface IotPluginInfoMapper extends BaseMapperX<IotPluginInfoDO> {
  14 +
  15 + default PageResult<IotPluginInfoDO> selectPage(PluginInfoPageReqVO reqVO) {
  16 + return selectPage(reqVO, new LambdaQueryWrapperX<IotPluginInfoDO>()
  17 + .likeIfPresent(IotPluginInfoDO::getName, reqVO.getName())
  18 + .eqIfPresent(IotPluginInfoDO::getStatus, reqVO.getStatus())
  19 + .orderByDesc(IotPluginInfoDO::getId));
  20 + }
  21 +
  22 + default List<IotPluginInfoDO> selectListByStatus(Integer status) {
  23 + return selectList(new LambdaQueryWrapperX<IotPluginInfoDO>()
  24 + .eq(IotPluginInfoDO::getStatus, status)
  25 + .orderByAsc(IotPluginInfoDO::getId));
  26 + }
  27 +
  28 +}
0 29 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/IotPluginInstanceMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.dal.mysql.plugin;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  5 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +@Mapper
  9 +public interface IotPluginInstanceMapper extends BaseMapperX<IotPluginInstanceDO> {
  10 +
  11 + // TODO @芋艿:方法名,重构
  12 + default IotPluginInstanceDO selectByMainIdAndPluginId(String mainId, Long pluginId) {
  13 + return selectOne(new LambdaQueryWrapperX<IotPluginInstanceDO>()
  14 + .eq(IotPluginInstanceDO::getProcessId, mainId)
  15 + .eq(IotPluginInstanceDO::getPluginId, pluginId));
  16 + }
  17 +
  18 +}
0 19 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/PluginInfoMapper.java deleted
1   -package cn.iocoder.yudao.module.iot.dal.mysql.plugin;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
5   -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6   -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoPageReqVO;
7   -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
8   -
9   -import java.util.List;
10   -
11   -import org.apache.ibatis.annotations.Mapper;
12   -
13   -/**
14   - * IoT 插件信息 Mapper
15   - *
16   - * @author 芋道源码
17   - */
18   -@Mapper
19   -public interface PluginInfoMapper extends BaseMapperX<PluginInfoDO> {
20   -
21   - default PageResult<PluginInfoDO> selectPage(PluginInfoPageReqVO reqVO) {
22   - return selectPage(reqVO, new LambdaQueryWrapperX<PluginInfoDO>()
23   - .likeIfPresent(PluginInfoDO::getName, reqVO.getName())
24   - .eqIfPresent(PluginInfoDO::getStatus, reqVO.getStatus())
25   - .orderByDesc(PluginInfoDO::getId));
26   - }
27   -
28   - default List<PluginInfoDO> selectListByStatus(Integer status) {
29   - return selectList(new LambdaQueryWrapperX<PluginInfoDO>()
30   - .eq(PluginInfoDO::getStatus, status)
31   - .orderByAsc(PluginInfoDO::getId));
32   - }
33   -
34   -}
35 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/mysql/plugin/PluginInstanceMapper.java deleted
1   -package cn.iocoder.yudao.module.iot.dal.mysql.plugin;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
5   -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6   -import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.instance.PluginInstancePageReqVO;
7   -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInstanceDO;
8   -import org.apache.ibatis.annotations.Mapper;
9   -
10   -/**
11   - * IoT 插件实例 Mapper
12   - *
13   - * @author 芋道源码
14   - */
15   -@Mapper
16   -public interface PluginInstanceMapper extends BaseMapperX<PluginInstanceDO> {
17   -
18   - default PluginInstanceDO selectByMainIdAndPluginId(String mainId, Long pluginId) {
19   - return selectOne(new LambdaQueryWrapperX<PluginInstanceDO>()
20   - .eq(PluginInstanceDO::getMainId, mainId)
21   - .eq(PluginInstanceDO::getPluginId, pluginId));
22   - }
23   -
24   - // TODO @haohao:这个还需要么?相关不用的 VO 可以删除
25   - default PageResult<PluginInstanceDO> selectPage(PluginInstancePageReqVO reqVO) {
26   - return selectPage(reqVO, new LambdaQueryWrapperX<PluginInstanceDO>()
27   - .eqIfPresent(PluginInstanceDO::getMainId, reqVO.getMainId())
28   - .eqIfPresent(PluginInstanceDO::getPluginId, reqVO.getPluginId())
29   - .eqIfPresent(PluginInstanceDO::getIp, reqVO.getIp())
30   - .eqIfPresent(PluginInstanceDO::getPort, reqVO.getPort())
31   - .eqIfPresent(PluginInstanceDO::getHeartbeatAt, reqVO.getHeartbeatAt())
32   - .betweenIfPresent(PluginInstanceDO::getCreateTime, reqVO.getCreateTime())
33   - .orderByDesc(PluginInstanceDO::getId));
34   - }
35   -
36   -}
37 0 \ No newline at end of file
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/RedisKeyConstants.java
1 1 package cn.iocoder.yudao.module.iot.dal.redis;
2 2  
3 3 import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
  4 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO;
4 5  
5 6 /**
6 7 * Iot Redis Key 枚举类
... ... @@ -42,4 +43,13 @@ public interface RedisKeyConstants {
42 43 */
43 44 String THING_MODEL_LIST = "thing_model_list";
44 45  
  46 + /**
  47 + * 设备插件的插件进程编号的映射,采用 HASH 结构
  48 + *
  49 + * KEY 格式:device_plugin_instance_process_ids
  50 + * HASH KEY:${deviceKey}
  51 + * VALUE:插件进程编号,对应 {@link IotPluginInstanceDO#getProcessId()} 字段
  52 + */
  53 + String DEVICE_PLUGIN_INSTANCE_PROCESS_IDS = "device_plugin_instance_process_ids";
  54 +
45 55 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/device/DevicePropertyRedisDAO.java
... ... @@ -33,7 +33,7 @@ public class DevicePropertyRedisDAO {
33 33 entry -> JsonUtils.parseObject((String) entry.getValue(), IotDevicePropertyDO.class));
34 34 }
35 35  
36   - public void set(String deviceKey, Map<String, IotDevicePropertyDO> properties) {
  36 + public void putAll(String deviceKey, Map<String, IotDevicePropertyDO> properties) {
37 37 if (CollUtil.isEmpty(properties)) {
38 38 return;
39 39 }
... ... @@ -43,11 +43,6 @@ public class DevicePropertyRedisDAO {
43 43 entry -> JsonUtils.toJsonString(entry.getValue())));
44 44 }
45 45  
46   - public void delete(String deviceKey) {
47   - String redisKey = formatKey(deviceKey);
48   - stringRedisTemplate.delete(redisKey);
49   - }
50   -
51 46 private static String formatKey(String deviceKey) {
52 47 return String.format(DEVICE_PROPERTY, deviceKey);
53 48 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/dal/redis/plugin/DevicePluginProcessIdRedisDAO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.dal.redis.plugin;
  2 +
  3 +import cn.iocoder.yudao.module.iot.dal.redis.RedisKeyConstants;
  4 +import jakarta.annotation.Resource;
  5 +import org.springframework.data.redis.core.StringRedisTemplate;
  6 +import org.springframework.stereotype.Repository;
  7 +
  8 +/**
  9 + * 设备插件的插件进程编号的缓存的 Redis DAO
  10 + */
  11 +@Repository
  12 +public class DevicePluginProcessIdRedisDAO {
  13 +
  14 + @Resource
  15 + private StringRedisTemplate stringRedisTemplate;
  16 +
  17 + public void put(String deviceKey, String processId) {
  18 + stringRedisTemplate.opsForHash().put(RedisKeyConstants.DEVICE_PLUGIN_INSTANCE_PROCESS_IDS, deviceKey, processId);
  19 + }
  20 +
  21 + public String get(String deviceKey) {
  22 + return (String) stringRedisTemplate.opsForHash().get(RedisKeyConstants.DEVICE_PLUGIN_INSTANCE_PROCESS_IDS, deviceKey);
  23 + }
  24 +
  25 +}
0 26 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/framework/plugin/core/PluginStart.java
... ... @@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.iot.framework.plugin.core;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
5   -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
  5 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO;
6 6 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
7   -import cn.iocoder.yudao.module.iot.service.plugin.PluginInfoService;
  7 +import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInfoService;
8 8 import lombok.extern.slf4j.Slf4j;
9 9 import org.pf4j.spring.SpringPluginManager;
10 10 import org.springframework.boot.ApplicationArguments;
... ... @@ -20,7 +20,7 @@ import java.util.List;
20 20 public class PluginStart implements ApplicationRunner {
21 21  
22 22 @Resource
23   - private PluginInfoService pluginInfoService;
  23 + private IotPluginInfoService pluginInfoService;
24 24  
25 25 @Resource
26 26 private SpringPluginManager pluginManager;
... ... @@ -28,7 +28,7 @@ public class PluginStart implements ApplicationRunner {
28 28 @Override
29 29 public void run(ApplicationArguments args) {
30 30 TenantUtils.executeIgnore(() -> { // 1. 忽略租户上下文执行
31   - List<PluginInfoDO> pluginInfoList = pluginInfoService
  31 + List<IotPluginInfoDO> pluginInfoList = pluginInfoService
32 32 .getPluginInfoListByStatus(IotPluginStatusEnum.RUNNING.getStatus()); // 2. 获取运行中的插件列表
33 33 if (CollUtil.isEmpty(pluginInfoList)) { // 3. 检查插件列表是否为空
34 34 log.info("[run] 没有需要启动的插件"); // 4. 日志记录没有插件需要启动
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/job/plugin/PluginInstancesJob.java
1 1 package cn.iocoder.yudao.module.iot.job.plugin;
2 2  
3 3 import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
4   -import cn.iocoder.yudao.module.iot.service.plugin.PluginInstanceService;
  4 +import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService;
5 5 import org.springframework.scheduling.annotation.Scheduled;
6 6 import org.springframework.stereotype.Component;
7 7  
... ... @@ -18,7 +18,7 @@ import java.util.concurrent.TimeUnit;
18 18 public class PluginInstancesJob {
19 19  
20 20 @Resource
21   - private PluginInstanceService pluginInstanceService;
  21 + private IotPluginInstanceService pluginInstanceService;
22 22  
23 23 @Scheduled(initialDelay = 60, fixedRate = 60, timeUnit = TimeUnit.SECONDS)
24 24 public void updatePluginInstances() {
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/control/IotDeviceUpstreamServiceImpl.java
... ... @@ -20,6 +20,7 @@ import cn.iocoder.yudao.module.iot.mq.message.IotDeviceMessage;
20 20 import cn.iocoder.yudao.module.iot.mq.producer.device.IotDeviceProducer;
21 21 import cn.iocoder.yudao.module.iot.service.device.IotDeviceService;
22 22 import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService;
  23 +import cn.iocoder.yudao.module.iot.service.plugin.IotPluginInstanceService;
23 24 import jakarta.annotation.Resource;
24 25 import lombok.extern.slf4j.Slf4j;
25 26 import org.springframework.stereotype.Service;
... ... @@ -43,6 +44,8 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService {
43 44 private IotDeviceService deviceService;
44 45 @Resource
45 46 private IotDevicePropertyService devicePropertyService;
  47 + @Resource
  48 + private IotPluginInstanceService pluginInstanceService;
46 49  
47 50 @Resource
48 51 private IotDeviceProducer deviceProducer;
... ... @@ -144,10 +147,11 @@ public class IotDeviceUpstreamServiceImpl implements IotDeviceUpstreamService {
144 147 }
145 148  
146 149 private void updateDeviceLastTime(IotDeviceDO device, IotDeviceUpstreamAbstractReqDTO reqDTO) {
147   - // 1. TODO 芋艿:插件状态
  150 + // 1. 【异步】记录设备与插件实例的映射
  151 + pluginInstanceService.updateDevicePluginInstanceProcessIdAsync(device.getDeviceKey(), reqDTO.getProcessId());
148 152  
149   - // 2. 更新设备的最后时间
150   - devicePropertyService.updateDeviceReportTime(device.getDeviceKey(), LocalDateTime.now());
  153 + // 2. 【异步】更新设备的最后时间
  154 + devicePropertyService.updateDeviceReportTimeAsync(device.getDeviceKey(), LocalDateTime.now());
151 155 }
152 156  
153 157 private void sendDeviceMessage(IotDeviceMessage message, IotDeviceDO device) {
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/device/data/IotDevicePropertyService.java
... ... @@ -61,11 +61,11 @@ public interface IotDevicePropertyService {
61 61 Set<String> getDeviceKeysByReportTime(LocalDateTime maxReportTime);
62 62  
63 63 /**
64   - * 更新设备上报时间
  64 + * 异步更新设备上报时间
65 65 *
66 66 * @param deviceKey 设备标识
67 67 * @param reportTime 上报时间
68 68 */
69   - void updateDeviceReportTime(String deviceKey, LocalDateTime reportTime);
  69 + void updateDeviceReportTimeAsync(String deviceKey, LocalDateTime reportTime);
70 70  
71 71 }
72 72 \ 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
... ... @@ -27,6 +27,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
27 27 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
28 28 import jakarta.annotation.Resource;
29 29 import lombok.extern.slf4j.Slf4j;
  30 +import org.springframework.scheduling.annotation.Async;
30 31 import org.springframework.stereotype.Service;
31 32  
32 33 import java.time.LocalDateTime;
... ... @@ -151,7 +152,7 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService {
151 152 LocalDateTimeUtil.toEpochMilli(message.getReportTime()));
152 153  
153 154 // 3.2 保存设备属性【日志】
154   - deviceDataRedisDAO.set(message.getDeviceKey(), convertMap(properties.entrySet(), Map.Entry::getKey,
  155 + deviceDataRedisDAO.putAll(message.getDeviceKey(), convertMap(properties.entrySet(), Map.Entry::getKey,
155 156 entry -> IotDevicePropertyDO.builder().value(entry.getValue()).updateTime(message.getReportTime()).build()));
156 157 }
157 158  
... ... @@ -190,7 +191,8 @@ public class IotDevicePropertyServiceImpl implements IotDevicePropertyService {
190 191 }
191 192  
192 193 @Override
193   - public void updateDeviceReportTime(String deviceKey, LocalDateTime reportTime) {
  194 + @Async
  195 + public void updateDeviceReportTimeAsync(String deviceKey, LocalDateTime reportTime) {
194 196 deviceReportTimeRedisDAO.update(deviceKey, reportTime);
195 197 }
196 198  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/PluginInfoService.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInfoService.java
... ... @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.iot.service.plugin;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoPageReqVO;
5 5 import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoSaveReqVO;
6   -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
  6 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO;
7 7 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
8 8 import jakarta.validation.Valid;
9 9 import org.springframework.web.multipart.MultipartFile;
... ... @@ -15,10 +15,10 @@ import java.util.List;
15 15 *
16 16 * @author 芋道源码
17 17 */
18   -public interface PluginInfoService {
  18 +public interface IotPluginInfoService {
19 19  
20 20 /**
21   - * 创建IoT 插件信息
  21 + * 创建插件信息
22 22 *
23 23 * @param createReqVO 创建信息
24 24 * @return 编号
... ... @@ -26,34 +26,34 @@ public interface PluginInfoService {
26 26 Long createPluginInfo(@Valid PluginInfoSaveReqVO createReqVO);
27 27  
28 28 /**
29   - * 更新IoT 插件信息
  29 + * 更新插件信息
30 30 *
31 31 * @param updateReqVO 更新信息
32 32 */
33 33 void updatePluginInfo(@Valid PluginInfoSaveReqVO updateReqVO);
34 34  
35 35 /**
36   - * 删除IoT 插件信息
  36 + * 删除插件信息
37 37 *
38 38 * @param id 编号
39 39 */
40 40 void deletePluginInfo(Long id);
41 41  
42 42 /**
43   - * 获得IoT 插件信息
  43 + * 获得插件信息
44 44 *
45 45 * @param id 编号
46   - * @return IoT 插件信息
  46 + * @return 插件信息
47 47 */
48   - PluginInfoDO getPluginInfo(Long id);
  48 + IotPluginInfoDO getPluginInfo(Long id);
49 49  
50 50 /**
51   - * 获得IoT 插件信息分页
  51 + * 获得插件信息分页
52 52 *
53 53 * @param pageReqVO 分页查询
54   - * @return IoT 插件信息分页
  54 + * @return 插件信息分页
55 55 */
56   - PageResult<PluginInfoDO> getPluginInfoPage(PluginInfoPageReqVO pageReqVO);
  56 + PageResult<IotPluginInfoDO> getPluginInfoPage(PluginInfoPageReqVO pageReqVO);
57 57  
58 58 /**
59 59 * 上传插件的 JAR 包
... ... @@ -76,7 +76,7 @@ public interface PluginInfoService {
76 76 *
77 77 * @return 插件信息列表
78 78 */
79   - List<PluginInfoDO> getPluginInfoList();
  79 + List<IotPluginInfoDO> getPluginInfoList();
80 80  
81 81 /**
82 82 * 根据状态获得插件信息列表
... ... @@ -84,5 +84,5 @@ public interface PluginInfoService {
84 84 * @param status 状态 {@link IotPluginStatusEnum}
85 85 * @return 插件信息列表
86 86 */
87   - List<PluginInfoDO> getPluginInfoListByStatus(Integer status);
  87 + List<IotPluginInfoDO> getPluginInfoListByStatus(Integer status);
88 88 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/PluginInfoServiceImpl.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInfoServiceImpl.java
... ... @@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 5 import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoPageReqVO;
6 6 import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoSaveReqVO;
7   -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
8   -import cn.iocoder.yudao.module.iot.dal.mysql.plugin.PluginInfoMapper;
  7 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO;
  8 +import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginInfoMapper;
9 9 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
10 10 import jakarta.annotation.Resource;
11 11 import lombok.extern.slf4j.Slf4j;
... ... @@ -28,20 +28,20 @@ import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.PLUGIN_INFO_N
28 28 @Service
29 29 @Validated
30 30 @Slf4j
31   -public class PluginInfoServiceImpl implements PluginInfoService {
  31 +public class IotPluginInfoServiceImpl implements IotPluginInfoService {
32 32  
33 33 @Resource
34   - private PluginInfoMapper pluginInfoMapper;
  34 + private IotPluginInfoMapper pluginInfoMapper;
35 35  
36 36 @Resource
37   - private PluginInstanceService pluginInstanceService;
  37 + private IotPluginInstanceService pluginInstanceService;
38 38  
39 39 @Resource
40 40 private SpringPluginManager pluginManager;
41 41  
42 42 @Override
43 43 public Long createPluginInfo(PluginInfoSaveReqVO createReqVO) {
44   - PluginInfoDO pluginInfo = BeanUtils.toBean(createReqVO, PluginInfoDO.class);
  44 + IotPluginInfoDO pluginInfo = BeanUtils.toBean(createReqVO, IotPluginInfoDO.class);
45 45 pluginInfoMapper.insert(pluginInfo);
46 46 return pluginInfo.getId();
47 47 }
... ... @@ -51,14 +51,14 @@ public class PluginInfoServiceImpl implements PluginInfoService {
51 51 // 校验存在
52 52 validatePluginInfoExists(updateReqVO.getId());
53 53 // 更新
54   - PluginInfoDO updateObj = BeanUtils.toBean(updateReqVO, PluginInfoDO.class);
  54 + IotPluginInfoDO updateObj = BeanUtils.toBean(updateReqVO, IotPluginInfoDO.class);
55 55 pluginInfoMapper.updateById(updateObj);
56 56 }
57 57  
58 58 @Override
59 59 public void deletePluginInfo(Long id) {
60 60 // 1.1 校验存在
61   - PluginInfoDO pluginInfoDO = validatePluginInfoExists(id);
  61 + IotPluginInfoDO pluginInfoDO = validatePluginInfoExists(id);
62 62 // 1.2 停止插件
63 63 if (IotPluginStatusEnum.RUNNING.getStatus().equals(pluginInfoDO.getStatus())) {
64 64 throw exception(PLUGIN_INFO_DELETE_FAILED_RUNNING);
... ... @@ -74,8 +74,8 @@ public class PluginInfoServiceImpl implements PluginInfoService {
74 74 pluginInfoMapper.deleteById(id);
75 75 }
76 76  
77   - private PluginInfoDO validatePluginInfoExists(Long id) {
78   - PluginInfoDO pluginInfo = pluginInfoMapper.selectById(id);
  77 + private IotPluginInfoDO validatePluginInfoExists(Long id) {
  78 + IotPluginInfoDO pluginInfo = pluginInfoMapper.selectById(id);
79 79 if (pluginInfo == null) {
80 80 throw exception(PLUGIN_INFO_NOT_EXISTS);
81 81 }
... ... @@ -83,19 +83,19 @@ public class PluginInfoServiceImpl implements PluginInfoService {
83 83 }
84 84  
85 85 @Override
86   - public PluginInfoDO getPluginInfo(Long id) {
  86 + public IotPluginInfoDO getPluginInfo(Long id) {
87 87 return pluginInfoMapper.selectById(id);
88 88 }
89 89  
90 90 @Override
91   - public PageResult<PluginInfoDO> getPluginInfoPage(PluginInfoPageReqVO pageReqVO) {
  91 + public PageResult<IotPluginInfoDO> getPluginInfoPage(PluginInfoPageReqVO pageReqVO) {
92 92 return pluginInfoMapper.selectPage(pageReqVO);
93 93 }
94 94  
95 95 @Override
96 96 public void uploadFile(Long id, MultipartFile file) {
97 97 // 1. 校验插件信息是否存在
98   - PluginInfoDO pluginInfoDo = validatePluginInfoExists(id);
  98 + IotPluginInfoDO pluginInfoDo = validatePluginInfoExists(id);
99 99  
100 100 // 2. 停止并卸载旧的插件
101 101 pluginInstanceService.stopAndUnloadPlugin(pluginInfoDo.getPluginKey());
... ... @@ -114,9 +114,9 @@ public class PluginInfoServiceImpl implements PluginInfoService {
114 114 * @param pluginKeyNew 插件标识符
115 115 * @param file 文件
116 116 */
117   - private void updatePluginInfo(PluginInfoDO pluginInfoDo, String pluginKeyNew, MultipartFile file) {
  117 + private void updatePluginInfo(IotPluginInfoDO pluginInfoDo, String pluginKeyNew, MultipartFile file) {
118 118 // 创建新的插件信息对象并链式设置属性
119   - PluginInfoDO updatedPluginInfo = new PluginInfoDO()
  119 + IotPluginInfoDO updatedPluginInfo = new IotPluginInfoDO()
120 120 .setId(pluginInfoDo.getId())
121 121 .setPluginKey(pluginKeyNew)
122 122 .setStatus(IotPluginStatusEnum.STOPPED.getStatus())
... ... @@ -133,25 +133,25 @@ public class PluginInfoServiceImpl implements PluginInfoService {
133 133 @Override
134 134 public void updatePluginStatus(Long id, Integer status) {
135 135 // 1. 校验插件信息是否存在
136   - PluginInfoDO pluginInfoDo = validatePluginInfoExists(id);
  136 + IotPluginInfoDO pluginInfoDo = validatePluginInfoExists(id);
137 137  
138 138 // 2. 更新插件状态
139 139 pluginInstanceService.updatePluginStatus(pluginInfoDo, status);
140 140  
141 141 // 3. 更新数据库中的插件状态
142   - PluginInfoDO updatedPluginInfo = new PluginInfoDO();
  142 + IotPluginInfoDO updatedPluginInfo = new IotPluginInfoDO();
143 143 updatedPluginInfo.setId(id);
144 144 updatedPluginInfo.setStatus(status);
145 145 pluginInfoMapper.updateById(updatedPluginInfo);
146 146 }
147 147  
148 148 @Override
149   - public List<PluginInfoDO> getPluginInfoList() {
  149 + public List<IotPluginInfoDO> getPluginInfoList() {
150 150 return pluginInfoMapper.selectList();
151 151 }
152 152  
153 153 @Override
154   - public List<PluginInfoDO> getPluginInfoListByStatus(Integer status) {
  154 + public List<IotPluginInfoDO> getPluginInfoListByStatus(Integer status) {
155 155 return pluginInfoMapper.selectListByStatus(status);
156 156 }
157 157  
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/PluginInstanceService.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceService.java
1 1 package cn.iocoder.yudao.module.iot.service.plugin;
2 2  
3   -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
  3 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO;
4 4 import org.springframework.web.multipart.MultipartFile;
5 5  
6 6 /**
... ... @@ -8,7 +8,7 @@ import org.springframework.web.multipart.MultipartFile;
8 8 *
9 9 * @author 芋道源码
10 10 */
11   -public interface PluginInstanceService {
  11 +public interface IotPluginInstanceService {
12 12  
13 13 // TODO @芋艿:这个是否应该放到 plugin 主动心跳,而是 server 自己心跳
14 14 /**
... ... @@ -28,7 +28,7 @@ public interface PluginInstanceService {
28 28 *
29 29 * @param pluginInfoDo 插件信息
30 30 */
31   - void deletePluginFile(PluginInfoDO pluginInfoDo);
  31 + void deletePluginFile(IotPluginInfoDO pluginInfoDo);
32 32  
33 33 /**
34 34 * 上传并加载新的插件文件
... ... @@ -44,6 +44,16 @@ public interface PluginInstanceService {
44 44 * @param pluginInfoDo 插件信息
45 45 * @param status 新状态
46 46 */
47   - void updatePluginStatus(PluginInfoDO pluginInfoDo, Integer status);
  47 + void updatePluginStatus(IotPluginInfoDO pluginInfoDo, Integer status);
  48 +
  49 + // ========== 设备与插件的映射操作 ==========
  50 +
  51 + /**
  52 + * 更新设备对应的插件实例的进程编号
  53 + *
  54 + * @param deviceKey 设备 Key
  55 + * @param processId 进程编号
  56 + */
  57 + void updateDevicePluginInstanceProcessIdAsync(String deviceKey, String processId);
48 58  
49 59 }
50 60 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/PluginInstanceServiceImpl.java renamed to yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/plugin/IotPluginInstanceServiceImpl.java
... ... @@ -3,10 +3,11 @@ package cn.iocoder.yudao.module.iot.service.plugin;
3 3 import cn.hutool.core.io.FileUtil;
4 4 import cn.hutool.core.net.NetUtil;
5 5 import cn.hutool.core.util.IdUtil;
6   -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
7   -import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInstanceDO;
8   -import cn.iocoder.yudao.module.iot.dal.mysql.plugin.PluginInfoMapper;
9   -import cn.iocoder.yudao.module.iot.dal.mysql.plugin.PluginInstanceMapper;
  6 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInfoDO;
  7 +import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.IotPluginInstanceDO;
  8 +import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginInfoMapper;
  9 +import cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginInstanceMapper;
  10 +import cn.iocoder.yudao.module.iot.dal.redis.plugin.DevicePluginProcessIdRedisDAO;
10 11 import cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants;
11 12 import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
12 13 import jakarta.annotation.Resource;
... ... @@ -38,16 +39,20 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
38 39 @Service
39 40 @Validated
40 41 @Slf4j
41   -public class PluginInstanceServiceImpl implements PluginInstanceService {
  42 +public class IotPluginInstanceServiceImpl implements IotPluginInstanceService {
42 43  
43 44 // TODO @haohao:mac@uuid
44 45 public static final String MAIN_ID = IdUtil.fastSimpleUUID();
45 46  
  47 + // TODO @haohao:不直接操作,通过 Service 哈
46 48 @Resource
47   - private PluginInfoMapper pluginInfoMapper;
  49 + private IotPluginInfoMapper pluginInfoMapper;
48 50  
49 51 @Resource
50   - private PluginInstanceMapper pluginInstanceMapper;
  52 + private IotPluginInstanceMapper pluginInstanceMapper;
  53 +
  54 + @Resource
  55 + private DevicePluginProcessIdRedisDAO devicePluginProcessIdRedisDAO;
51 56  
52 57 @Resource
53 58 private SpringPluginManager pluginManager;
... ... @@ -73,7 +78,7 @@ public class PluginInstanceServiceImpl implements PluginInstanceService {
73 78 }
74 79  
75 80 @Override
76   - public void deletePluginFile(PluginInfoDO pluginInfoDO) {
  81 + public void deletePluginFile(IotPluginInfoDO pluginInfoDO) {
77 82 File file = new File(pluginsDir, pluginInfoDO.getFileName());
78 83 if (!file.exists()) {
79 84 return;
... ... @@ -115,7 +120,7 @@ public class PluginInstanceServiceImpl implements PluginInstanceService {
115 120 }
116 121  
117 122 @Override
118   - public void updatePluginStatus(PluginInfoDO pluginInfoDo, Integer status) {
  123 + public void updatePluginStatus(IotPluginInfoDO pluginInfoDo, Integer status) {
119 124 String pluginKey = pluginInfoDo.getPluginKey();
120 125 PluginWrapper plugin = pluginManager.getPlugin(pluginKey);
121 126  
... ... @@ -147,9 +152,9 @@ public class PluginInstanceServiceImpl implements PluginInstanceService {
147 152 List<PluginWrapper> plugins = pluginManager.getPlugins();
148 153  
149 154 // 1.2 获取插件信息列表并转换为 Map 以便快速查找
150   - List<PluginInfoDO> pluginInfos = pluginInfoMapper.selectList();
151   - Map<String, PluginInfoDO> pluginInfoMap = pluginInfos.stream()
152   - .collect(Collectors.toMap(PluginInfoDO::getPluginKey, Function.identity()));
  155 + List<IotPluginInfoDO> pluginInfos = pluginInfoMapper.selectList();
  156 + Map<String, IotPluginInfoDO> pluginInfoMap = pluginInfos.stream()
  157 + .collect(Collectors.toMap(IotPluginInfoDO::getPluginKey, Function.identity()));
153 158  
154 159 // 1.3 获取本机 IP 和 MAC 地址,mac@uuid
155 160 String ip = NetUtil.getLocalhostStr();
... ... @@ -161,34 +166,42 @@ public class PluginInstanceServiceImpl implements PluginInstanceService {
161 166 String pluginKey = plugin.getPluginId();
162 167  
163 168 // 2.1 查找插件信息
164   - PluginInfoDO pluginInfo = pluginInfoMap.get(pluginKey);
  169 + IotPluginInfoDO pluginInfo = pluginInfoMap.get(pluginKey);
165 170 if (pluginInfo == null) {
166 171 log.error("插件信息不存在,pluginKey = {}", pluginKey);
167 172 continue;
168 173 }
169 174  
170 175 // 2.2 情况一:如果插件实例不存在,则创建
171   - PluginInstanceDO pluginInstance = pluginInstanceMapper.selectByMainIdAndPluginId(mainId,
  176 + IotPluginInstanceDO pluginInstance = pluginInstanceMapper.selectByMainIdAndPluginId(mainId,
172 177 pluginInfo.getId());
173   - if (pluginInstance == null) {
174   - // 4.4 如果插件实例不存在,则创建
175   - pluginInstance = PluginInstanceDO.builder()
176   - .pluginId(pluginInfo.getId())
177   - .mainId(MAIN_ID + "-" + mac)
178   - .ip(ip)
179   - .port(port)
180   - .heartbeatAt(System.currentTimeMillis())
181   - .build();
182   - pluginInstanceMapper.insert(pluginInstance);
183   - } else {
184   - // 2.2 情况二:如果存在,则更新 heartbeatAt
185   - PluginInstanceDO updatePluginInstance = PluginInstanceDO.builder()
186   - .id(pluginInstance.getId())
187   - .heartbeatAt(System.currentTimeMillis())
188   - .build();
189   - pluginInstanceMapper.updateById(updatePluginInstance);
190   - }
  178 + // TODO @芋艿:稍后优化;
  179 +// if (pluginInstance == null) {
  180 +// // 4.4 如果插件实例不存在,则创建
  181 +// pluginInstance = PluginInstanceDO.builder()
  182 +// .pluginId(pluginInfo.getId())
  183 +// .mainId(MAIN_ID + "-" + mac)
  184 +// .hostIp(ip)
  185 +// .port(port)
  186 +// .heartbeatAt(System.currentTimeMillis())
  187 +// .build();
  188 +// pluginInstanceMapper.insert(pluginInstance);
  189 +// } else {
  190 +// // 2.2 情况二:如果存在,则更新 heartbeatAt
  191 +// PluginInstanceDO updatePluginInstance = PluginInstanceDO.builder()
  192 +// .id(pluginInstance.getId())
  193 +// .heartbeatAt(System.currentTimeMillis())
  194 +// .build();
  195 +// pluginInstanceMapper.updateById(updatePluginInstance);
  196 +// }
191 197 }
192 198 }
193 199  
  200 + // ========== 设备与插件的映射操作 ==========
  201 +
  202 + @Override
  203 + public void updateDevicePluginInstanceProcessIdAsync(String deviceKey, String processId) {
  204 + devicePluginProcessIdRedisDAO.put(deviceKey, processId);
  205 + }
  206 +
194 207 }
195 208 \ No newline at end of file
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/resources/mapper/plugininstance/PluginInstanceMapper.xml
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3   -<mapper namespace="cn.iocoder.yudao.module.iot.dal.mysql.plugin.PluginInstanceMapper">
  3 +<mapper namespace="cn.iocoder.yudao.module.iot.dal.mysql.plugin.IotPluginInstanceMapper">
4 4  
5 5 <!--
6 6 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
... ...
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-common/src/main/java/cn/iocoder/yudao/module/iot/plugin/common/util/IotPluginCommonUtils.java 0 → 100644
  1 +package cn.iocoder.yudao.module.iot.plugin.common.util;
  2 +
  3 +import cn.hutool.core.util.IdUtil;
  4 +import cn.hutool.core.util.StrUtil;
  5 +import cn.hutool.system.SystemUtil;
  6 +
  7 +/**
  8 + * IoT 插件的通用工具类
  9 + *
  10 + * 芋道源码
  11 + */
  12 +public class IotPluginCommonUtils {
  13 +
  14 + /**
  15 + * 流程实例的进程编号
  16 + */
  17 + private static String processId;
  18 +
  19 + public static String getProcessId() {
  20 + if (StrUtil.isEmpty(processId)) {
  21 + initProcessId();
  22 + }
  23 + return processId;
  24 + }
  25 +
  26 + private synchronized static void initProcessId() {
  27 + processId = String.format("%s@%d@%s", // IP@PID@${uuid}
  28 + SystemUtil.getHostInfo().getAddress(), SystemUtil.getCurrentPID(), IdUtil.fastSimpleUUID());
  29 + }
  30 +
  31 +}
... ...
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/pom.xml
... ... @@ -128,6 +128,12 @@
128 128 <version>${revision}</version>
129 129 </dependency>
130 130  
  131 + <!-- Web 相关 -->
  132 + <dependency>
  133 + <groupId>org.springframework.boot</groupId>
  134 + <artifactId>spring-boot-starter-web</artifactId>
  135 + </dependency>
  136 +
131 137 <!-- 工具类相关 -->
132 138 <dependency>
133 139 <groupId>io.vertx</groupId>
... ...
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/HttpPluginSpringbootApplication.java renamed to yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/IotHttpPluginApplication.java
... ... @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.iot.plugin.http;
2 2  
3 3 import lombok.extern.slf4j.Slf4j;
4 4 import org.springframework.boot.SpringApplication;
  5 +import org.springframework.boot.WebApplicationType;
5 6 import org.springframework.boot.autoconfigure.SpringBootApplication;
6 7 import org.springframework.context.ConfigurableApplicationContext;
7 8  
... ... @@ -10,10 +11,12 @@ import org.springframework.context.ConfigurableApplicationContext;
10 11 */
11 12 @Slf4j
12 13 @SpringBootApplication
13   -public class HttpPluginSpringbootApplication {
  14 +public class IotHttpPluginApplication {
14 15  
15 16 public static void main(String[] args) {
16   - ConfigurableApplicationContext context = SpringApplication.run(HttpPluginSpringbootApplication.class, args);
  17 + SpringApplication application = new SpringApplication(IotHttpPluginApplication.class);
  18 + application.setWebApplicationType(WebApplicationType.NONE);
  19 + ConfigurableApplicationContext context = application.run(args);
17 20  
18 21 // 手动获取 VertxService 并启动
19 22 // TODO @haohao:可以放在 bean 的 init 里么?回复:会和插件模式冲突 @芋艿,测试下
... ...
yudao-module-iot/yudao-module-iot-plugins/yudao-module-iot-plugin-http/src/main/java/cn/iocoder/yudao/module/iot/plugin/http/upstream/router/IotDevicePropertyReportVertxHandler.java
... ... @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.iot.api.device.IotDeviceUpstreamApi;
7 7 import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDevicePropertyReportReqDTO;
8 8 import cn.iocoder.yudao.module.iot.api.device.dto.control.upstream.IotDeviceStateUpdateReqDTO;
9 9 import cn.iocoder.yudao.module.iot.enums.device.IotDeviceStateEnum;
  10 +import cn.iocoder.yudao.module.iot.plugin.common.util.IotPluginCommonUtils;
10 11 import io.vertx.core.Handler;
11 12 import io.vertx.ext.web.RequestBody;
12 13 import io.vertx.ext.web.RoutingContext;
... ... @@ -50,19 +51,17 @@ public class IotDevicePropertyReportVertxHandler implements Handler&lt;RoutingConte
50 51 String id = jsonData.getStr("id");
51 52  
52 53 try {
53   - // TODO @haohao:pluginKey 需要设置
54 54 // 设备上线
55 55 deviceUpstreamApi.updateDeviceState(((IotDeviceStateUpdateReqDTO)
56 56 new IotDeviceStateUpdateReqDTO().setRequestId(IdUtil.fastSimpleUUID())
57   - .setPluginKey("http")
58   - .setReportTime(LocalDateTime.now())
  57 + .setProcessId(IotPluginCommonUtils.getProcessId()).setReportTime(LocalDateTime.now())
59 58 .setProductKey(productKey).setDeviceName(deviceName))
60 59 .setState(IotDeviceStateEnum.ONLINE.getState()));
61 60  
62 61 // 属性上报
63 62 deviceUpstreamApi.reportDeviceProperty(((IotDevicePropertyReportReqDTO)
64 63 new IotDevicePropertyReportReqDTO().setRequestId(IdUtil.fastSimpleUUID())
65   - .setPluginKey("http").setReportTime(LocalDateTime.now())
  64 + .setProcessId(IotPluginCommonUtils.getProcessId()).setReportTime(LocalDateTime.now())
66 65 .setProductKey(productKey).setDeviceName(deviceName))
67 66 .setProperties((Map<String, Object>) requestBody.asJsonObject().getMap().get("properties")));
68 67  
... ...