ソースを参照

设备注册时,如果设备已经注册则更新配置等信息。

zhouhao 3 年 前
コミット
0a6869fa44

+ 64 - 1
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/entity/DeviceInstanceEntity.java

@@ -13,8 +13,12 @@ import org.jetlinks.community.device.enums.DeviceFeature;
 import org.jetlinks.community.device.enums.DeviceState;
 import org.jetlinks.core.device.DeviceConfigKey;
 import org.jetlinks.core.device.DeviceInfo;
+import org.jetlinks.core.metadata.DeviceMetadata;
+import org.jetlinks.core.metadata.MergeOption;
+import org.jetlinks.supports.official.JetLinksDeviceMetadataCodec;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
+import reactor.core.publisher.Mono;
 
 import javax.persistence.Column;
 import javax.persistence.GeneratedValue;
@@ -23,7 +27,7 @@ import javax.persistence.Table;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.Pattern;
 import java.sql.JDBCType;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Stream;
 
 @Getter
@@ -158,6 +162,65 @@ public class DeviceInstanceEntity extends GenericEntity<String> implements Recor
         return info;
     }
 
+    public void mergeConfiguration(Map<String, Object> configuration) {
+        if (this.configuration == null) {
+            this.configuration = new HashMap<>();
+        }
+        Map<String, Object> newConf = new HashMap<>(configuration);
+        //状态自管理,单独设置到feature中
+        Object selfManageState = newConf.remove(DeviceConfigKey.selfManageState.getKey());
+        if (null != selfManageState) {
+            if (Boolean.TRUE.equals(selfManageState)) {
+                addFeature(DeviceFeature.selfManageState);
+            } else {
+                removeFeature(DeviceFeature.selfManageState);
+            }
+        }
+        //物模型单独设置
+        Object metadata = newConf.remove(DeviceConfigKey.metadata.getKey());
+        if (null != metadata) {
+            setDeriveMetadata(String.valueOf(metadata));
+        }
+
+        this.configuration.putAll(newConf);
+    }
+
+    public void removeFeature(DeviceFeature... features) {
+        if (this.features != null) {
+            List<DeviceFeature> featureList = new ArrayList<>(Arrays.asList(this.features));
+            for (DeviceFeature feature : features) {
+                featureList.remove(feature);
+            }
+            this.features = featureList.toArray(new DeviceFeature[0]);
+        }
+    }
+
+    public Mono<String> mergeMetadata(String metadata) {
+        return JetLinksDeviceMetadataCodec
+            .getInstance()
+            .decode(metadata)
+            .flatMap(this::mergeMetadata);
+    }
+
+    public Mono<String> mergeMetadata(DeviceMetadata metadata) {
+        JetLinksDeviceMetadataCodec codec = JetLinksDeviceMetadataCodec.getInstance();
+
+        if (StringUtils.isEmpty(this.getDeriveMetadata())) {
+            return codec.encode(metadata)
+                        .doOnNext(this::setDeriveMetadata);
+        }
+
+        return Mono
+            .zip(
+                codec.decode(getDeriveMetadata()),
+                Mono.just(metadata),
+                (derive, another) -> derive.merge(another, MergeOption.ignoreExists)
+            )
+            .flatMap(codec::encode)
+            .doOnNext(this::setDeriveMetadata);
+    }
+
+
     public void addFeature(DeviceFeature... features) {
         if (this.features == null) {
             this.features = features;

+ 26 - 10
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/DeviceMessageBusinessHandler.java

@@ -4,6 +4,7 @@ import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.MapUtils;
 import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
+import org.jetlinks.community.PropertyConstants;
 import org.jetlinks.community.device.entity.DeviceInstanceEntity;
 import org.jetlinks.community.device.entity.DeviceTagEntity;
 import org.jetlinks.community.device.enums.DeviceFeature;
@@ -49,6 +50,14 @@ public class DeviceMessageBusinessHandler {
 
     private final EventBus eventBus;
 
+    /**
+     * 自动注册设备信息
+     * <p>
+     * 设备消息的header需要包含{@code deviceName},{@code productId}才会自动注册.、
+     *
+     * @param message 注册消息
+     * @return 注册后的设备操作接口
+     */
     private Mono<DeviceOperator> doAutoRegister(DeviceRegisterMessage message) {
         //自动注册
         return Mono
@@ -75,15 +84,18 @@ public class DeviceMessageBusinessHandler {
                 instance.setCreateTimeNow();
                 instance.setCreatorId(tps.getT4().getCreatorId());
                 instance.setOrgId(tps.getT4().getOrgId());
+
+                //设备自状态管理
+                //网关注册设备子设备时,设置自状态管理。
+                //在检查子设备状态时,将会发送ChildDeviceMessage<DeviceStateCheckMessage>到网关
+                //网关需要回复ChildDeviceMessageReply<DeviceStateCheckMessageReply>
                 @SuppressWarnings("all")
                 boolean selfManageState = CastUtils
                     .castBoolean(tps.getT5().getOrDefault(DeviceConfigKey.selfManageState.getKey(), false));
 
-                if (selfManageState) {
-                    instance.addFeature(DeviceFeature.selfManageState);
-                }
-
                 instance.setState(selfManageState ? DeviceState.offline : DeviceState.online);
+                //合并配置
+                instance.mergeConfiguration(tps.getT5());
 
                 return deviceService
                     .save(Mono.just(instance))
@@ -96,25 +108,29 @@ public class DeviceMessageBusinessHandler {
             });
     }
 
+
     @Subscribe("/device/*/*/register")
     @Transactional(propagation = Propagation.NEVER)
     public Mono<Void> autoRegisterDevice(DeviceRegisterMessage message) {
         return registry
             .getDevice(message.getDeviceId())
             .flatMap(device -> {
+                //注册消息中修改了配置信息
                 @SuppressWarnings("all")
                 Map<String, Object> config = message.getHeader("configuration").map(Map.class::cast).orElse(null);
                 if (MapUtils.isNotEmpty(config)) {
-                    return device
-                        .setConfigs(config)
+
+                    return deviceService
+                        .mergeConfiguration(device.getDeviceId(), config, update ->
+                            //更新设备名称
+                            update.set(DeviceInstanceEntity::getName,
+                                       message.getHeader(PropertyConstants.deviceName).orElse(null)))
                         .thenReturn(device);
                 }
                 return Mono.just(device);
             })
-            .switchIfEmpty(Mono.defer(() -> {
-                //自动注册
-                return doAutoRegister(message);
-            }))
+            //注册中心中没有此设备则进行自动注册
+            .switchIfEmpty(Mono.defer(() -> doAutoRegister(message)))
             .then();
     }
 

+ 32 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/LocalDeviceInstanceService.java

@@ -5,6 +5,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
 import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
+import org.hswebframework.ezorm.rdb.mapping.ReactiveUpdate;
 import org.hswebframework.ezorm.rdb.mapping.defaults.SaveResult;
 import org.hswebframework.ezorm.rdb.operator.dml.Terms;
 import org.hswebframework.web.crud.service.GenericReactiveCrudService;
@@ -477,4 +478,35 @@ public class LocalDeviceInstanceService extends GenericReactiveCrudService<Devic
         return checker.check(instance);
     }
 
+    public Mono<Void> mergeConfiguration(String deviceId,
+                                         Map<String, Object> configuration,
+                                         Function<ReactiveUpdate<DeviceInstanceEntity>,
+                                             ReactiveUpdate<DeviceInstanceEntity>> updateOperation) {
+        if (MapUtils.isEmpty(configuration)) {
+            return Mono.empty();
+        }
+        return this
+            .findById(deviceId)
+            .flatMap(device -> {
+                //合并更新配置
+                device.mergeConfiguration(configuration);
+                return createUpdate()
+                    .set(device::getConfiguration)
+                    .set(device::getFeatures)
+                    .set(device::getDeriveMetadata)
+                    .as(updateOperation)
+                    .where(device::getId)
+                    .execute();
+            })
+            .then(
+                //更新缓存里到信息
+                registry
+                    .getDevice(deviceId)
+                    .flatMap(device -> device.setConfigs(configuration))
+            )
+            .then();
+
+    }
+
+
 }

+ 24 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/web/DeviceInstanceController.java

@@ -819,5 +819,29 @@ public class DeviceInstanceController implements
                       .then());
     }
 
