TRX 1 рік тому
батько
коміт
2a68d558cb

+ 1 - 1
src/main/java/com/zswl/dataservice/controller/iot/IotController.java

@@ -34,7 +34,7 @@ import java.util.List;
 @RequestMapping("/iot")
 @RestController
 @Validated
-@Tag(name = "模版-物模型管理")
+@Tag(name = "物模型-物模型管理")
 public class IotController {
 
     @Autowired

+ 59 - 0
src/main/java/com/zswl/dataservice/controller/iot/IotSendController.java

@@ -0,0 +1,59 @@
+package com.zswl.dataservice.controller.iot;
+
+import com.github.microservice.models.iot.IotSendParam;
+import com.zswl.dataservice.auth.UserContext;
+import com.zswl.dataservice.model.baseParam.NameModel;
+import com.zswl.dataservice.model.iot.*;
+import com.zswl.dataservice.service.iot.IotSendMessageService;
+import com.zswl.dataservice.service.iot.IotServiceImpl;
+import com.zswl.dataservice.utils.result.ResultContent;
+import io.swagger.v3.oas.annotations.Hidden;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.web.PageableDefault;
+import org.springframework.util.Assert;
+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;
+
+/**
+ * 物模型下发数据
+ *
+ * @author TRX
+ * @date 2024/3/21
+ */
+@RequestMapping("/iotSend")
+@RestController
+@Validated
+@Tag(name = "物模型-下发数据")
+public class IotSendController {
+
+    @Autowired
+    IotSendMessageService iotSendMessageService;
+
+    @Parameter(in = ParameterIn.HEADER, name = "accessToken", required = false, description = "accessToken")
+    @Operation(summary = "下发消息")
+    @RequestMapping(value = "sendIotMessage", method = {RequestMethod.POST})
+    public ResultContent sendIotMessage(@RequestBody @Valid IotSendParam param) {
+        param.setUserId(UserContext.currentUser().getId());
+        return iotSendMessageService.sendIotMessage(param);
+    }
+
+    @Operation(summary = "下发消息")
+    @RequestMapping(value = "/free/sendIotMessage", method = {RequestMethod.POST})
+    @Hidden
+    public ResultContent sendIotMessageFree(@RequestBody @Valid IotSendParam param) {
+        return iotSendMessageService.sendIotMessage(param);
+    }
+
+}

+ 4 - 0
src/main/java/com/zswl/dataservice/dao/iot/IotMainDao.java

@@ -7,6 +7,7 @@ import com.zswl.dataservice.domain.iot.IotMain;
 import com.zswl.dataservice.domain.iot.IotTemplate;
 import com.zswl.dataservice.domain.iot.IotTopic;
 import com.zswl.dataservice.type.FunctionType;
+import com.zswl.dataservice.type.IotDataType;
 
 import java.util.List;
 
@@ -27,4 +28,7 @@ public interface IotMainDao extends MongoDao<IotMain>, IotMainDaoExtend {
     List<IotMain> findByIotTemplateAndFunctionTypeOrderByCreateTimeAsc(IotTemplate iotTemplate, FunctionType functionType);
 
     List<IotMain> findByRealIotTopicAndFunctionTypeOrderByCreateTimeAsc(String realIotTopic, FunctionType functionType);
+
+    List<IotMain> findByDeviceIdAndIdentifierAndIotDataType(String deviceId, String identifier, IotDataType iotData);
+
 }

+ 1 - 1
src/main/java/com/zswl/dataservice/domain/mqtt/OperationMessage.java

@@ -80,7 +80,7 @@ public class OperationMessage extends SuperEntity {
     }
 
     @Schema(description = "mqtt消息类型: 发送 接收")
-    OperationType operationType;
+    private OperationType operationType;
 
     @Schema(description = "消息创建时间,服务器的时间")
     private String time;

+ 7 - 0
src/main/java/com/zswl/dataservice/domain/mqtt/OperationMessageResult.java

@@ -3,6 +3,7 @@ package com.zswl.dataservice.domain.mqtt;
 import cn.hutool.json.JSONObject;
 import com.zswl.dataservice.domain.base.SuperEntity;
 import com.zswl.dataservice.domain.iot.IotMain;
+import com.zswl.dataservice.type.OperationType;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.AllArgsConstructor;
 import lombok.Data;
@@ -25,6 +26,9 @@ public class OperationMessageResult extends SuperEntity {
     @DBRef(lazy = true)
     private OperationMessage operationMessage;
 
+    @Schema(description = "mqtt消息类型: 发送 接收")
+    private OperationType operationType;
+
     @Schema(description = "关联的事件")
     private IotMain iotMain;
 
@@ -40,6 +44,9 @@ public class OperationMessageResult extends SuperEntity {
     @Schema(description = "topic")
     private String realIotTopic;
 
+    @Schema(description = "发送数据")
+    private Object data;
+
     //-------------------业务处理结果 start----------------
 
     @Schema(description = "是否处理成功")

+ 1 - 1
src/main/java/com/zswl/dataservice/service/artemis/OperationMessageService.java

@@ -85,7 +85,7 @@ public class OperationMessageService {
 
     // 保存90天
     @Value("${artemisstore.time}")
-    private Long ttlMill = 30 * 24L * 60 * 60 * 1000L;
+    public static final Long ttlMill = 30 * 24L * 60 * 60 * 1000L;
 
     @Autowired
     private ExecuteMethodInfoDao executeMethodInfoDao;

+ 144 - 0
src/main/java/com/zswl/dataservice/service/iot/IotSendMessageService.java

@@ -0,0 +1,144 @@
+package com.zswl.dataservice.service.iot;
+
+import cn.hutool.json.JSONObject;
+import com.github.microservice.models.iot.IotSendParam;
+import com.zswl.dataservice.dao.iot.IotMainDao;
+import com.zswl.dataservice.dao.iot.IotTopicDao;
+import com.zswl.dataservice.dao.mqtt.DeviceInfoDao;
+import com.zswl.dataservice.dao.mqtt.GateWay2DeviceDao;
+import com.zswl.dataservice.dao.mqtt.OperationMessageDao;
+import com.zswl.dataservice.dao.mqtt.OperationMessageResultDao;
+import com.zswl.dataservice.domain.iot.IotMain;
+import com.zswl.dataservice.domain.mqtt.*;
+import com.zswl.dataservice.service.artemis.OperationMessageService;
+import com.zswl.dataservice.service.base.SuperService;
+import com.zswl.dataservice.type.IotDataType;
+import com.zswl.dataservice.type.OperationType;
+import com.zswl.dataservice.utils.CommonUtil;
+import com.zswl.dataservice.utils.DateUtils;
+import com.zswl.dataservice.utils.TokenUtil;
+import com.zswl.dataservice.utils.mqtt.MqttTopicUtils;
+import com.zswl.dataservice.utils.mqtt.mqttConfig.client.MQClient;
+import com.zswl.dataservice.utils.result.ResultContent;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * @author TRX
+ * @date 2024/8/9
+ */
+@Slf4j
+@Service
+public class IotSendMessageService extends SuperService {
+
+    @Autowired
+    private DeviceInfoDao deviceInfoDao;
+
+    @Autowired
+    private IotMainDao iotMainDao;
+
+    @Autowired
+    OperationMessageDao operationMessageDao;
+
+    @Autowired
+    private OperationMessageResultDao operationMessageResultDao;
+
+    @Autowired
+    private MQClient mqClient;
+
+    @Autowired
+    private GateWay2DeviceDao gateWay2DeviceDao;
+
+
+    /**
+     * 发送信息
+     *
+     * @param param
+     * @return
+     */
+    public ResultContent sendIotMessage(IotSendParam param) {
+        // 验证数据
+        DeviceInfo deviceInfo = deviceInfoDao.findTopByDeviceId(param.getDeviceId());
+        if (ObjectUtils.isEmpty(deviceInfo)) {
+            return ResultContent.buildFail(String.format("设备不存在:%S", param.getDeviceId()));
+        }
+        List<IotMain> list = iotMainDao.findByDeviceIdAndIdentifierAndIotDataType(
+                param.getDeviceId(), param.getIdentifier(), IotDataType.Device
+        );
+        if (ObjectUtils.isEmpty(list)) {
+            return ResultContent.buildFail("没有对应的设备物模型");
+        }
+        GateWayInfo gateWayInfo = null;
+        GateWay2Device gateWay2Device = gateWay2DeviceDao.findTopByDeviceInfoOrderByUpdateTimeDesc(deviceInfo);
+        if (ObjectUtils.isEmpty(gateWay2Device)) {
+            gateWayInfo = gateWay2Device.getGateWayInfo();
+        }
+        String dataId = param.getDataId();
+        if (StringUtils.isEmpty(dataId)) {
+            dataId = CommonUtil.UUID();
+        }
+        // 组装要发送的数据
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.set("id", dataId);
+        jsonObject.set("data", param.getData());
+        jsonObject.set("timeStr", DateUtils.paresTime(System.currentTimeMillis(), DateUtils.patternyyyySSS));
+        jsonObject.set("time", System.currentTimeMillis());
+        jsonObject.set("ttl", param.getTtl());
+        jsonObject.set("imitate", param.getIsImitate());
+
+        String token = TokenUtil.create();
+        OperationMessage entity = operationMessageDao.init(dataId, token);
+        if (ObjectUtils.isNotEmpty(entity)) {
+            entity.setMessageId(CommonUtil.UUID()); // 消息ID
+            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.setEvent("");
+            entity.setGateWayInfo(gateWayInfo);
+            if (ObjectUtils.isNotEmpty(gateWayInfo)) {
+                entity.setGateWayId(gateWayInfo.getGateWayId());
+            }
+            entity.setDeviceId(deviceInfo.getDeviceId());
+            entity.setDeviceInfo(deviceInfo);
+            entity.setTtl(new Date(System.currentTimeMillis() + OperationMessageService.ttlMill));
+            entity.setReceiveTime(System.currentTimeMillis());
+            entity.setReceiveTimeStr(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
+            operationMessageDao.save(entity);
+
+            for (IotMain iotMain : list) {
+                // %s/issued 下发数据 Topic
+                String topic = MqttTopicUtils.buildIssuedTopic(iotMain.getRealIotTopic());
+
+                OperationMessageResult messageResult = new OperationMessageResult();
+                messageResult.setOperationMessage(entity);
+                messageResult.setIotMain(iotMain);
+                // 设备ID
+                messageResult.setDeviceId(iotMain.getDeviceId());
+                // 分组code
+                messageResult.setProjectCode(iotMain.getProjectCode());
+                messageResult.setGateWayId(entity.getGateWayId());
+                messageResult.setRealIotTopic(topic);
+                messageResult.setData(jsonObject);
+                messageResult.setGateWayId(entity.getGateWayId());
+                messageResult.setOperationType(entity.getOperationType());
+
+                operationMessageResultDao.save(messageResult);
+            }
+        }
+        return ResultContent.buildSuccess();
+    }
+
+}

+ 10 - 0
src/main/java/com/zswl/dataservice/utils/mqtt/MqttTopicUtils.java

@@ -55,4 +55,14 @@ public class MqttTopicUtils {
         return String.format("%s/device/%s/%s", version, deviceId, operationInstruction);
     }
 
+    /**
+     * 组装下发 topic
+     *
+     * @param iotTopic
+     * @return
+     */
+    public static String buildIssuedTopic(String iotTopic) {
+        return String.format("%s/issued", iotTopic);
+    }
+
 }