TRX 1 рік тому
батько
коміт
7bf1bf8a0a

+ 1 - 1
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/controller/devices/DeviceStatisticsController.java

@@ -40,7 +40,7 @@ public class DeviceStatisticsController {
     public ResultContent deviceStatistics() {
         return deviceStatisticsService.deviceStatistics();
     }
-
+    
     @ResourceAuth(value = "user", type = AuthType.User)
     @Operation(summary = "设备在线折线图状态统计")
     @RequestMapping(value = "statisticsDeviceOnLine", method = {RequestMethod.POST})

+ 10 - 2
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/controller/iot/IotSendController.java

@@ -3,6 +3,7 @@ package com.zhongshu.iot.server.core.controller.iot;
 import com.github.microservice.auth.security.annotations.ResourceAuth;
 import com.github.microservice.auth.security.helper.AuthHelper;
 import com.github.microservice.auth.security.type.AuthType;
+import com.github.microservice.busInfoModel.thing.IotThingSendParam;
 import com.github.microservice.models.iot.IotSendByIdParam;
 import com.github.microservice.models.iot.IotSendParam;
 import com.github.microservice.net.ResultContent;
@@ -31,10 +32,10 @@ import org.springframework.web.bind.annotation.RestController;
 public class IotSendController {
 
     @Autowired
-    IotSendMessageService iotSendMessageService;
+    private IotSendMessageService iotSendMessageService;
 
     @Autowired
-    AuthHelper authHelper;
+    private AuthHelper authHelper;
 
     @ResourceAuth(value = "user", type = AuthType.User)
     @Operation(summary = "下发消息")
@@ -57,4 +58,11 @@ public class IotSendController {
         return iotSendMessageService.sendIotMessage(param);
     }
 
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @Operation(summary = "下发刷新物模型属性值的消息")
+    @RequestMapping(value = "sendGetIotProperty", method = {RequestMethod.POST})
+    public ResultContent sendGetIotProperty(@RequestBody @Valid IotThingSendParam param) {
+        return iotSendMessageService.sendGetIotProperty(param);
+    }
+
 }

+ 2 - 0
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/dao/iot/IotMainDao.java

@@ -40,4 +40,6 @@ public interface IotMainDao extends IotMainDaoExtend, org.springframework.data.m
 
     List<IotMain> findByDeviceIdAndFunctionTypeAndIotDataType(String deviceId, FunctionType functionType, IotDataType iotDataType);
 
+    List<IotMain> findByIotThingId(String iotThingId);
+
 }

+ 12 - 7
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/dao/iot/impl/IotMainDaoImpl.java

@@ -52,15 +52,17 @@ public class IotMainDaoImpl extends BaseImpl implements IotMainDaoExtend {
             criteria.and("iotThingId").is(param.getIotThingId());
         }
 
+        // 配置类型(属性、事件、服务)
         if (param.getFunctionType() != null) {
             criteria.and("functionType").is(param.getFunctionType());
         }
 
+        //物模型类型 产品、物模型
         if (param.getIotDataType() != null) {
             criteria.and("iotDataType").is(param.getIotDataType());
         }
 
-        // 数据类型
+        // 数据类型 数字、字符串...
         if (param.getDataType() != null) {
             criteria.and("dataType").is(param.getDataType());
         }
@@ -75,6 +77,7 @@ public class IotMainDaoImpl extends BaseImpl implements IotMainDaoExtend {
             criteria.and("gateWayId").is(param.getGateWayId());
         }
 
+        // 业务地址类型: 内网、外网
         if (param.getRemoteUrlType() != null) {
             criteria.and("remoteUrlType").is(param.getRemoteUrlType());
         }
@@ -84,17 +87,17 @@ public class IotMainDaoImpl extends BaseImpl implements IotMainDaoExtend {
             criteria.and("eventType").is(param.getEventType());
         }
 
