【代码优化】IoT:设备下行实现前,相关代码的整理
This commit is contained in:
parent
911c8c7461
commit
5110948db8
|
@ -33,17 +33,13 @@ public enum IotPluginDeployTypeEnum implements ArrayValuable<Integer> {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IotPluginDeployTypeEnum fromDeployType(Integer deployType) {
|
public static IotPluginDeployTypeEnum valueOf(Integer deployType) {
|
||||||
return Arrays.stream(values())
|
return Arrays.stream(values())
|
||||||
.filter(value -> value.getDeployType().equals(deployType))
|
.filter(value -> value.getDeployType().equals(deployType))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isValidDeployType(Integer deployType) {
|
|
||||||
return fromDeployType(deployType) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer[] array() {
|
public Integer[] array() {
|
||||||
return ARRAYS;
|
return ARRAYS;
|
||||||
|
|
|
@ -3,11 +3,11 @@ package cn.iocoder.yudao.module.iot.controller.admin.plugin;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.PluginInfoImportReqVO;
|
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoImportReqVO;
|
||||||
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.PluginInfoPageReqVO;
|
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoPageReqVO;
|
||||||
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.PluginInfoRespVO;
|
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoRespVO;
|
||||||
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.PluginInfoSaveReqVO;
|
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo.PluginInfoDO;
|
import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
|
||||||
import cn.iocoder.yudao.module.iot.service.plugin.PluginInfoService;
|
import cn.iocoder.yudao.module.iot.service.plugin.PluginInfoService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo;
|
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
|
||||||
import lombok.*;
|
|
||||||
import jakarta.validation.constraints.*;
|
|
||||||
|
|
||||||
@Schema(description = "管理后台 - IoT 插件实例新增/修改 Request VO")
|
|
||||||
@Data
|
|
||||||
public class PluginInstanceSaveReqVO {
|
|
||||||
|
|
||||||
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "23864")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@Schema(description = "插件主程序id", requiredMode = Schema.RequiredMode.REQUIRED, example = "23738")
|
|
||||||
@NotEmpty(message = "插件主程序id不能为空")
|
|
||||||
private String mainId;
|
|
||||||
|
|
||||||
@Schema(description = "插件id", requiredMode = Schema.RequiredMode.REQUIRED, example = "26498")
|
|
||||||
@NotNull(message = "插件id不能为空")
|
|
||||||
private Long pluginId;
|
|
||||||
|
|
||||||
@Schema(description = "插件主程序所在ip", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
||||||
@NotEmpty(message = "插件主程序所在ip不能为空")
|
|
||||||
private String ip;
|
|
||||||
|
|
||||||
@Schema(description = "插件主程序端口", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
||||||
@NotNull(message = "插件主程序端口不能为空")
|
|
||||||
private Integer port;
|
|
||||||
|
|
||||||
@Schema(description = "心跳时间,心路时间超过30秒需要剔除", requiredMode = Schema.RequiredMode.REQUIRED)
|
|
||||||
@NotNull(message = "心跳时间,心路时间超过30秒需要剔除不能为空")
|
|
||||||
private Long heartbeatAt;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo;
|
package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo;
|
package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo;
|
package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo;
|
package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||||
import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
|
import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo;
|
package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.instance;
|
||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
@ -8,11 +8,8 @@ import java.time.LocalDateTime;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
|
||||||
// TODO @haohao:建议搞个 plugin,然后里面分 info 和 instance。另外,是不是 info => config 会好点,插件配置?
|
|
||||||
@Schema(description = "管理后台 - IoT 插件实例分页 Request VO")
|
@Schema(description = "管理后台 - IoT 插件实例分页 Request VO")
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
@ToString(callSuper = true)
|
|
||||||
public class PluginInstancePageReqVO extends PageParam {
|
public class PluginInstancePageReqVO extends PageParam {
|
||||||
|
|
||||||
@Schema(description = "插件主程序id", example = "23738")
|
@Schema(description = "插件主程序id", example = "23738")
|
|
@ -1,9 +1,11 @@
|
||||||
package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo;
|
package cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.instance;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.*;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import com.alibaba.excel.annotation.*;
|
|
||||||
|
|
||||||
@Schema(description = "管理后台 - IoT 插件实例 Response VO")
|
@Schema(description = "管理后台 - IoT 插件实例 Response VO")
|
||||||
@Data
|
@Data
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo;
|
package cn.iocoder.yudao.module.iot.dal.dataobject.plugin;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum;
|
import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginDeployTypeEnum;
|
||||||
|
@ -47,6 +47,7 @@ public class PluginInfoDO extends BaseDO {
|
||||||
* 枚举 {@link IotPluginDeployTypeEnum}
|
* 枚举 {@link IotPluginDeployTypeEnum}
|
||||||
*/
|
*/
|
||||||
private Integer deployType;
|
private Integer deployType;
|
||||||
|
// TODO @芋艿:如果是外置的插件,fileName 和 version 的选择~
|
||||||
/**
|
/**
|
||||||
* 插件包文件名
|
* 插件包文件名
|
||||||
*/
|
*/
|
||||||
|
@ -55,6 +56,7 @@ public class PluginInfoDO extends BaseDO {
|
||||||
* 插件版本
|
* 插件版本
|
||||||
*/
|
*/
|
||||||
private String version;
|
private String version;
|
||||||
|
// TODO @芋艿:type 字典的定义
|
||||||
/**
|
/**
|
||||||
* 插件类型
|
* 插件类型
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -64,6 +66,7 @@ public class PluginInfoDO extends BaseDO {
|
||||||
/**
|
/**
|
||||||
* 设备插件协议类型
|
* 设备插件协议类型
|
||||||
*/
|
*/
|
||||||
|
// TODO @芋艿:枚举字段
|
||||||
private String protocol;
|
private String protocol;
|
||||||
/**
|
/**
|
||||||
* 状态
|
* 状态
|
||||||
|
@ -71,6 +74,7 @@ public class PluginInfoDO extends BaseDO {
|
||||||
* 枚举 {@link IotPluginStatusEnum}
|
* 枚举 {@link IotPluginStatusEnum}
|
||||||
*/
|
*/
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
// TODO @芋艿:configSchema、config 示例字段
|
||||||
/**
|
/**
|
||||||
* 插件配置项描述信息
|
* 插件配置项描述信息
|
||||||
*/
|
*/
|
||||||
|
@ -79,6 +83,7 @@ public class PluginInfoDO extends BaseDO {
|
||||||
* 插件配置信息
|
* 插件配置信息
|
||||||
*/
|
*/
|
||||||
private String config;
|
private String config;
|
||||||
|
// TODO @芋艿:script 后续的使用
|
||||||
/**
|
/**
|
||||||
* 插件脚本
|
* 插件脚本
|
||||||
*/
|
*/
|
|
@ -1,7 +1,6 @@
|
||||||
package cn.iocoder.yudao.module.iot.dal.dataobject.plugininstance;
|
package cn.iocoder.yudao.module.iot.dal.dataobject.plugin;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
import cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo.PluginInfoDO;
|
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
@ -28,6 +27,7 @@ public class PluginInstanceDO extends BaseDO {
|
||||||
*/
|
*/
|
||||||
@TableId
|
@TableId
|
||||||
private Long id;
|
private Long id;
|
||||||
|
// TODO @芋艿:找一个更好的字段名
|
||||||
/**
|
/**
|
||||||
* 插件主程序 ID
|
* 插件主程序 ID
|
||||||
*/
|
*/
|
||||||
|
@ -43,10 +43,12 @@ public class PluginInstanceDO extends BaseDO {
|
||||||
* 插件主程序所在 IP
|
* 插件主程序所在 IP
|
||||||
*/
|
*/
|
||||||
private String ip;
|
private String ip;
|
||||||
|
// TODO @芋艿:这个 port 是否有必要记录
|
||||||
/**
|
/**
|
||||||
* 插件主程序端口
|
* 插件主程序端口
|
||||||
*/
|
*/
|
||||||
private Integer port;
|
private Integer port;
|
||||||
|
// TODO @芋艿:downstreamPort 增加,目的:用于下行
|
||||||
|
|
||||||
// TODO @haohao:字段改成 heartbeatTime,LocalDateTime
|
// TODO @haohao:字段改成 heartbeatTime,LocalDateTime
|
||||||
/**
|
/**
|
|
@ -3,12 +3,12 @@ package cn.iocoder.yudao.module.iot.dal.mysql.plugin;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo.PluginInfoDO;
|
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IoT 插件信息 Mapper
|
* IoT 插件信息 Mapper
|
||||||
|
|
|
@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.iot.dal.mysql.plugin;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.PluginInstancePageReqVO;
|
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.instance.PluginInstancePageReqVO;
|
||||||
import cn.iocoder.yudao.module.iot.dal.dataobject.plugininstance.PluginInstanceDO;
|
import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInstanceDO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.iot.emq.callback;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.iot.emq.client.EmqxClient;
|
|
||||||
import cn.iocoder.yudao.module.iot.emq.service.EmqxService;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
|
|
||||||
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
|
|
||||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
// TODO @芋艿:详细再瞅瞅
|
|
||||||
/**
|
|
||||||
* 用于处理MQTT连接的回调,如连接断开、消息到达、消息发布完成、连接完成等事件。
|
|
||||||
*
|
|
||||||
* @author ahh
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
//@Component
|
|
||||||
public class EmqxCallback implements MqttCallbackExtended {
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
@Resource
|
|
||||||
private EmqxService emqxService;
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
@Resource
|
|
||||||
private EmqxClient emqxClient;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void connectionLost(Throwable throwable) {
|
|
||||||
log.info("MQTT 连接断开", throwable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void messageArrived(String topic, MqttMessage mqttMessage) {
|
|
||||||
emqxService.subscribeCallback(topic, mqttMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
|
|
||||||
log.info("消息发送成功: {}", iMqttDeliveryToken.getMessageId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void connectComplete(boolean reconnect, String serverURI) {
|
|
||||||
log.info("MQTT 已连接到服务器: {}", serverURI);
|
|
||||||
emqxService.subscribe(emqxClient.getMqttClient());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.iot.emq.client;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.iot.emq.callback.EmqxCallback;
|
|
||||||
import cn.iocoder.yudao.module.iot.emq.config.MqttConfig;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.eclipse.paho.client.mqttv3.MqttClient;
|
|
||||||
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
|
|
||||||
import org.eclipse.paho.client.mqttv3.MqttException;
|
|
||||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
|
||||||
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MQTT客户端类,负责建立与MQTT服务器的连接,提供发布消息和订阅主题的功能
|
|
||||||
*
|
|
||||||
* @author ahh
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Data
|
|
||||||
//@Component
|
|
||||||
public class EmqxClient {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private EmqxCallback emqxCallback;
|
|
||||||
@Resource
|
|
||||||
private MqttConfig mqttConfig;
|
|
||||||
|
|
||||||
private MqttClient mqttClient;
|
|
||||||
|
|
||||||
public void connect() {
|
|
||||||
if (mqttClient == null) {
|
|
||||||
createMqttClient();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
mqttClient.connect(createMqttOptions());
|
|
||||||
log.info("MQTT客户端连接成功");
|
|
||||||
} catch (MqttException e) {
|
|
||||||
log.error("MQTT客户端连接失败", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createMqttClient() {
|
|
||||||
try {
|
|
||||||
mqttClient = new MqttClient(mqttConfig.getHostUrl(), "yudao" + mqttConfig.getClientId(), new MemoryPersistence());
|
|
||||||
mqttClient.setCallback(emqxCallback);
|
|
||||||
} catch (MqttException e) {
|
|
||||||
log.error("创建MQTT客户端失败", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private MqttConnectOptions createMqttOptions() {
|
|
||||||
MqttConnectOptions options = new MqttConnectOptions();
|
|
||||||
options.setUserName(mqttConfig.getUsername());
|
|
||||||
options.setPassword(mqttConfig.getPassword().toCharArray());
|
|
||||||
options.setConnectionTimeout(mqttConfig.getTimeout());
|
|
||||||
options.setKeepAliveInterval(mqttConfig.getKeepalive());
|
|
||||||
options.setCleanSession(mqttConfig.isClearSession());
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void publish(String topic, String message) {
|
|
||||||
try {
|
|
||||||
if (mqttClient == null || !mqttClient.isConnected()) {
|
|
||||||
connect();
|
|
||||||
}
|
|
||||||
mqttClient.publish(topic, new MqttMessage(message.getBytes()));
|
|
||||||
log.info("消息已发布到主题: {}", topic);
|
|
||||||
} catch (MqttException e) {
|
|
||||||
log.error("消息发布失败", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void subscribe(String topic) {
|
|
||||||
try {
|
|
||||||
if (mqttClient == null || !mqttClient.isConnected()) {
|
|
||||||
connect();
|
|
||||||
}
|
|
||||||
mqttClient.subscribe(topic);
|
|
||||||
log.info("订阅了主题: {}", topic);
|
|
||||||
} catch (MqttException e) {
|
|
||||||
log.error("订阅主题失败", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.iot.emq.config;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
// TODO @芋艿:详细再瞅瞅
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 配置类,用于读取MQTT连接的配置信息,如用户名、密码、连接地址等
|
|
||||||
*
|
|
||||||
* @author ahh
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
//@Component
|
|
||||||
//@ConfigurationProperties("iot.emq")
|
|
||||||
public class MqttConfig {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户名
|
|
||||||
*/
|
|
||||||
private String username;
|
|
||||||
/**
|
|
||||||
* 密码
|
|
||||||
*/
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 连接地址
|
|
||||||
*/
|
|
||||||
private String hostUrl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户Id
|
|
||||||
*/
|
|
||||||
private String clientId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 默认连接话题
|
|
||||||
*/
|
|
||||||
private String defaultTopic;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 超时时间
|
|
||||||
*/
|
|
||||||
private int timeout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保持连接数
|
|
||||||
*/
|
|
||||||
private int keepalive;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否清除session
|
|
||||||
*/
|
|
||||||
private boolean clearSession;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否共享订阅
|
|
||||||
*/
|
|
||||||
private boolean isShared;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分组共享订阅
|
|
||||||
*/
|
|
||||||
private boolean isSharedGroup;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.iot.emq.service;
|
|
||||||
|
|
||||||
import org.eclipse.paho.client.mqttv3.MqttClient;
|
|
||||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
|
||||||
|
|
||||||
// TODO @芋艿:在瞅瞅
|
|
||||||
/**
|
|
||||||
* 用于处理MQTT消息的具体业务逻辑,如订阅回调
|
|
||||||
*
|
|
||||||
* @author ahh
|
|
||||||
*/
|
|
||||||
public interface EmqxService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订阅回调
|
|
||||||
*
|
|
||||||
* @param topic 主题
|
|
||||||
* @param mqttMessage 消息
|
|
||||||
*/
|
|
||||||
void subscribeCallback(String topic, MqttMessage mqttMessage);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订阅主题
|
|
||||||
*
|
|
||||||
* @param client MQTT 客户端
|
|
||||||
*/
|
|
||||||
void subscribe(MqttClient client);
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.iot.emq.service;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.iot.service.device.data.IotDevicePropertyService;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.eclipse.paho.client.mqttv3.MqttClient;
|
|
||||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
|
||||||
import org.springframework.scheduling.annotation.Async;
|
|
||||||
|
|
||||||
// TODO @芋艿:在瞅瞅
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于处理MQTT消息的具体业务逻辑,如订阅回调
|
|
||||||
*
|
|
||||||
* @author ahh
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
// @Service
|
|
||||||
public class EmqxServiceImpl implements EmqxService {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private IotDevicePropertyService iotDeviceDataService;
|
|
||||||
|
|
||||||
// TODO 多线程处理消息
|
|
||||||
@Override
|
|
||||||
@Async
|
|
||||||
public void subscribeCallback(String topic, MqttMessage mqttMessage) {
|
|
||||||
log.info("收到消息,主题: {}, 内容: {}", topic, new String(mqttMessage.getPayload()));
|
|
||||||
// 根据不同的主题,处理不同的业务逻辑
|
|
||||||
if (topic.contains("/property/post")) {
|
|
||||||
// 设备上报数据 topic /sys/f13f57c63e9/dianbiao1/thing/event/property/post
|
|
||||||
// TODO @hao:这块未来可能,搞个 IotTopicUrls 之类?把拼接和解析的逻辑,收敛
|
|
||||||
String productKey = topic.split("/")[2];
|
|
||||||
String deviceName = topic.split("/")[3];
|
|
||||||
String message = new String(mqttMessage.getPayload());
|
|
||||||
// IotDevicePropertyReportReqDTO createDTO = IotDevicePropertyReportReqDTO.builder()
|
|
||||||
// .productKey(productKey)
|
|
||||||
// .deviceName(deviceName)
|
|
||||||
// .properties(message) // TODO 芋艿:临时去掉,看看
|
|
||||||
// .build();
|
|
||||||
// iotDeviceDataService.saveDeviceProperty(createDTO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void subscribe(MqttClient client) {
|
|
||||||
try {
|
|
||||||
// 订阅默认主题,可以根据需要修改
|
|
||||||
client.subscribe("/sys/+/+/#", 1);
|
|
||||||
log.info("订阅默认主题成功");
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("订阅默认主题失败", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.iot.emq.start;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.iot.emq.client.EmqxClient;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.springframework.boot.ApplicationArguments;
|
|
||||||
import org.springframework.boot.ApplicationRunner;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
// TODO @芋艿:在瞅瞅
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于在应用启动时自动连接MQTT服务器
|
|
||||||
*
|
|
||||||
* @author ahh
|
|
||||||
*/
|
|
||||||
//@Component
|
|
||||||
public class EmqxStart implements ApplicationRunner {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private EmqxClient emqxClient;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(ApplicationArguments applicationArguments) {
|
|
||||||
emqxClient.connect();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.iot.framework.plugin;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||||
import cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo.PluginInfoDO;
|
import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
|
||||||
import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
|
import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
|
||||||
import cn.iocoder.yudao.module.iot.service.plugin.PluginInfoService;
|
import cn.iocoder.yudao.module.iot.service.plugin.PluginInfoService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
|
@ -18,7 +18,6 @@ public class UnifiedConfiguration {
|
||||||
private String pluginsDir;
|
private String pluginsDir;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
// @DependsOn("deviceDataApiImpl")
|
|
||||||
public SpringPluginManager pluginManager() {
|
public SpringPluginManager pluginManager() {
|
||||||
log.info("[init][实例化 SpringPluginManager]");
|
log.info("[init][实例化 SpringPluginManager]");
|
||||||
SpringPluginManager springPluginManager = new SpringPluginManager(Paths.get(pluginsDir)) {
|
SpringPluginManager springPluginManager = new SpringPluginManager(Paths.get(pluginsDir)) {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package cn.iocoder.yudao.module.iot.service.plugin;
|
package cn.iocoder.yudao.module.iot.service.plugin;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.PluginInfoPageReqVO;
|
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoPageReqVO;
|
||||||
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.PluginInfoSaveReqVO;
|
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo.PluginInfoDO;
|
import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
|
||||||
import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
|
import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
|
@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.iot.service.plugin;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.PluginInfoPageReqVO;
|
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoPageReqVO;
|
||||||
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.PluginInfoSaveReqVO;
|
import cn.iocoder.yudao.module.iot.controller.admin.plugin.vo.info.PluginInfoSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo.PluginInfoDO;
|
import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
|
||||||
import cn.iocoder.yudao.module.iot.dal.mysql.plugin.PluginInfoMapper;
|
import cn.iocoder.yudao.module.iot.dal.mysql.plugin.PluginInfoMapper;
|
||||||
import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
|
import cn.iocoder.yudao.module.iot.enums.plugin.IotPluginStatusEnum;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package cn.iocoder.yudao.module.iot.service.plugin;
|
package cn.iocoder.yudao.module.iot.service.plugin;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo.PluginInfoDO;
|
import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,6 +10,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||||
*/
|
*/
|
||||||
public interface PluginInstanceService {
|
public interface PluginInstanceService {
|
||||||
|
|
||||||
|
// TODO @芋艿:这个是否应该放到 plugin 主动心跳,而是 server 自己心跳
|
||||||
/**
|
/**
|
||||||
* 上报插件实例(心跳)
|
* 上报插件实例(心跳)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.iot.service.plugin;
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.core.net.NetUtil;
|
import cn.hutool.core.net.NetUtil;
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.iocoder.yudao.module.iot.dal.dataobject.plugininfo.PluginInfoDO;
|
import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInfoDO;
|
||||||
import cn.iocoder.yudao.module.iot.dal.dataobject.plugininstance.PluginInstanceDO;
|
import cn.iocoder.yudao.module.iot.dal.dataobject.plugin.PluginInstanceDO;
|
||||||
import cn.iocoder.yudao.module.iot.dal.mysql.plugin.PluginInfoMapper;
|
import cn.iocoder.yudao.module.iot.dal.mysql.plugin.PluginInfoMapper;
|
||||||
import cn.iocoder.yudao.module.iot.dal.mysql.plugin.PluginInstanceMapper;
|
import cn.iocoder.yudao.module.iot.dal.mysql.plugin.PluginInstanceMapper;
|
||||||
import cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants;
|
import cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants;
|
||||||
|
@ -40,13 +40,15 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PluginInstanceServiceImpl implements PluginInstanceService {
|
public class PluginInstanceServiceImpl implements PluginInstanceService {
|
||||||
|
|
||||||
// TODO @haohao:mac@uuid
|
// TODO @haohao:mac@uuid
|
||||||
public static final String MAIN_ID = IdUtil.fastSimpleUUID();
|
public static final String MAIN_ID = IdUtil.fastSimpleUUID();
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private PluginInfoMapper pluginInfoMapper;
|
private PluginInfoMapper pluginInfoMapper;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private PluginInstanceMapper pluginInstanceMapper;
|
private PluginInstanceMapper pluginInstanceMapper;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private SpringPluginManager pluginManager;
|
private SpringPluginManager pluginManager;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue