소스 검색

更新!

TRX 1 년 전
부모
커밋
1f9e95877d

+ 7 - 0
OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/mqtt/DeviceInfoAddParam.java

@@ -3,6 +3,7 @@ package com.zhongshu.iot.client.model.mqtt;
 import cn.hutool.json.JSONObject;
 import com.github.microservice.models.type.DeviceSpecType;
 import com.github.microservice.models.type.DeviceType;
+import com.github.microservice.models.type.RegistType;
 import com.zhongshu.iot.client.model.baseParam.SuperParam;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
@@ -14,12 +15,18 @@ import lombok.Data;
 @Data
 public class DeviceInfoAddParam extends SuperParam {
 
+    @Schema(description = "mqtt账号名称")
+    private String mqttUserName;
+
     @Schema(description = "设备ID")
     private String deviceId;
 
     @Schema(description = "设备名称")
     private String deviceName;
 
+    @Schema(description = "设备注册方式")
+    private RegistType registType;
+
     @Schema(description = "设备类型:消费机 闸机")
     private DeviceType deviceType;
 

+ 49 - 0
OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/mqtt/DeviceInfoRegistParam.java

@@ -0,0 +1,49 @@
+package com.zhongshu.iot.client.model.mqtt;
+
+import cn.hutool.json.JSONObject;
+import com.github.microservice.models.type.DeviceSpecType;
+import com.github.microservice.models.type.DeviceType;
+import com.github.microservice.models.type.RegistType;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * @author TRX
+ * @date 2024/5/16
+ */
+@Data
+public class DeviceInfoRegistParam {
+
+    @Schema(description = "mqtt账号名称")
+    private String mqttUserName;
+
+    @Schema(description = "网关ID")
+    private String gateWayId;
+
+    @Schema(description = "设备ID")
+    private String deviceId;
+
+    @Schema(description = "设备名称")
+    private String deviceName;
+
+    @Schema(description = "设备类型:消费机 闸机")
+    private DeviceType deviceType;
+
+    @Schema(description = "设备型号")
+    private DeviceSpecType deviceModel;
+
+    @Schema(description = "ip地址")
+    private String ip;
+
+    @Schema(description = "所属项目")
+    private String projectInfoCode;
+
+    @Schema(description = "固件版本")
+    private String firmwareVersion;
+
+    @Schema(description = "连接参数")
+    private JSONObject connectParam;
+
+    @Schema(description = "设备类型")
+    private String deviceCate;
+}

+ 5 - 4
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/mqtt/DeviceInfo.java

@@ -1,10 +1,7 @@
 package com.zhongshu.iot.server.core.domain.iot.mqtt;
 
 import cn.hutool.json.JSONObject;
-import com.github.microservice.models.type.DeviceSpecType;
-import com.github.microservice.models.type.DeviceState;
-import com.github.microservice.models.type.DeviceType;
-import com.github.microservice.models.type.OnLineState;
+import com.github.microservice.models.type.*;
 import com.zhongshu.iot.server.core.domain.base.SuperEntity;
 import com.zhongshu.iot.server.core.domain.iot.IotTemplate;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -38,6 +35,9 @@ public class DeviceInfo extends SuperEntity {
     @Schema(description = "设备类型:消费机 闸机")
     private DeviceType deviceType;
 
+    @Schema(description = "设备注册方式")
+    private RegistType registType = RegistType.Gateway;
+
     @Schema(description = "设备型号")
     private DeviceSpecType deviceModel;
 
@@ -81,4 +81,5 @@ public class DeviceInfo extends SuperEntity {
 
     @Schema(description = "心跳间隔,单位:秒")
     private Long hbInterval = 30l;
+
 }

+ 14 - 7
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/device/DeviceInfoService.java

@@ -32,6 +32,7 @@ import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
 
 /**
  * @author TRX
@@ -61,6 +62,9 @@ public class DeviceInfoService {
     @Autowired
     DeviceSyncFullCardService deviceSyncFullCardService;
 
+    @Autowired
+    private GateWayUserInfoService gateWayUserInfoService;
+
     public ResultContent initSyncAllDevice() {
         // 同步所有的设备
         List<DeviceInfo> deviceInfos = deviceInfoDao.findAll();
@@ -88,12 +92,7 @@ public class DeviceInfoService {
         BeanUtils.copyProperties(param, deviceInfo, "id");
         deviceInfo.setLastOnlineTime(System.currentTimeMillis());
         deviceInfo.setOnLineState(OnLineState.OnLine);
-        if (StringUtils.isNotEmpty(param.getDeviceCate())) {
-            DeviceType deviceType = CommonUtil.getEnumByName(DeviceType.class, param.getDeviceCate());
-            if (deviceType != null) {
-                deviceInfo.setDeviceType(deviceType);
-            }
-        }
+
         // 项目
         if (StringUtils.isNotEmpty(param.getProjectInfoCode())) {
             ProjectInfo projectInfo = projectInfoDao.findTopByCode(param.getProjectInfoCode());
@@ -103,7 +102,15 @@ public class DeviceInfoService {
         deviceInfo.setLastOnlineTime(System.currentTimeMillis());
         deviceInfoDao.save(deviceInfo);
 
-        operationLogsService.addLogs(String.format("添加了设备;%s", deviceInfo.getDeviceName()), LogsLevel.Middle, deviceInfo);
+
+        DeviceInfo finalDeviceInfo = deviceInfo;
+        CompletableFuture.runAsync(() -> {
+            // 日志
+            operationLogsService.addLogs(String.format("添加了设备;%s", finalDeviceInfo.getDeviceName()), LogsLevel.Middle, finalDeviceInfo);
+            // 跟新账号的绑定设备数量
+            gateWayUserInfoService.updateBindNumber(finalDeviceInfo.getMqttUserName());
+        });
+
         return ResultContent.buildSuccess(deviceInfo);
     }
 

+ 157 - 2
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/device/GateWayInfoService.java

@@ -4,9 +4,12 @@ import cn.hutool.json.JSONUtil;
 import com.github.microservice.http.APIResponseModel;
 import com.github.microservice.models.common.CommonResult;
 import com.github.microservice.models.project.ProjectConfigQueryParam;
+import com.github.microservice.models.type.DeviceType;
 import com.github.microservice.models.type.OnLineState;
+import com.github.microservice.models.type.RegistType;
 import com.github.microservice.net.ResultContent;
 import com.zhongshu.iot.client.model.mqtt.*;
+import com.zhongshu.iot.client.type.type.LogsLevel;
 import com.zhongshu.iot.server.core.dao.mqtt.*;
 import com.zhongshu.iot.server.core.domain.iot.mqtt.*;
 import com.zhongshu.iot.server.core.httpRequest.ApiRequestService;
@@ -14,6 +17,7 @@ import com.zhongshu.iot.server.core.httpRequest.conf.FullCardAPIConfig;
 import com.zhongshu.iot.server.core.service.base.SuperService;
 import com.zhongshu.iot.server.core.service.iot.IotServiceImpl;
 import com.zhongshu.iot.server.core.service.sync.DeviceSyncFullCardService;
+import com.zhongshu.iot.server.core.util.CommonUtil;
 import com.zhongshu.iot.server.core.util.DateUtils;
 import com.zhongshu.iot.server.core.util.bean.BeanUtils;
 import com.zhongshu.iot.server.core.util.mqtt.MqttTopicUtils;
@@ -37,6 +41,7 @@ import javax.management.remote.JMXConnectorFactory;
 import javax.management.remote.JMXServiceURL;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
 
 /**
  * @author TRX
@@ -148,6 +153,9 @@ public class GateWayInfoService extends SuperService {
         if (StringUtils.isEmpty(param.getProjectInfoCode())) {
             return ResultContent.buildFail("projectInfoCode不能为空");
         }
+        if (param.getHbInterval() != null && param.getHbInterval() <= 0) {
+            return ResultContent.buildFail("hbInterval不符合规范");
+        }
         ProjectInfo projectInfo = null;
         if (StringUtils.isNotEmpty(param.getProjectInfoCode())) {
             projectInfo = projectInfoDao.findTopByCode(param.getProjectInfoCode());
@@ -156,8 +164,7 @@ public class GateWayInfoService extends SuperService {
             return ResultContent.buildFail("projectInfoCode不存在");
         }
         GateWayUserInfo gateWayUserInfo = gateWayUserInfoDao.findTopByUserName(param.getMqttUserName());
-        if (StringUtils.isNotEmpty(gateWayUserInfo.getProjectCode()) &&
-                !gateWayUserInfo.getProjectCode().equals(param.getProjectInfoCode())) {
+        if (StringUtils.isNotEmpty(gateWayUserInfo.getProjectCode()) && !gateWayUserInfo.getProjectCode().equals(param.getProjectInfoCode())) {
             return ResultContent.buildFail("projectInfoCode不匹配");
         }
 
@@ -184,12 +191,160 @@ public class GateWayInfoService extends SuperService {
         return ResultContent.buildSuccess(gateWayInfo);
     }
 
+    /**
+     * 注册设备
+     *
+     * @param dataId
+     * @param dataStr
+     * @return
+     */
+    public ResultContent registDevice(String dataId, String dataStr) {
+        log.info("registDevice: {}", dataId);
+        CommonResult commonResult = new CommonResult();
+        OperationMessage operationMessage = operationMessageDao.findTopByDataId(dataId);
+        commonResult.setMessageId(dataId);
+        if (ObjectUtils.isEmpty(operationMessage)) {
+            commonResult.setFailed("数据不存在");
+            return ResultContent.buildSuccess(commonResult);
+        }
+        ResultContent<GateWayUserInfo> resultContent = gateWayUserInfoService.verifyMqttUser(operationMessage.getTopic());
+        if (resultContent.isFailed()) {
+            commonResult.setFailed(resultContent.getMsg());
+            return ResultContent.buildSuccess(commonResult);
+        }
+
+        // 注册设备参数
+        DeviceInfoRegistParam param = null;
+        try {
+            param = JSONUtil.toBean(dataStr, DeviceInfoRegistParam.class);
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            commonResult.setFailed(resultContent.getMsg());
+            return ResultContent.buildSuccess(commonResult);
+        }
+        // 连接账号信息
+        GateWayUserInfo gateWayUserInfo = resultContent.getContent();
+        param.setMqttUserName(gateWayUserInfo.getUserName());
+
+        // 添加设备
+        ResultContent<DeviceInfo> content = addDevice(param);
+        if (content.isSuccess()) {
+        } else {
+            commonResult.setFailed(content.getMsg());
+            return ResultContent.buildSuccess(commonResult);
+        }
+        commonResult.setSuccess("注册成功");
+        return ResultContent.buildSuccess(commonResult);
+    }
+
+    /**
+     * 注册设备
+     *
+     * @param param
+     * @return
+     */
+    public ResultContent<DeviceInfo> addDevice(DeviceInfoRegistParam param) {
+        if (StringUtils.isEmpty(param.getDeviceId())) {
+            return ResultContent.buildFail("deviceId不能为空");
+        }
+        if (StringUtils.isEmpty(param.getDeviceName())) {
+            return ResultContent.buildFail("deviceName不能为空");
+        }
+        if (StringUtils.isEmpty(param.getDeviceCate())) {
+            return ResultContent.buildFail("deviceCate不能为空");
+        }
+        if (StringUtils.isEmpty(param.getProjectInfoCode())) {
+            return ResultContent.buildFail("projectInfoCode不能为空");
+        }
+        ProjectInfo projectInfo = projectInfoDao.findTopByCode(param.getProjectInfoCode());
+        if (ObjectUtils.isEmpty(projectInfo)) {
+            return ResultContent.buildFail("projectInfoCode不存在");
+        }
+
+        RegistType registType = RegistType.Gateway;
+        GateWayInfo gateWayInfo;
+        if (StringUtils.isNotEmpty(param.getGateWayId())) {
+            gateWayInfo = gateWayInfoDao.findTopByGateWayId(param.getGateWayId());
+            if (ObjectUtils.isEmpty(gateWayInfo)) {
+                return ResultContent.buildFail("gateWayId数据不存在");
+            }
+            registType = RegistType.Gateway;
+        } else {
+            gateWayInfo = null;
+            registType = RegistType.DirectConnection;
+        }
+
+        // 封装参数
+        List<DeviceInfoAddParam> devices = new ArrayList<>();
+        DeviceInfoAddParam deviceInfoAddParam = new DeviceInfoAddParam();
+        BeanUtils.copyProperties(param, deviceInfoAddParam);
+        deviceInfoAddParam.setRegistType(registType);
+        if (StringUtils.isNotEmpty(param.getDeviceCate())) {
+            DeviceType deviceType = CommonUtil.getEnumByName(DeviceType.class, param.getDeviceCate());
+            if (deviceType == null) {
+                return ResultContent.buildFail("deviceCate不存在");
+            }
+            if (deviceType != null) {
+                deviceInfoAddParam.setDeviceType(deviceType);
+            }
+        }
+        devices.add(deviceInfoAddParam);
+
+        // 设备列表
+        List<DeviceInfo> deviceInfos = new ArrayList<>();
+        if (ObjectUtils.isNotEmpty(devices)) {
+            // 绑定网关和设备的关系
+            for (DeviceInfoAddParam device : devices) {
+                // 保存设备信息
+                ResultContent<DeviceInfo> resultContent = deviceInfoService.addDeviceInfo(device);
+                DeviceInfo deviceInfo = resultContent.getContent();
+
+                if (registType == RegistType.DirectConnection) {
+                    // 直连
+                    List<GateWay2Device> _list = gateWay2DeviceDao.findByDeviceInfo(deviceInfo);
+                    gateWay2DeviceDao.deleteAll(_list);
+                } else if (registType == RegistType.Gateway) {
+                    // 网关注册
+                    // 设备可以绑定到多个网关,一个网关只能绑定设备一次
+                    GateWay2Device gateWay2Device = gateWay2DeviceDao.findTopByDeviceInfoOrderByUpdateTimeDesc(deviceInfo);
+                    if (ObjectUtils.isEmpty(gateWay2Device)) {
+                        gateWay2Device = new GateWay2Device();
+                        gateWay2Device.setState(OnLineState.OnLine);
+                    } else {
+                    }
+                    gateWay2Device.setGateWayInfo(gateWayInfo);
+                    gateWay2Device.setDeviceInfo(deviceInfo);
+                    gateWay2Device.setGateWayId(gateWayInfo.getGateWayId());
+                    gateWay2Device.setDeviceId(deviceInfo.getDeviceId());
+
+                    gateWay2Device.setBindTimeStr(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
+                    gateWay2DeviceDao.save(gateWay2Device);
+                }
+                deviceInfos.add(deviceInfo);
+
+                // 更新设备的topic
+                iotService.updateAllDeviceIotMainGateWayInfo(deviceInfo);
+            }
+        }
+
+        CompletableFuture.runAsync(() -> {
+            // 更新网关的权限
+            jmxSyncService.syncSecurityToMQTTService(gateWayInfo);
+            log.info("设备注册成功:{}", deviceInfos.size());
+            // 同步设备
+            deviceSyncFullCardService.noticeSyncDevice(deviceInfos);
+        });
+
+        return ResultContent.buildSuccess();
+    }
+
     /**
      * 注册网关
      *
      * @param param
      * @return
      */
+    @Deprecated
     public ResultContent<MqttInfoReturnModel> registerGateWay(GateWayInfoAddParam param) {
         ProjectInfo projectInfo = projectInfoDao.findTopByCode(param.getProjectInfoCode());
         if (ObjectUtils.isEmpty(projectInfo)) {

+ 13 - 0
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/device/GateWayUserInfoService.java

@@ -220,6 +220,19 @@ public class GateWayUserInfoService {
         if (ObjectUtils.isEmpty(entity)) {
             return ResultContent.buildFail("数据不存在");
         }
+        if (param.getNumber() == null || param.getNumber() <= 0) {
+            return ResultContent.buildFail("number不符合规范");
+        }
+        if (param.getNumber() < entity.getBindNumber()) {
+            return ResultContent.buildFail(String.format("number不能小于已连接的数量: %d", entity.getBindNumber()));
+        }
+        ProjectInfo projectInfo = null;
+        if (StringUtils.isNotEmpty(entity.getProjectCode())) {
+            projectInfo = projectInfoDao.findTopByCode(entity.getProjectCode());
+            if (ObjectUtils.isEmpty(projectInfo)) {
+                return ResultContent.buildFail("projectCode不存在");
+            }
+        }
         BeanUtils.copyProperties(param, entity);
         gateWayUserInfoDao.save(entity);
         return ResultContent.buildSuccess();

+ 8 - 6
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/device/JMXSyncService.java

@@ -208,12 +208,14 @@ public class JMXSyncService {
      * @return
      */
     public ResultContent syncSecurityToMQTTService(GateWayInfo gateWayInfo) {
-        //todo同步权限
-        List<MqttInfo> list = mqttInfoDao.findAll();
-        log.info("syncSecurityToMQTTService {}", list.size());
-        if (ObjectUtils.isNotEmpty(list)) {
-            for (MqttInfo mqttInfo : list) {
-                syncMqttSecuritySettings(mqttInfo, List.of(gateWayInfo));
+        if (ObjectUtils.isNotEmpty(gateWayInfo)) {
+            //todo同步权限
+            List<MqttInfo> list = mqttInfoDao.findAll();
+            log.info("syncSecurityToMQTTService {}", list.size());
+            if (ObjectUtils.isNotEmpty(list)) {
+                for (MqttInfo mqttInfo : list) {
+                    syncMqttSecuritySettings(mqttInfo, List.of(gateWayInfo));
+                }
             }
         }
         return ResultContent.buildSuccess();

+ 6 - 1
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/iotPlatform/impl/RegisterDeviceTopic.java

@@ -4,8 +4,10 @@ package com.zhongshu.iot.server.core.service.iotPlatform.impl;
 import com.github.microservice.net.ResultContent;
 import com.zhongshu.iot.server.core.domain.ExecuteAnnotationService;
 import com.zhongshu.iot.server.core.domain.ExecuteAnnotationServiceMethod;
+import com.zhongshu.iot.server.core.service.device.GateWayInfoService;
 import com.zhongshu.iot.server.core.service.iotPlatform.PlatformTopic;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 /**
@@ -17,6 +19,9 @@ import org.springframework.stereotype.Component;
 @Slf4j
 public class RegisterDeviceTopic implements PlatformTopic {
 
+    @Autowired
+    private GateWayInfoService gateWayInfoService;
+
     @Override
     public String topic() {
         return "/platform/%s/regist";
@@ -25,6 +30,6 @@ public class RegisterDeviceTopic implements PlatformTopic {
     @ExecuteAnnotationServiceMethod(value = "registDevice", remark = "设备注册")
     @Override
     public ResultContent<Object> action(String dataId, String message) {
-        return ResultContent.buildSuccess();
+        return gateWayInfoService.registDevice(dataId, message);
     }
 }

+ 0 - 1
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/sync/DeviceSyncFullCardService.java

@@ -142,7 +142,6 @@ public class DeviceSyncFullCardService extends SuperService {
                 syncParam.setProjectInfoCode(it.getProjectInfoCode());
 
                 // 封装设备关联物模型数据
-
                 return syncParam;
             }).collect(Collectors.toList());
         }

+ 1 - 1
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/user/OperationLogsService.java

@@ -89,7 +89,7 @@ public class OperationLogsService extends SuperService {
             logs.setIp(IPUtil.getRemoteIp(request));
             logs.setUrl(request.getRequestURI());
         } catch (Exception e) {
-            e.printStackTrace();
+            log.error("addLogs: {}", e.getMessage());
         }
         operationLogsDao.save(logs);
         return ResultContent.buildSuccess();