Explorar el Código

add 下发指令

18339543638 hace 4 años
padre
commit
10deca7dbc

+ 100 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/entity/DeviceDirectivesEntity.java

@@ -0,0 +1,100 @@
+package org.jetlinks.community.device.entity;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.hswebframework.ezorm.rdb.mapping.annotation.*;
+import org.hswebframework.web.api.crud.entity.GenericEntity;
+import org.hswebframework.web.validator.CreateGroup;
+import org.jetlinks.community.device.enums.DeviceProductState;
+import org.jetlinks.community.device.enums.DirectiveState;
+import org.jetlinks.core.message.DeviceMessage;
+import org.jetlinks.core.message.MessageType;
+import javax.persistence.Column;
+import javax.persistence.Index;
+import javax.persistence.Table;
+import javax.validation.constraints.NotBlank;
+import java.sql.JDBCType;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName DeviceDirectivesEntity.java
+ * @Description 设备下发指令消息
+ * @createTime 2021年11月23日 15:16:00
+ */
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@Table(name = "dev_device_directives",indexes = {
+    @Index(name = "directives_device_id", columnList = "device_id,message_id",unique = true),
+})
+public class DeviceDirectivesEntity extends GenericEntity<String> {
+
+    @Comment("产品id")
+    @Column(name = "product_id",nullable = false)
+    @Schema(description = "产品id")
+    private String productId;
+
+    @Comment("设备id")
+    @Column(name = "device_id",nullable = false)
+    @Schema(description = "设备id")
+    private String deviceId;
+
+    @Comment("消息id")
+    @Column(name = "message_id",nullable = false)
+    @Schema(description = "消息id")
+    private String messageId;
+
+    @Comment("消息发送时间")
+    @Column(name = "send_timestamp",nullable = false)
+    @Schema(description = "消息发送时间")
+    private Long sendTimestamp;
+
+    @Comment("消息类型")
+    @Column(name = "message_type",nullable = false)
+    @NotBlank(message = "消息类型不能为空", groups = CreateGroup.class)
+    private String messageType;
+
+    @Comment("错误原因")
+    @Column(name = "last_error")
+    @Schema(description = "错误原因")
+    private String lastError;
+
+    @Comment("回复内容")
+    @Column(name = "reply_message")
+    @ColumnType(jdbcType = JDBCType.CLOB)
+    @Schema(description = "回复内容")
+    @JsonCodec
+    private DeviceMessage replyMessage;
+
+    @Comment("下发指令")
+    @Column(name = "send_message")
+    @ColumnType(jdbcType = JDBCType.CLOB)
+    @Schema(description = "下发指令")
+    @JsonCodec
+    private DeviceMessage sendMessage;
+
+    @Column(name = "state",length = 16)
+    @EnumCodec
+    @ColumnType(javaType = String.class)
+    @DefaultValue("wait")
+    @Schema(
+        description = "状态(只读)"
+        ,accessMode = Schema.AccessMode.READ_ONLY
+        , defaultValue = "wait"
+    )
+    private DirectiveState state;
+
+    public static DeviceDirectivesEntity of(String productId,
+                                            String deviceId,
+                                            String messageId,
+                                            long sendTimestamp,
+                                            String messageType, DeviceMessage sendMessage) {
+        return new DeviceDirectivesEntity(productId,deviceId,messageId,sendTimestamp,messageType,null,null,sendMessage,null);
+    }
+
+}

+ 0 - 36
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/entity/DeviceShadowEntity.java

@@ -155,40 +155,4 @@ public class DeviceShadowEntity {
         private long timestamp;
     }
 
-    public static void main(String[] args) {
-       String s="{\n" +
-           "    \"state\": {\n" +
-           "        \"desired\": {\n" +
-           "            \"color\": \"RED\", \n" +
-           "            \"sequence\": [\n" +
-           "                \"RED\", \n" +
-           "                \"GREEN\", \n" +
-           "                \"BLUE\"\n" +
-           "            ]\n" +
-           "        }, \n" +
-           "        \"reported\": {\n" +
-           "            \"color\": \"GREEN\"\n" +
-           "        }\n" +
-           "    }, \n" +
-           "    \"metadata\": {\n" +
-           "        \"desired\": {\n" +
-           "            \"color\": {\n" +
-           "                \"timestamp\": 1469564492\n" +
-           "            }, \n" +
-           "            \"sequence\": {\n" +
-           "                \"timestamp\": 1469564492\n" +
-           "            }\n" +
-           "        }, \n" +
-           "        \"reported\": {\n" +
-           "            \"color\": {\n" +
-           "                \"timestamp\": 1469564492\n" +
-           "            }\n" +
-           "        }\n" +
-           "    }, \n" +
-           "    \"timestamp\": 1469564492, \n" +
-           "    \"version\": 1\n" +
-           "}";
-        DeviceShadowEntity map = JSONUtil.toBean(s, DeviceShadowEntity.class);
-        System.out.println(map);
-    }
 }

