diff --git a/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java b/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java index 33e97e8c..d9fced7c 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java +++ b/main/manager-api/src/main/java/xiaozhi/common/constant/Constant.java @@ -91,6 +91,15 @@ public interface Constant { */ String SERVER_WEBSOCKET = "server.websocket"; + /** + * mqtt gateway 配置 + */ + String SERVER_MQTT_GATEWAY = "server.mqtt_gateway"; + + /** + * websocket地址 + */ + /** * ota地址 */ diff --git a/main/manager-api/src/main/java/xiaozhi/common/utils/JsonUtils.java b/main/manager-api/src/main/java/xiaozhi/common/utils/JsonUtils.java index 288dae9a..093f2acf 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/utils/JsonUtils.java +++ b/main/manager-api/src/main/java/xiaozhi/common/utils/JsonUtils.java @@ -66,5 +66,5 @@ public class JsonUtils { throw new RuntimeException(e); } } - + } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/device/controller/OTAController.java b/main/manager-api/src/main/java/xiaozhi/modules/device/controller/OTAController.java index 05d36e9a..7a826a33 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/device/controller/OTAController.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/device/controller/OTAController.java @@ -78,6 +78,10 @@ public class OTAController { @GetMapping @Hidden public ResponseEntity getOTA() { + String mqttUdpConfig = sysParamsService.getValue(Constant.SERVER_MQTT_GATEWAY, false); + if(StringUtils.isBlank(mqttUdpConfig)) { + return ResponseEntity.ok("OTA接口不正常,缺少websocket地址,请登录智控台,在参数管理找到【server.mqtt_udp】配置"); + } String wsUrl = sysParamsService.getValue(Constant.SERVER_WEBSOCKET, true); if (StringUtils.isBlank(wsUrl) || wsUrl.equals("null")) { return ResponseEntity.ok("OTA接口不正常,缺少websocket地址,请登录智控台,在参数管理找到【server.websocket】配置"); diff --git a/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceReportRespDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceReportRespDTO.java index f938001e..5c53b788 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceReportRespDTO.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceReportRespDTO.java @@ -22,6 +22,9 @@ public class DeviceReportRespDTO { @Schema(description = "WebSocket配置") private Websocket websocket; + + @Schema(description = "MQTT Gateway配置") + private MQTT mqtt; @Getter @Setter @@ -70,4 +73,21 @@ public class DeviceReportRespDTO { @Schema(description = "WebSocket服务器地址") private String url; } + + @Getter + @Setter + public static class MQTT { + @Schema(description = "MQTT 配置网址") + private String endpoint; + @Schema(description = "MQTT 客户端唯一标识符") + private String client_id; + @Schema(description = "MQTT 认证用户名") + private String username; + @Schema(description = "MQTT 认证密码") + private String password; + @Schema(description = "ESP32 发布消息的主题") + private String publish_topic; + @Schema(description = "ESP32 订阅的主题") + private String subscribe_topic; + } } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/device/service/impl/DeviceServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/device/service/impl/DeviceServiceImpl.java index 3cff111d..9b0e4a70 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/device/service/impl/DeviceServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/device/service/impl/DeviceServiceImpl.java @@ -175,6 +175,24 @@ public class DeviceServiceImpl extends BaseServiceImpl } response.setWebsocket(websocket); + + // 添加MQTT UDP配置 + // 从系统参数获取WebSocket URL,如果未配置不使用默认值 + String mqttUdpConfig = sysParamsService.getValue(Constant.SERVER_MQTT_GATEWAY, false); + if(!StringUtils.isBlank(mqttUdpConfig)) { + DeviceReportRespDTO.MQTT mqtt= new DeviceReportRespDTO.MQTT(); + mqtt.setEndpoint(mqttUdpConfig); + mqtt.setClient_id(clientId); + String userNameString = deviceById.getId().replace(":", "_"); + mqtt.setUsername(userNameString); + mqtt.setPassword(deviceById.getBoard()); + String topicString = deviceById.getBoard() + '/' + deviceById.getAgentId(); + mqtt.setPublish_topic(topicString); + String subscribeString = "devices/p2p/"+userNameString; + mqtt.setSubscribe_topic(subscribeString); + response.setMqtt(mqtt); + } + if (deviceById != null) { // 如果设备存在,则异步更新上次连接时间和版本信息 diff --git a/main/manager-api/src/main/resources/db/changelog/202506152342.sql b/main/manager-api/src/main/resources/db/changelog/202506152342.sql new file mode 100644 index 00000000..a18dd8ef --- /dev/null +++ b/main/manager-api/src/main/resources/db/changelog/202506152342.sql @@ -0,0 +1,3 @@ +delete from `sys_params` where id = 108; +INSERT INTO `sys_params` (id, param_code, param_value, value_type, param_type, remark) VALUES (108, 'server.mqtt_udp', 'null', 'string', 1, 'mqtt udp 配置'); + diff --git a/main/manager-api/src/main/resources/db/changelog/202506152350.sql b/main/manager-api/src/main/resources/db/changelog/202506152350.sql new file mode 100644 index 00000000..917d0425 --- /dev/null +++ b/main/manager-api/src/main/resources/db/changelog/202506152350.sql @@ -0,0 +1,5 @@ +delete from `sys_params` where id = 108; +INSERT INTO `sys_params` (id, param_code, param_value, value_type, param_type, remark) VALUES (108, 'server.mqtt_gateway', 'null', 'string', 1, 'mqtt gateway 配置'); + +delete from `sys_params` where id = 109; +INSERT INTO `sys_params` (id, param_code, param_value, value_type, param_type, remark) VALUES (109, 'server.udp_gateway', 'null', 'string', 1, 'udp gateway 配置'); diff --git a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml index 32ba9f30..4d1d3798 100755 --- a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml @@ -239,4 +239,17 @@ databaseChangeLog: changes: - sqlFile: encoding: utf8 - path: classpath:db/changelog/202506261637.sql \ No newline at end of file + path: classpath:db/changelog/202506261637.sql + id: 202506152342 + author: marlonz + changes: + - sqlFile: + encoding: utf8 + path: classpath:db/changelog/202506152342.sql + - changeSet: + id: 202506152350 + author: marlonz + changes: + - sqlFile: + encoding: utf8 + path: classpath:db/changelog/202506152350.sql diff --git a/main/manager-web/package-lock.json b/main/manager-web/package-lock.json index c104b60c..6d1f5128 100644 --- a/main/manager-web/package-lock.json +++ b/main/manager-web/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "core-js": "^3.41.0", "cross-env": "^7.0.3", + "dotenv": "^16.5.0", "element-ui": "^2.15.14", "flyio": "^0.6.14", "normalize.css": "^8.0.1", @@ -2540,6 +2541,16 @@ } } }, + "node_modules/@vue/cli-service/node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=10" + } + }, "node_modules/@vue/cli-shared-utils": { "version": "5.0.8", "resolved": "https://registry.npmmirror.com/@vue/cli-shared-utils/-/cli-shared-utils-5.0.8.tgz", @@ -4776,12 +4787,15 @@ } }, "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", - "dev": true, + "version": "16.5.0", + "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.5.0.tgz", + "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", + "license": "BSD-2-Clause", "engines": { - "node": ">=10" + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" } }, "node_modules/dotenv-expand": {