TRX 1 год назад
Родитель
Сommit
7524de1fd6

+ 6 - 0
OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/baseParam/SuperSearchParam.java

@@ -38,4 +38,10 @@ public class SuperSearchParam implements Serializable {
 
     @Schema(description = "所属项目ID", hidden = true)
     private String epId;
+
+    @Schema(description = "第几页,从0开始,默认:0")
+    private Integer number = 0;
+
+    @Schema(description = "每页查询多少条数据,大于0的整数,如:10")
+    private Integer size = 10;
 }

+ 1 - 0
OneCardIotClient/src/main/java/com/zhongshu/iot/client/model/iot/IotMainSearch.java

@@ -45,5 +45,6 @@ public class IotMainSearch extends SuperSearchParam {
     @Schema(description = "搜索关键字")
     private String keyWord;
 
+    @Schema(description = "物模型类型")
     private IotDataType iotDataType;
 }

+ 20 - 0
OneCardIotClient/src/main/java/com/zhongshu/iot/client/openApi/base/DeviceIdParam.java

@@ -0,0 +1,20 @@
+package com.zhongshu.iot.client.openApi.base;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author TRX
+ * @date 2024/11/11
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DeviceIdParam {
+
+    @Schema(description = "设备ID/设备编号")
+    private String deviceId;
+
+}

+ 109 - 0
OneCardIotClient/src/main/java/com/zhongshu/iot/client/openApi/model/IotMainOpenAPIModel.java

@@ -0,0 +1,109 @@
+package com.zhongshu.iot.client.openApi.model;
+
+import com.github.microservice.types.FunctionType;
+import com.zhongshu.iot.client.model.baseParam.SuperModel;
+import com.zhongshu.iot.client.model.iot.IotAttribute;
+import com.zhongshu.iot.client.model.iot.IotDict;
+import com.zhongshu.iot.client.model.iot.IotTemplateModel;
+import com.zhongshu.iot.client.openApi.base.SuperAPIModel;
+import com.zhongshu.iot.client.type.DataType;
+import com.zhongshu.iot.client.type.EventType;
+import com.zhongshu.iot.client.type.OperationType;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @author TRX
+ * @date 2024/6/20
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class IotMainOpenAPIModel extends SuperAPIModel {
+
+    @Schema(description = "功能名称")
+    private String name;
+
+    @Schema(description = "标识符")
+    private String identifier;
+
+    @Schema(description = "功能类型,属性 事件 服务")
+    private FunctionType functionType;
+
+    private String functionTypeStr;
+
+    public String getFunctionTypeStr() {
+        if (functionType != null) {
+            return functionType.getRemark();
+        }
+        return "";
+    }
+
+    @Schema(description = "物模型Topic")
+    private String iotTopic;
+
+    @Schema(description = "真实的topic")
+    private String realIotTopic;
+
+    @Schema(description = "是否返回数据")
+    private Boolean isReturnData = Boolean.TRUE;
+
+    @Schema(description = "事件类型,如:消息、警告、故障")
+    private EventType eventType;
+
+    private String eventTypeStr;
+
+    public String getEventTypeStr() {
+        if (eventType != null) {
+            return eventType.getRemark();
+        }
+        return "";
+    }
+
+    //---------------------------------属性类型的  字段  start ------------------
+    @Schema(description = "数据类型,number、Boolean、String 等")
+    private DataType dataType;
+
+    @Schema(description = "元素类型,只有 dataType=Array才使用")
+    private DataType elementType;
+
+    private String dataTypeStr;
+
+    public String getDataTypeStr() {
+        if (dataType != null) {
+            return dataType.getRemark();
+        }
+        return "";
+    }
+
+    @Schema(description = "单位名称,如:千克、流明、立方米等...")
+    private String unitName;
+
+    @Schema(description = "步长")
+    private BigDecimal stepNumber;
+
+    @Schema(description = "最大的长度,如:类型为字符串时使用")
+    private Integer maxLength;
+
+    @Schema(description = "开始值")
+    private BigDecimal start;
+
+    @Schema(description = "结束值")
+    private BigDecimal end;
+
+    @Schema(description = "属性,参数列表,输入参数")
+    private List<IotAttribute> childs;
+
+    @Schema(description = "值的对应,如:0-开")
+    private List<IotDict> dicts;
+
+    @Schema(description = "属性,输出参数列表,输入参数")
+    private List<IotAttribute> outChilds;
+
+    //--------------------------------关联设备时特有的属性 start------------------
+}