+ 0 - 32
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/entity/DeviceTagGeoInfo.java

@@ -1,32 +0,0 @@
-package org.jetlinks.community.device.entity;
-
-import lombok.Data;
-
-import javax.persistence.Column;
-
-/**
- * @author lifang
- * @version 1.0.0
- * @ClassName DeviceTagGeoInfo.java
- * @Description TODO
- * @createTime 2021年10月22日 15:29:00
- */
-@Data
-public class DeviceTagGeoInfo {
-
-    private String deviceId;
-
-    private String deviceName;
-
-    private String productId;
-    private String productName;
-
-    private String locationShape;
-
-    private String locationPoint;
-
-    public static DeviceTagGeoInfo of(DeviceTagEntity tag, DeviceInstanceEntity device){
-        DeviceTagGeoInfo geoProperty = new DeviceTagGeoInfo();
-        return geoProperty;
-    }
-}

+ 28 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/enums/DirectiveState.java

@@ -0,0 +1,28 @@
+package org.jetlinks.community.device.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.hswebframework.web.dict.Dict;
+import org.hswebframework.web.dict.EnumDict;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName DirectiveState.java
+ * @Description TODO
+ * @createTime 2021年11月23日 16:55:00
+ */
+@AllArgsConstructor
+@Getter
+@Dict("directive-state")
+public enum  DirectiveState  implements EnumDict<String> {
+    wait("等待中"),
+    sendError("发送失败"),
+    success("发送成功");
+    private String text;
+    @Override
+    public String getValue() {
+        return this.name();
+    }
+
+}

+ 90 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/interceptor/DeviceDirectiveSendInterceptor.java

@@ -0,0 +1,90 @@
+package org.jetlinks.community.device.interceptor;
+
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.jetlinks.community.device.entity.DeviceDirectivesEntity;
+import org.jetlinks.community.device.enums.DirectiveState;
+import org.jetlinks.community.device.service.DeviceDirectivesService;
+import org.jetlinks.core.device.DeviceOperator;
+import org.jetlinks.core.exception.DeviceOperationException;
+import org.jetlinks.core.message.DeviceMessage;
+import org.jetlinks.core.message.MessageType;
+import org.jetlinks.core.message.function.FunctionInvokeMessage;
+import org.jetlinks.core.message.interceptor.DeviceMessageSenderInterceptor;
+import org.jetlinks.core.message.property.ReadPropertyMessage;
+import org.jetlinks.core.message.property.WritePropertyMessage;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName DeviceDirectiveSendInterceptor.java
+ * @Description TODO
+ * @createTime 2021年11月23日 15:56:00
+ */
+@AllArgsConstructor
+@Slf4j(topic = "system.device.directive")
+@Component
+public class DeviceDirectiveSendInterceptor implements DeviceMessageSenderInterceptor {
+    private final DeviceDirectivesService deviceDirectivesService;
+
+
+    @Override
+    public Mono<DeviceMessage> preSend(DeviceOperator device, DeviceMessage message) {
+        DeviceDirectivesEntity directivesEntity = new DeviceDirectivesEntity();
+        directivesEntity.setState(DirectiveState.wait);
+        directivesEntity.setSendMessage(message);
+        directivesEntity.setSendTimestamp(message.getTimestamp());
+        directivesEntity.setMessageId(message.getMessageId());
+        MessageType directive = isDirective(message);
+        if(directive!=null){
+            directivesEntity.setMessageType(directive.name());
+            directivesEntity.setDeviceId(device.getDeviceId());
+            return device.getProduct()
+                .flatMap(product->{
+                    directivesEntity.setProductId(product.getId());
+                    return deviceDirectivesService.save(directivesEntity)
+                        .thenReturn(message);
+                });
+        }
+        return Mono.just(message);
+    }
+
+    @Override
+    public <R extends DeviceMessage> Flux<R> afterSent(DeviceOperator device, DeviceMessage message, Flux<R> reply) {
+        MessageType directive = isDirective(message);
+        if(directive!=null){
+            return reply.cast(DeviceMessage.class)
+                .map(msg->
+                    deviceDirectivesService.createUpdate()
+                        .where(DeviceDirectivesEntity::getDeviceId,msg.getDeviceId())
+                        .where(DeviceDirectivesEntity::getMessageId,msg.getMessageId())
+                        .set(DeviceDirectivesEntity::getReplyMessage,msg)
+                        .set(DeviceDirectivesEntity::getState,DirectiveState.success)
+                        .execute())
+                .onErrorResume(DeviceOperationException.class,e->deviceDirectivesService.createUpdate()
+                    .where(DeviceDirectivesEntity::getDeviceId,message.getDeviceId())
+                    .where(DeviceDirectivesEntity::getMessageId,message.getMessageId())
+                    .set(DeviceDirectivesEntity::getLastError,e.getMessage())
+                    .set(DeviceDirectivesEntity::getState,DirectiveState.sendError)
+                    .execute().thenReturn(Mono.empty()))
+                .thenMany(reply);
+        }
+        return reply;
+    }
+
+    private MessageType isDirective(DeviceMessage message){
+        if(message instanceof ReadPropertyMessage){
+            return MessageType.READ_PROPERTY;
+        }
+        if(message instanceof FunctionInvokeMessage){
+            return MessageType.INVOKE_FUNCTION;
+        }
+        if(message instanceof WritePropertyMessage){
+            return MessageType.WRITE_PROPERTY;
+        }
+        return null;
+    }
+}