+    //合并产品的物模型
+    @PutMapping(value = "/{id}/metadata/merge-product")
+    @SaveAction
+    @Operation(summary = "合并产品的物模型")
+    public Mono<Void> mergeProductMetadata(@PathVariable String id) {
+        return service
+            .findById(id)
+            //只有单独保存过物模型的才合并
+            .filter(deviceInstance -> StringUtils.hasText(deviceInstance.getDeriveMetadata()))
+            .flatMap(deviceInstance -> productService
+                .findById(deviceInstance.getProductId())
+                .flatMap(product -> deviceInstance.mergeMetadata(product.getMetadata()))
+                .then(
+                    Mono.defer(() -> service
+                        .createUpdate()
+                        .set(deviceInstance::getDeriveMetadata)
+                        .where(deviceInstance::getId)
+                        .execute()
+                        .then(registry.getDevice(deviceInstance.getId()))
+                        .flatMap(device -> device.updateMetadata(deviceInstance.getDeriveMetadata()))
+                        .then())
+                ));
+    }
+
 
 }

+ 1 - 1
pom.xml

@@ -20,7 +20,7 @@
         <java.version>1.8</java.version>
         <project.build.jdk>${java.version}</project.build.jdk>
         <hsweb.framework.version>4.0.13-SNAPSHOT</hsweb.framework.version>
-        <easyorm.version>4.0.13-SNAPSHOT</easyorm.version>
+        <easyorm.version>4.0.13</easyorm.version>
         <hsweb.expands.version>3.0.2</hsweb.expands.version>
         <jetlinks.version>1.1.9-SNAPSHOT</jetlinks.version>
         <r2dbc.version>Arabba-SR10</r2dbc.version>