+ 43 - 0
OneCardIotClient/src/main/java/com/zhongshu/iot/client/openApi/model/IotTemplateOpenAPIModel.java

@@ -0,0 +1,43 @@
+package com.zhongshu.iot.client.openApi.model;
+
+import com.zhongshu.iot.client.openApi.base.SuperAPIModel;
+import com.zhongshu.iot.client.type.DataState;
+import com.zhongshu.iot.client.type.IotDataType;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 设备管理的物模型数据
+ *
+ * @author TRX
+ * @date 2024/6/20
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class IotTemplateOpenAPIModel extends SuperAPIModel {
+
+    @Schema(description = "模版名称")
+    private String name;
+
+    @Schema(description = "数据状态")
+    private DataState state = DataState.Enable;
+
+    private String stateStr;
+
+    public String getStateStr() {
+        if (state != null) {
+            return state.getRemark();
+        }
+        return "";
+    }
+
+    @Schema(description = "关联的设备")
+    private String deviceId;
+
+    @Schema(description = "所属分组code")
+    private String projectCode;
+
+}

+ 22 - 4
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/controller/openAPi/DeviceIotOpenApiController.java

@@ -3,9 +3,13 @@ package com.zhongshu.iot.server.core.controller.openAPi;
 import com.github.microservice.auth.security.annotations.ResourceAuth;
 import com.github.microservice.auth.security.type.AuthType;
 import com.github.microservice.net.ResultContent;
+import com.zhongshu.iot.client.model.iot.IotMainSearch;
 import com.zhongshu.iot.client.model.mqtt.DeviceInfoModel;
 import com.zhongshu.iot.client.model.mqtt.DeviceInfoSearchParam;
+import com.zhongshu.iot.client.openApi.base.DeviceIdParam;
 import com.zhongshu.iot.client.openApi.model.DeviceInfoOpenAPIModel;
+import com.zhongshu.iot.client.openApi.model.IotMainOpenAPIModel;
+import com.zhongshu.iot.client.openApi.model.IotTemplateOpenAPIModel;
 import com.zhongshu.iot.server.core.service.openApi.DeviceIotOpenApiService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -15,10 +19,13 @@ import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.web.PageableDefault;
 import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.List;