+ 16 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/DeviceDirectivesService.java

@@ -0,0 +1,16 @@
+package org.jetlinks.community.device.service;
+
+import org.hswebframework.web.crud.service.GenericReactiveCrudService;
+import org.jetlinks.community.device.entity.DeviceDirectivesEntity;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName DeviceDirectivesService.java
+ * @Description 设备指令服务
+ * @createTime 2021年11月23日 15:51:00
+ */
+@Service
+public class DeviceDirectivesService extends GenericReactiveCrudService<DeviceDirectivesEntity, String> {
+}

+ 4 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/web/DeviceCategoryController.java

@@ -6,6 +6,8 @@ import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.hswebframework.web.api.crud.entity.TreeSupportEntity;
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.authorization.annotation.Resource;
 import org.hswebframework.web.crud.service.ReactiveCrudService;
 import org.hswebframework.web.crud.web.reactive.ReactiveServiceCrudController;
 import org.hswebframework.web.exception.BusinessException;
@@ -20,6 +22,8 @@ import reactor.core.publisher.Mono;
 @RestController
 @RequestMapping("/device/category")
 @Slf4j
+@Authorize
+@Resource(id="device-category",name = "设备目录")
 @AllArgsConstructor
 @Tag(name = "设备分类目录")
 public class DeviceCategoryController implements

+ 37 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/web/DeviceDirectiveController.java

@@ -0,0 +1,37 @@
+package org.jetlinks.community.device.web;
+
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.authorization.annotation.Resource;
+import org.hswebframework.web.crud.service.ReactiveCrudService;
+import org.hswebframework.web.crud.web.reactive.ReactiveServiceCrudController;
+import org.jetlinks.community.device.entity.DeviceCategory;
+import org.jetlinks.community.device.entity.DeviceDirectivesEntity;
+import org.jetlinks.community.device.service.DeviceDirectivesService;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName DeviceDirectiveController.java
+ * @Description TODO
+ * @createTime 2021年11月23日 17:15:00
+ */
+@RestController
+@RequestMapping("/device/directives")
+@Slf4j
+@Authorize
+@Resource(id="device-directives",name = "设备下发指令")
+@AllArgsConstructor
+@Tag(name = "设备下发指令")
+public class DeviceDirectiveController implements
+    ReactiveServiceCrudController<DeviceDirectivesEntity, String> {
+    private final DeviceDirectivesService directivesService;
+    @Override
+    public ReactiveCrudService<DeviceDirectivesEntity, String> getService() {
+        return directivesService;
+    }
+}

+ 1 - 2
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/web/DeviceMessageController.java

@@ -38,7 +38,7 @@ import java.util.Map;
 import java.util.function.Function;
 
 @RestController
-@RequestMapping({"/device/message/task","/device"})
+@RequestMapping({"/device"})
 @Slf4j
 @Authorize
 @Resource(id = "device-instance", name = "设备实例")
@@ -107,7 +107,6 @@ public class DeviceMessageController implements
     //获取设备固件信息
     @GetMapping("/standard/{deviceId}/firmware/version")
     @SneakyThrows
-    @Deprecated
     public Mono<?> getFirmwareVersion(@PathVariable String deviceId) {
         return registry
             .getDevice(deviceId)