+        // 标识符
+        if (StringUtils.isNotEmpty(param.getIdentifier())) {
+            criteria.and("identifier").is(param.getIdentifier());
+        }
+
         // 模糊搜索
         List<Criteria> criterias = new ArrayList<>();
         if (StringUtils.isNotEmpty(param.getName())) {
             Pattern pattern = Pattern.compile("^.*" + param.getName() + ".*$");
             criterias.add(Criteria.where("name").is(pattern));
         }
-        // 标识符
-        if (StringUtils.isNotEmpty(param.getIdentifier())) {
-            Pattern pattern = Pattern.compile("^.*" + param.getIdentifier() + ".*$");
-            criterias.add(Criteria.where("identifier").is(pattern));
-        }
         if (StringUtils.isNotEmpty(param.getIotTopic())) {
             Pattern pattern = Pattern.compile("^.*" + param.getIotTopic() + ".*$");
             criterias.add(Criteria.where("iotTopic").is(pattern));
@@ -106,7 +109,9 @@ public class IotMainDaoImpl extends BaseImpl implements IotMainDaoExtend {
         // 关键字搜索
         if (StringUtils.isNotEmpty(param.getKeyWord())) {
             Pattern pattern = Pattern.compile("^.*" + param.getKeyWord() + ".*$");
-            criteria.orOperator(Criteria.where("name").regex(pattern), Criteria.where("identifier").regex(pattern), Criteria.where("iotTopic").regex(pattern));
+            criteria.orOperator(Criteria.where("name").regex(pattern),
+                    Criteria.where("identifier").regex(pattern),
+                    Criteria.where("iotTopic").regex(pattern));
         }
 
         Sort sort = buildSort(param);

+ 2 - 0
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/dataConfig/CommonTTLTimeConfig.java

@@ -20,5 +20,7 @@ public class CommonTTLTimeConfig {
     // 默认心跳间隔时间
     public static final Long maxDeviceRedisOnLineTime = 60L;
 
+
+
     public static final String OnLineExpiredKey = "expiredKey_";
 }

+ 5 - 5
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/device/OperationMessage.java

@@ -31,10 +31,10 @@ public class OperationMessage extends SuperEntity {
     private String messageId;
 
     @Schema(description = "topic")
-    private String topic;
+    private String topic = "";
 
     @Schema(description = "终端ID")
-    private String clientId;
+    private String clientId = "";
 
     @Schema(description = "业务生成的ID")
     @Indexed(unique = true, sparse = true)
@@ -49,14 +49,14 @@ public class OperationMessage extends SuperEntity {
     @Schema(description = "消息内容")
     private Object data;
 
-    @Schema(description = "ttl时间(毫秒数)")
+    @Schema(description = "消息过期(毫秒数)")
     private Long ttlTime;
 
     @Schema(description = "发送时间,消息里的时间")
     private Long sendTime;
 
     @Schema(description = "接收的消息是否超时")
-    private Boolean isTimeOut;
+    private Boolean isTimeOut = Boolean.FALSE;
 
     @Schema(description = "处理标记,判断用那个业务方法处理")
     private String event;
@@ -67,7 +67,7 @@ public class OperationMessage extends SuperEntity {
     //------------------------关联的消息
 
     @Schema(description = "消息的类型")
-    private String messageClass;
+    private String messageClass = "";
 
     @Schema(description = "关于的设备信息")
     private DeviceInfo deviceInfo;

+ 26 - 5
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/domain/iot/device/OperationMessageResult.java

@@ -2,6 +2,9 @@ package com.zhongshu.iot.server.core.domain.iot.device;
 
 import cn.hutool.json.JSONObject;
 import com.github.microservice.types.FunctionType;
+import com.github.microservice.types.deviceUse.DeviceCategory;
+import com.github.microservice.types.deviceUse.DeviceType;
+import com.github.microservice.types.deviceUse.RegistType;
 import com.zhongshu.card.client.utils.DateUtils;
 import com.zhongshu.iot.client.type.EventType;
 import com.zhongshu.iot.client.type.OperationBusType;
@@ -13,9 +16,12 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.springframework.data.mongodb.core.index.Indexed;
 import org.springframework.data.mongodb.core.mapping.DBRef;
 import org.springframework.data.mongodb.core.mapping.Document;
 
+import java.util.Date;
+
 /**
  * @author TRX
  * @date 2024/7/15
@@ -27,6 +33,9 @@ import org.springframework.data.mongodb.core.mapping.Document;
 public class OperationMessageResult extends SuperEntity {
 
     // ---------------------消息管关联的信息 start------------------
+    @Schema(description = "消息内容")
+    @DBRef(lazy = true)
+    private OperationMessage operationMessage;
 
     @Schema(description = "关联的mqtt账号")
     private String mqttUserName;
@@ -50,10 +59,6 @@ public class OperationMessageResult extends SuperEntity {
     @Schema(description = "事件类型")
     private EventType eventType;
 
-    @Schema(description = "消息内容")
-    @DBRef(lazy = true)
-    private OperationMessage operationMessage;
-
     @Schema(description = "消息业务类型")
     private OperationBusType operationBusType;
 
@@ -77,13 +82,25 @@ public class OperationMessageResult extends SuperEntity {
     @Schema(description = "设备ID")
     private String deviceId;
 
+    @Schema(description = "设备名称")
+    private String deviceName;
+
+    @Schema(description = "设备类型:消费机 闸机")
+    private DeviceType deviceType;
+
+    @Schema(description = "设备注册方式")
+    private RegistType registType;
+
+    @Schema(description = "区分是网关、设备")
+    private DeviceCategory deviceCategory;
+
     @Schema(description = "分组ID")
     private String projectCode;
 
     @Schema(description = "网关ID")
     private String gateWayId;
 
-    @Schema(description = "topic")
+    @Schema(description = "真实的 topic")
     private String realIotTopic;
 
     @Schema(description = "入参,发送数据")
@@ -191,4 +208,8 @@ public class OperationMessageResult extends SuperEntity {
         this.hourKey = DateUtils.paresTime(System.currentTimeMillis(), DateUtils.patternyyyyMMddHHKey);
     }
 
+    @Schema(description = "消息的过期时间")
+    @Indexed(expireAfterSeconds = 0)
+    private Date ttl;
+
 }

+ 25 - 2
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/artemis/OperationMessageService.java

@@ -28,6 +28,7 @@ import com.zhongshu.iot.server.core.domain.iot.device.OperationMessageResult;
 import com.zhongshu.iot.server.core.domain.other.ExecuteMethodInfo;
 import com.zhongshu.iot.server.core.httpRequest.ApiRequestService;
 import com.zhongshu.iot.server.core.service.device.DeviceInfoService;
+import com.zhongshu.iot.server.core.service.device.GateWayManagerService;
 import com.zhongshu.iot.server.core.service.iot.IotDataVerifyService;
 import com.zhongshu.iot.server.core.service.iotPlatform.PlatformTopic;
 import com.zhongshu.iot.server.core.util.CommonUtil;
@@ -96,6 +97,9 @@ public class OperationMessageService {
     @Autowired
     private IotDataVerifyService iotDataVerifyService;
 
+    @Autowired
+    private GateWayManagerService gateWayManagerService;
+
     @Value("${artemisstore.time}")
     public Long ttlMill = 30 * 24L * 60 * 60 * 1000L;
 
@@ -695,19 +699,38 @@ public class OperationMessageService {
         if (ObjectUtils.isEmpty(messageResult) || ObjectUtils.isEmpty(iotMain)) {
             return;
         }
+        messageResult.setOperationBusType(OperationBusType.IotThing);
+        messageResult.setTimes();
         // 所属物模型事件 产品信息
         messageResult.setIotMain(iotMain);
         messageResult.setIotThingId(iotMain.getIotThingId());
+        // 产品code
         messageResult.setProductCode(iotMain.getProductCode());
         messageResult.setFunctionType(iotMain.getFunctionType());
         messageResult.setIdentifier(iotMain.getIdentifier());
         messageResult.setIotName(iotMain.getName());
         messageResult.setEventType(iotMain.getEventType());
-        // 设备ID
-        messageResult.setDeviceId(iotMain.getDeviceId());
+
         // 分组code
         messageResult.setProjectCode(iotMain.getProjectCode());
         messageResult.setRealIotTopic(iotMain.getRealIotTopic());
+
+        // 设备ID
+        DeviceInfo deviceInfo = deviceInfoDao.findTopByDeviceId(iotMain.getDeviceId());
+        messageResult.setDeviceId(iotMain.getDeviceId());
+        if (ObjectUtils.isNotEmpty(deviceInfo)) {
+            DeviceInfo gateWayInfo = gateWayManagerService.getDeviceGateWayInfo(deviceInfo);
+            messageResult.setDeviceName(deviceInfo.getDeviceName());
+            messageResult.setDeviceType(deviceInfo.getDeviceType());
+            messageResult.setDeviceCategory(deviceInfo.getDeviceCategory());
+
+            // 所属网关信息
+            if (ObjectUtils.isNotEmpty(gateWayInfo)) {
+                messageResult.setGateWayId(gateWayInfo.getDeviceId());
+            }
+        }
+
+        messageResult.setTtl(new Date(System.currentTimeMillis() + ttlMill));
     }
 
     public OperationMessageModel toModel(OperationMessage entity) {

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

@@ -297,6 +297,12 @@ public class GateWayManagerService extends SuperService {
         return deviceInfoDao.findByDeviceCategory(DeviceCategory.GW);
     }
 
+    public DeviceInfo getDeviceGateWayInfo(String deviceId) {
+        if (StringUtils.isEmpty(deviceId)) {
+            return null;
+        }
+        return getDeviceGateWayInfo(deviceInfoDao.findTopByDeviceId(deviceId));
+    }
 
     /**
      * 得到设备的网关信息

+ 70 - 28
OneCardIotServer/src/main/java/com/zhongshu/iot/server/core/service/iot/IotSendMessageService.java

@@ -2,11 +2,15 @@ package com.zhongshu.iot.server.core.service.iot;
 
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
+import com.github.microservice.busInfoModel.thing.IotThingSendParam;
+import com.github.microservice.dataConfig.IotIdentifierConfig;
 import com.github.microservice.models.iot.IotSendByIdParam;
 import com.github.microservice.models.iot.IotSendGateWayParam;
 import com.github.microservice.models.iot.IotSendParam;
+import com.github.microservice.models.property.PostGetPropertyParam;
 import com.github.microservice.net.ResultContent;
 import com.github.microservice.net.ResultMessage;
+import com.github.microservice.types.FunctionType;
 import com.zhongshu.iot.client.model.iot.IotMainSearch;
 import com.zhongshu.iot.client.type.IotDataType;
 import com.zhongshu.iot.client.type.OperationBusType;
@@ -19,6 +23,7 @@ import com.zhongshu.iot.server.core.domain.iot.IotMain;
 import com.zhongshu.iot.server.core.domain.iot.device.DeviceInfo;
 import com.zhongshu.iot.server.core.domain.iot.device.OperationMessage;
 import com.zhongshu.iot.server.core.domain.iot.device.OperationMessageResult;
+import com.zhongshu.iot.server.core.service.artemis.OperationMessageService;
 import com.zhongshu.iot.server.core.service.base.SuperService;
 import com.zhongshu.iot.server.core.util.CommonUtil;
 import com.zhongshu.iot.server.core.util.DateUtils;
@@ -61,10 +66,18 @@ public class IotSendMessageService extends SuperService {
     @Autowired
     private MQClient mqClient;
 
+    @Autowired
+    private OperationMessageService operationMessageService;
+
     // 保存90天
     @Value("${artemisstore.time}")
     public Long ttlMill = 30 * 24L * 60 * 60 * 1000L;
 
+    /**
+     *
+     * @param param
+     * @return
+     */
     public ResultContent sendIotMsgById(IotSendByIdParam param) {
         if (StringUtils.isEmpty(param.getId())) {
             return ResultContent.buildFail("id不能为空");
@@ -80,22 +93,63 @@ public class IotSendMessageService extends SuperService {
         iotSendParam.setData(param.getData());
         iotSendParam.setId(param.getId());
         iotSendParam.setIsImitate(Boolean.TRUE);
+        iotSendParam.setIotThingId(iotMain.getIotThingId());
         return sendIotMessage(iotSendParam);
     }
 
     /**
-     * 发送信息
+     * 下发得到物模型的属性值
+     * @param param
+     * @return
+     */
+    public ResultContent sendGetIotProperty(IotThingSendParam param) {
+        if (StringUtils.isEmpty(param.getId()) && StringUtils.isEmpty(param.getIotThingId())) {
+            return ResultContent.buildFail("id和iotThingId不能同时为空");
+        }
+        String iotThingId = "";
+        List<IotMain> iotMains = new ArrayList<>();
+        if (StringUtils.isNotEmpty(param.getIotThingId())) {
+            iotMains = iotMainDao.findByIotThingId(param.getIotThingId());
+            iotThingId = param.getIotThingId();
+        } else if (StringUtils.isNotEmpty(param.getId())) {
+            IotMain iotMain = iotMainDao.findTopById(param.getId());
+            if (ObjectUtils.isNotEmpty(iotMain)) {
+                iotMains.add(iotMain);
+            }
+            iotThingId = iotMain.getIotThingId();
+        }
+        if (ObjectUtils.isEmpty(iotMains)) {
+            return ResultContent.buildFail("没有找到属性");
+        }
+        PostGetPropertyParam propertyParam = new PostGetPropertyParam();
+        for (IotMain iotMain : iotMains) {
+            propertyParam.addProperty(iotMain.getDeviceId(), iotMain.getIdentifier());
+        }
+        JSONObject data = JSONUtil.parseObj(propertyParam);
+
+        // 组装发送数据
+        IotSendParam sendParam = new IotSendParam();
+        sendParam.setIotThingId(iotThingId);
+        sendParam.setFunctionType(FunctionType.Server);
+        sendParam.setIdentifier(IotIdentifierConfig.getAttrs);
+        sendParam.setData(data);
+        return sendIotMessage(sendParam);
+    }
+
+    /**
+     * 发送信息 (统一入口方法)
      *
      * @param param
      * @return
      */
     public ResultContent sendIotMessage(IotSendParam param) {
-        log.info("****************sendIotMessage***************设备ID={}  功能类型={}", param.getDeviceId(), param.getIdentifier());
+        log.info("************sendIotMessage*********设备ID={}  功能类型={}", param.getDeviceId(), param.getIdentifier());
+
         IotMainSearch search = new IotMainSearch();
         BeanUtils.copyProperties(param, search);
-        // 真实设备的topic
+        // 物模型的配置
         search.setIotDataType(IotDataType.Device);
-        Pageable pageable = PageRequest.of(0, Integer.MAX_VALUE);
+        Pageable pageable = PageRequest.of(0, 100);
         Page<IotMain> page = iotMainDao.page(pageable, search);
 
         List<IotMain> list = page.getContent();
@@ -104,8 +158,7 @@ public class IotSendMessageService extends SuperService {
             return ResultContent.buildFail("没有对应的设备物模型");
         }
         // list 根据 topic 去重
-        list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
-                () -> new TreeSet<>(Comparator.comparing(IotMain::getRealIotTopic))), ArrayList::new));
+        list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(IotMain::getRealIotTopic))), ArrayList::new));
 
         DeviceInfo deviceInfo = null;
         DeviceInfo gateWayInfo = null;
@@ -121,10 +174,12 @@ public class IotSendMessageService extends SuperService {
             dataId = CommonUtil.UUID();
         }
 
+        // 业务数据
+        JSONObject data = param.getData();
         // 组装要发送的数据
         JSONObject jsonObject = new JSONObject();
         jsonObject.set("id", dataId);
-        jsonObject.set("data", param.getData());
+        jsonObject.set("data", data);
         jsonObject.set("timeStr", DateUtils.paresTime(System.currentTimeMillis(), DateUtils.patternyyyySSS));
         jsonObject.set("time", System.currentTimeMillis());
         jsonObject.set("ttl", param.getTtl());
@@ -138,15 +193,12 @@ public class IotSendMessageService extends SuperService {
             entity.setMessageId(CommonUtil.UUID()); // 消息ID
             entity.setOperationBusType(OperationBusType.IotThing);
             entity.setTimes();
-            entity.setClientId(""); // 终端ID
-            entity.setTopic(""); // topic名称
             entity.setOperationType(OperationType.Push);
-            entity.setMessageClass("");
             entity.setData(jsonObject);
             entity.setTtlTime(param.getTtl());
             entity.setSendTime(System.currentTimeMillis());
             entity.setDataId(dataId);
-            entity.setIsTimeOut(false);
+            entity.setExpireAt(param.getTtl() + System.currentTimeMillis());
             entity.setEvent(param.getEvent());
 
             if (ObjectUtils.isNotEmpty(gateWayInfo)) {
@@ -157,7 +209,7 @@ public class IotSendMessageService extends SuperService {
                 entity.setDeviceId(deviceInfo.getDeviceId());
                 entity.setDeviceInfo(deviceInfo);
             }
-            
+            // 消息自动生成时间
             entity.setTtl(new Date(System.currentTimeMillis() + ttlMill));
             entity.setReceiveTime(System.currentTimeMillis());
             entity.setReceiveTimeStr(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
@@ -171,32 +223,22 @@ public class IotSendMessageService extends SuperService {
                 jsonObject.set("id", messageId);
 
                 OperationMessageResult messageResult = new OperationMessageResult();
-                messageResult.setTimes();
-                messageResult.setProductCode(iotMain.getProductCode());
-                messageResult.setIotThingId(iotMain.getIotThingId());
-                messageResult.setMessageId(messageId);
-                messageResult.setDataId(entity.getDataId());
+                operationMessageService.buildOperationMessageResultIotInfo(messageResult, iotMain);
                 messageResult.setOperationMessage(entity);
-
-                // 所属属性信息
-                messageResult.setIotMain(iotMain);
-                messageResult.setIotTemplate(iotMain.getIotTemplate());
-
-                // 设备ID
-                messageResult.setDeviceId(iotMain.getDeviceId());
-                // 分组code
-                messageResult.setProjectCode(iotMain.getProjectCode());
                 messageResult.setGateWayId(entity.getGateWayId());
-                messageResult.setRealIotTopic(topic);
-                messageResult.setData(jsonObject);
                 messageResult.setOperationType(entity.getOperationType());
 
+                messageResult.setMessageId(messageId);
+                messageResult.setDataId(entity.getDataId());
+                messageResult.setRealIotTopic(topic);
+                messageResult.setData(data);
                 Boolean isSendSuccess = Boolean.TRUE;
                 String sendMsg = "下发成功";
                 try {
                     mqClient.sendObject(topic, JSONUtil.toJsonStr(jsonObject), messageId);
                 } catch (Exception e) {
                     e.printStackTrace();
+                    isSendSuccess = false;
                     sendMsg = String.format("下发出错:%s", e.getMessage());
                 }
                 messageResult.setIsSendSuccess(isSendSuccess);