+
 /**
  * 设备相关的 openApi 接口
  *
@@ -34,11 +41,22 @@ public class DeviceIotOpenApiController {
     @Autowired
     private DeviceIotOpenApiService deviceIotOpenApiService;
 
-    @Operation(summary = "设备列表-分页查询")
+    @Operation(summary = "设备-设备分页查询")
     @RequestMapping(value = {"pageDevice"}, method = {RequestMethod.POST})
-    public ResultContent<Page<DeviceInfoOpenAPIModel>> pageDevice(@Parameter(hidden = true) @PageableDefault(page = 0, size = 10) Pageable pageable,
-            @Parameter(required = false) DeviceInfoSearchParam param) {
-        return deviceIotOpenApiService.pageDevice(pageable, param);
+    public ResultContent<Page<DeviceInfoOpenAPIModel>> pageDevice(@RequestBody DeviceInfoSearchParam param) {
+        return deviceIotOpenApiService.pageDevice(param);
+    }
+
+    @Operation(summary = "设备-关联的物模型列表")
+    @RequestMapping(value = {"getDeviceTemplateList"}, method = {RequestMethod.POST})
+    public ResultContent<List<IotTemplateOpenAPIModel>> getDeviceTemplateList(@RequestBody DeviceIdParam param) {
+        return deviceIotOpenApiService.getDeviceTemplateList(param);
+    }
+
+    @Operation(summary = "设备-物模型-标识符列表")
+    @RequestMapping(value = {"pageIotMain"}, method = {RequestMethod.POST})
+    public ResultContent<Page<IotMainOpenAPIModel>> pageIotMain(@RequestBody IotMainSearch param) {
+        return deviceIotOpenApiService.pageIotMain(param);
     }
 
 }

+ 29 - 21
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/mqtt/GateWayInfoService.java

@@ -303,16 +303,20 @@ public class GateWayInfoService extends SuperService {
             List<MqttInfo> list = mqttInfoDao.findAll();
             if (ObjectUtils.isNotEmpty(list)) {
                 for (MqttInfo mqttInfo : list) {
-                    String urlStr = String.format("service:jmx:rmi:///jndi/rmi://%s:%s/jmxrmi", mqttInfo.getJmxHost(), mqttInfo.getJmxPort());
-                    JMXServiceURL url = new JMXServiceURL(urlStr);
-                    @Cleanup JMXConnector connector = JMXConnectorFactory.connect(url, null);
-                    connector.connect();
-                    log.info("JMX %s:%s 连接成功...", mqttInfo.getJmxHost(), mqttInfo.getJmxPort());
-                    MBeanServerConnection connection = connector.getMBeanServerConnection();
-                    ObjectName addressObjectName = ObjectNameBuilder.create("org.apache.activemq.artemis", mqttInfo.getBrokerName()).getActiveMQServerObjectName();
-                    ActiveMQServerControl addressControl = MBeanServerInvocationHandler.newProxyInstance(connection, addressObjectName, ActiveMQServerControl.class, false);
-
-                    addressControl.addSecuritySettings(MqttTopicUtils.buildGateWayAllTopic(gateWayId), roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName);
+                    if (StringUtils.isNotEmpty(mqttInfo.getJmxHost()) && StringUtils.isNotEmpty(mqttInfo.getJmxPort())) {
+                        String urlStr = String.format("service:jmx:rmi:///jndi/rmi://%s:%s/jmxrmi", mqttInfo.getJmxHost(), mqttInfo.getJmxPort());
+                        JMXServiceURL url = new JMXServiceURL(urlStr);
+                        @Cleanup JMXConnector connector = JMXConnectorFactory.connect(url, null);
+                        connector.connect();
+                        log.info("JMX %s:%s 连接成功...", mqttInfo.getJmxHost(), mqttInfo.getJmxPort());
+                        MBeanServerConnection connection = connector.getMBeanServerConnection();
+                        ObjectName addressObjectName = ObjectNameBuilder.create("org.apache.activemq.artemis", mqttInfo.getBrokerName()).getActiveMQServerObjectName();
+                        ActiveMQServerControl addressControl = MBeanServerInvocationHandler.newProxyInstance(connection, addressObjectName, ActiveMQServerControl.class, false);
+
+                        addressControl.addSecuritySettings(MqttTopicUtils.buildGateWayAllTopic(gateWayId), roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName);
+                    } else {
+                        log.error("MQTT JMX 信息为空", mqttInfo.getName());
+                    }
                 }
             }
         } catch (Exception e) {
@@ -328,17 +332,21 @@ public class GateWayInfoService extends SuperService {
             if (ObjectUtils.isNotEmpty(list)) {
                 list.parallelStream().forEach(mqttInfo -> {
                     try {
-                        String urlStr = String.format("service:jmx:rmi:///jndi/rmi://%s:%s/jmxrmi", mqttInfo.getJmxHost(), mqttInfo.getJmxPort());
-                        JMXServiceURL url = new JMXServiceURL(urlStr);
-                        @Cleanup JMXConnector connector = JMXConnectorFactory.connect(url, null);
-                        connector.connect();
-                        log.info("JMX %s:%s 连接成功...", mqttInfo.getJmxHost(), mqttInfo.getJmxPort());
-                        MBeanServerConnection connection = connector.getMBeanServerConnection();
-                        ObjectName addressObjectName = ObjectNameBuilder.create("org.apache.activemq.artemis", mqttInfo.getBrokerName()).getActiveMQServerObjectName();
-                        ActiveMQServerControl addressControl = MBeanServerInvocationHandler.newProxyInstance(connection, addressObjectName, ActiveMQServerControl.class, false);
-
-                        for (DeviceInfo deviceInfo : deviceInfos) {
-                            addressControl.addSecuritySettings(MqttTopicUtils.buildDeviceAllTopic(deviceInfo.getDeviceId()), roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName);
+                        if (StringUtils.isNotEmpty(mqttInfo.getJmxHost()) && StringUtils.isNotEmpty(mqttInfo.getJmxPort())) {
+                            String urlStr = String.format("service:jmx:rmi:///jndi/rmi://%s:%s/jmxrmi", mqttInfo.getJmxHost(), mqttInfo.getJmxPort());
+                            JMXServiceURL url = new JMXServiceURL(urlStr);
+                            @Cleanup JMXConnector connector = JMXConnectorFactory.connect(url, null);
+                            connector.connect();
+                            log.info("JMX %s:%s 连接成功...", mqttInfo.getJmxHost(), mqttInfo.getJmxPort());
+                            MBeanServerConnection connection = connector.getMBeanServerConnection();
+                            ObjectName addressObjectName = ObjectNameBuilder.create("org.apache.activemq.artemis", mqttInfo.getBrokerName()).getActiveMQServerObjectName();
+                            ActiveMQServerControl addressControl = MBeanServerInvocationHandler.newProxyInstance(connection, addressObjectName, ActiveMQServerControl.class, false);
+
+                            for (DeviceInfo deviceInfo : deviceInfos) {
+                                addressControl.addSecuritySettings(MqttTopicUtils.buildDeviceAllTopic(deviceInfo.getDeviceId()), roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName, roleName);
+                            }
+                        } else {
+                            log.error("MQTT JMX 信息为空:{}", mqttInfo.getName());
                         }
                     } catch (Exception e) {
                         e.printStackTrace();

+ 1 - 1
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/mqtt/MqttInfoService.java

@@ -66,7 +66,7 @@ public class MqttInfoService {
         MqttInfoReturnModel mqttInfoSimpleModel = new MqttInfoReturnModel();
         MqttInfo mqttInfo = mqttInfoDao.findTopByAddress(AddressType.Common);
         if (ObjectUtils.isNotEmpty(mqttInfo)) {
-            mqttInfoSimpleModel.setBrokerAddress(String.format(":", mqttInfo.getBrokerHost(), mqttInfo.getBrokerPort()));
+            mqttInfoSimpleModel.setBrokerAddress(String.format("%s:%s", mqttInfo.getBrokerHost(), mqttInfo.getBrokerPort()));
             mqttInfoSimpleModel.setBrokerUsername(mqttInfo.getUserName());
             mqttInfoSimpleModel.setBrokerPassword(mqttInfo.getPassword());
         }

+ 75 - 3
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/openApi/DeviceIotOpenApiService.java

@@ -1,10 +1,20 @@
 package com.zhongshu.iot.server.core.service.openApi;
 
 import com.github.microservice.net.ResultContent;
-import com.zhongshu.iot.client.model.mqtt.DeviceInfoModel;
+import com.github.microservice.types.FunctionType;
+import com.zhongshu.iot.client.model.iot.IotMainModel;
+import com.zhongshu.iot.client.model.iot.IotMainSearch;
 import com.zhongshu.iot.client.model.mqtt.DeviceInfoSearchParam;
+import com.zhongshu.iot.client.openApi.base.DeviceIdParam;
 import com.zhongshu.iot.client.openApi.model.DeviceInfoOpenAPIModel;
+import com.zhongshu.iot.client.openApi.model.IotMainOpenAPIModel;
+import com.zhongshu.iot.client.openApi.model.IotTemplateOpenAPIModel;
+import com.zhongshu.iot.client.type.IotDataType;
+import com.zhongshu.iot.server.core.dao.iot.IotMainDao;
+import com.zhongshu.iot.server.core.dao.iot.IotTemplateDao;
 import com.zhongshu.iot.server.core.dao.mqtt.DeviceInfoDao;
+import com.zhongshu.iot.server.core.domain.iot.IotMain;
+import com.zhongshu.iot.server.core.domain.iot.IotTemplate;
 import com.zhongshu.iot.server.core.domain.iot.mqtt.DeviceInfo;
 import com.zhongshu.iot.server.core.util.bean.BeanUtils;
 import com.zhongshu.iot.server.core.util.page.PageEntityUtil;
@@ -13,9 +23,14 @@ import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
 /**
  * @author TRX
  * @date 2024/11/11
@@ -27,22 +42,62 @@ public class DeviceIotOpenApiService {
     @Autowired
     private DeviceInfoDao deviceInfoDao;
 
+    @Autowired
+    private IotTemplateDao iotTemplateDao;
+
+    @Autowired
+    private IotMainDao iotMainDao;
+
     /**
      * 设备列表
      *
-     * @param pageable
      * @param param
      * @return
      */
-    public ResultContent<Page<DeviceInfoOpenAPIModel>> pageDevice(Pageable pageable, DeviceInfoSearchParam param) {
+    public ResultContent<Page<DeviceInfoOpenAPIModel>> pageDevice(DeviceInfoSearchParam param) {
         if (StringUtils.isEmpty(param.getProjectInfoCode())) {
             return ResultContent.buildFail("projectInfoCode");
         }
+        Pageable pageable = PageRequest.of(param.getNumber(), param.getSize());
+
         Page<DeviceInfo> page = deviceInfoDao.page(pageable, param);
         return ResultContent.buildSuccess(PageEntityUtil.toPageModel(page, this::toDeviceModel));
     }
 
+    /**
+     * 得到设备管理的物模型
+     *
+     * @param param
+     * @return
+     */
+    public ResultContent<List<IotTemplateOpenAPIModel>> getDeviceTemplateList(DeviceIdParam param) {
+        if (ObjectUtils.isEmpty(param.getDeviceId())) {
+            return ResultContent.buildFail("deviceId不能为空");
+        }
+        List<IotTemplate> list = iotTemplateDao.findByDeviceIdAndIotDataTypeOrderByCreateTimeAsc(param.getDeviceId(), IotDataType.Device);
+        List<IotTemplateOpenAPIModel> models = new ArrayList<>();
+        if (ObjectUtils.isNotEmpty(list)) {
+            models = list.stream().map(this::toIotTemplateModel).collect(Collectors.toUnmodifiableList());
+        }
+        return ResultContent.buildSuccess(models);
+    }
 
+    /**
+     * 物模型管理的 标识符分页数据
+     *
+     * @param param
+     * @return
+     */
+    public ResultContent<Page<IotMainOpenAPIModel>> pageIotMain(IotMainSearch param) {
+        if (StringUtils.isEmpty(param.getIotTemplateId())) {
+            return ResultContent.buildFail("iotTemplateId不能为空");
+        }
+        Pageable pageable = PageRequest.of(param.getNumber(), param.getSize());
+        Page<IotMain> page = iotMainDao.page(pageable, param);
+        return ResultContent.buildSuccess(PageEntityUtil.toPageModel(page, this::toIotMainModel));
+    }
+
+    //-------------------------模型转换 start--------------------------
     private DeviceInfoOpenAPIModel toDeviceModel(DeviceInfo entity) {
         DeviceInfoOpenAPIModel model = new DeviceInfoOpenAPIModel();
         if (ObjectUtils.isNotEmpty(entity)) {
@@ -50,4 +105,21 @@ public class DeviceIotOpenApiService {
         }
         return model;
     }
+
+    private IotTemplateOpenAPIModel toIotTemplateModel(IotTemplate entity) {
+        IotTemplateOpenAPIModel model = new IotTemplateOpenAPIModel();
+        if (ObjectUtils.isNotEmpty(entity)) {
+            BeanUtils.copyProperties(entity, model);
+        }
+        return model;
+    }
+
+    private IotMainOpenAPIModel toIotMainModel(IotMain entity) {
+        IotMainOpenAPIModel model = new IotMainOpenAPIModel();
+        if (ObjectUtils.isNotEmpty(entity)) {
+            BeanUtils.copyProperties(entity, model);
+        }
+        return model;
+    }
+
 }