浏览代码

优化设备配置获取

zhou-hao 4 年之前
父节点
当前提交
3072e73518

+ 31 - 16
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/response/DeviceDetail.java

@@ -10,6 +10,7 @@ import org.jetlinks.community.device.entity.DeviceInstanceEntity;
 import org.jetlinks.community.device.entity.DeviceProductEntity;
 import org.jetlinks.community.device.entity.DeviceTagEntity;
 import org.jetlinks.community.device.enums.DeviceState;
+import org.jetlinks.core.metadata.ConfigPropertyMetadata;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
 import reactor.core.publisher.Mono;
@@ -117,22 +118,36 @@ public class DeviceDetail {
         return this;
     }
 
-    public Mono<DeviceDetail> with(DeviceOperator operator) {
-        return Mono.zip(
-            operator.getAddress().defaultIfEmpty("/"),
-            operator.getOnlineTime().defaultIfEmpty(0L),
-            operator.getOfflineTime().defaultIfEmpty(0L),
-            operator.getMetadata()
-        ).doOnNext(tp -> {
-            setOnlineTime(tp.getT2());
-            setOfflineTime(tp.getT3());
-            setAddress(tp.getT1());
-            with(tp.getT4()
-                   .getTags()
-                   .stream()
-                   .map(DeviceTagEntity::of)
-                   .collect(Collectors.toList()));
-        }).thenReturn(this);
+    public Mono<DeviceDetail> with(DeviceOperator operator, List<ConfigPropertyMetadata> configs) {
+        return Mono
+            .zip(
+                //T1: 远程地址
+                operator.getAddress().defaultIfEmpty("/"),
+                //T2: 上线时间
+                operator.getOnlineTime().defaultIfEmpty(0L),
+                //T3: 离线时间
+                operator.getOfflineTime().defaultIfEmpty(0L),
+                //T4: 物模型
+                operator.getMetadata(),
+                //T5: 真实的配置信息
+                operator.getSelfConfigs(configs
+                                            .stream()
+                                            .map(ConfigPropertyMetadata::getProperty)
+                                            .collect(Collectors.toList()))
+            )
+            .doOnNext(tp -> {
+                setOnlineTime(tp.getT2());
+                setOfflineTime(tp.getT3());
+                setAddress(tp.getT1());
+                with(tp.getT4()
+                       .getTags()
+                       .stream()
+                       .map(DeviceTagEntity::of)
+                       .collect(Collectors.toList()));
+                Map<String, Object> cachedConfigs = tp.getT5().getAllValues();
+                cachedConfigs.forEach(configuration::putIfAbsent);
+            })
+            .thenReturn(this);
     }
 
     public synchronized DeviceDetail with(List<DeviceTagEntity> tags) {

+ 43 - 49
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/LocalDeviceInstanceService.java

@@ -4,46 +4,30 @@ import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
-import org.hswebframework.ezorm.core.dsl.Query;
-import org.hswebframework.ezorm.core.param.TermType;
 import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
 import org.hswebframework.ezorm.rdb.mapping.defaults.SaveResult;
-import org.hswebframework.web.api.crud.entity.PagerResult;
-import org.hswebframework.web.api.crud.entity.QueryParamEntity;
 import org.hswebframework.web.crud.service.GenericReactiveCrudService;
 import org.hswebframework.web.exception.BusinessException;
-import org.hswebframework.web.exception.NotFoundException;
 import org.hswebframework.web.id.IDGenerator;
 import org.jetlinks.community.device.entity.*;
 import org.jetlinks.community.device.enums.DeviceState;
 import org.jetlinks.community.device.response.DeviceDeployResult;
 import org.jetlinks.community.device.response.DeviceDetail;
-import org.jetlinks.community.device.response.DeviceInfo;
-import org.jetlinks.community.device.timeseries.DeviceTimeSeriesMetric;
-import org.jetlinks.community.gateway.annotation.Subscribe;
-import org.jetlinks.community.timeseries.TimeSeriesManager;
 import org.jetlinks.community.utils.ErrorUtils;
 import org.jetlinks.core.device.DeviceConfigKey;
 import org.jetlinks.core.device.DeviceOperator;
 import org.jetlinks.core.device.DeviceRegistry;
 import org.jetlinks.core.enums.ErrorCode;
-import org.jetlinks.core.event.EventBus;
-import org.jetlinks.core.event.Subscription;
 import org.jetlinks.core.exception.DeviceOperationException;
 import org.jetlinks.core.message.*;
 import org.jetlinks.core.message.function.FunctionInvokeMessageReply;
 import org.jetlinks.core.message.property.ReadPropertyMessageReply;
 import org.jetlinks.core.message.property.WritePropertyMessageReply;
-import org.jetlinks.core.metadata.DataType;
+import org.jetlinks.core.metadata.ConfigMetadata;
 import org.jetlinks.core.metadata.PropertyMetadata;
-import org.jetlinks.core.metadata.types.ObjectType;
 import org.jetlinks.core.metadata.types.StringType;
-import org.jetlinks.core.utils.FluxUtils;
 import org.reactivestreams.Publisher;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 import reactor.core.scheduler.Schedulers;
@@ -51,30 +35,32 @@ import reactor.util.function.Tuple2;
 import reactor.util.function.Tuple3;
 import reactor.util.function.Tuples;
 
-import javax.annotation.PostConstruct;
-import java.time.Duration;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
-import static org.jetlinks.community.device.timeseries.DeviceTimeSeriesMetric.devicePropertyMetric;
-
 @Service
 @Slf4j
 public class LocalDeviceInstanceService extends GenericReactiveCrudService<DeviceInstanceEntity, String> {
 
-    @Autowired
-    private DeviceRegistry registry;
+    private final DeviceRegistry registry;
 
-    @Autowired
-    private LocalDeviceProductService deviceProductService;
+    private final LocalDeviceProductService deviceProductService;
 
-    @Autowired
-    private EventBus eventBus;
+    private final DeviceConfigMetadataManager metadataManager;
 
-    @Autowired
     @SuppressWarnings("all")
-    private ReactiveRepository<DeviceTagEntity, String> tagRepository;
+    private final ReactiveRepository<DeviceTagEntity, String> tagRepository;
+
+    public LocalDeviceInstanceService(DeviceRegistry registry,
+                                      LocalDeviceProductService deviceProductService,
+                                      DeviceConfigMetadataManager metadataManager,
+                                      ReactiveRepository<DeviceTagEntity, String> tagRepository) {
+        this.registry = registry;
+        this.deviceProductService = deviceProductService;
+        this.metadataManager = metadataManager;
+        this.tagRepository = tagRepository;
+    }
 
 
     @Override
@@ -235,25 +221,34 @@ public class LocalDeviceInstanceService extends GenericReactiveCrudService<Devic
                                                     List<DeviceTagEntity> tags) {
 
         DeviceDetail detail = new DeviceDetail().with(product).with(device).with(tags);
-
-        return registry
-            .getDevice(device.getId())
-            .flatMap(operator -> operator
-                //检查设备的真实状态,可能出现设备已经离线,但是数据库状态未及时更新的.
-                .checkState()
-                .map(DeviceState::of)
-                //检查失败,则返回原始状态
-                .onErrorReturn(device.getState())
-                //如果状态不一致,则需要更新数据库中的状态
-                .filter(state -> state != detail.getState())
-                .doOnNext(detail::setState)
-                .flatMap(state -> createUpdate()
-                    .set(DeviceInstanceEntity::getState, state)
-                    .where(DeviceInstanceEntity::getId, device.getId())
-                    .execute())
-                .thenReturn(operator))
+        return Mono
+            .zip(
+                //设备信息
+                registry
+                    .getDevice(device.getId())
+                    .flatMap(operator -> operator
+                        //检查设备的真实状态,可能出现设备已经离线,但是数据库状态未及时更新的.
+                        .checkState()
+                        .map(DeviceState::of)
+                        //检查失败,则返回原始状态
+                        .onErrorReturn(device.getState())
+                        //如果状态不一致,则需要更新数据库中的状态
+                        .filter(state -> state != detail.getState())
+                        .doOnNext(detail::setState)
+                        .flatMap(state -> createUpdate()
+                            .set(DeviceInstanceEntity::getState, state)
+                            .where(DeviceInstanceEntity::getId, device.getId())
+                            .execute())
+                        .thenReturn(operator)),
+                //配置定义
+                metadataManager
+                    .getDeviceConfigMetadata(device.getId())
+                    .flatMapIterable(ConfigMetadata::getProperties)
+                    .collectList(),
+                detail::with
+            )
             //填充详情信息
-            .flatMap(detail::with)
+            .flatMap(Function.identity())
             .switchIfEmpty(
                 Mono.defer(() -> {
                     //如果设备注册中心里没有设备信息,并且数据库里的状态不是未激活.
@@ -270,8 +265,7 @@ public class LocalDeviceInstanceService extends GenericReactiveCrudService<Devic
             .onErrorResume(err -> {
                 log.warn("get device detail error", err);
                 return Mono.just(detail);
-            })
-            ;
+            });
 
     }
 

+ 27 - 6
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/web/DeviceInstanceController.java

@@ -36,6 +36,7 @@ import org.jetlinks.community.io.excel.ImportExportService;
 import org.jetlinks.community.io.utils.FileUtils;
 import org.jetlinks.community.timeseries.query.AggregationData;
 import org.jetlinks.core.ProtocolSupport;
+import org.jetlinks.core.Values;
 import org.jetlinks.core.device.DeviceConfigKey;
 import org.jetlinks.core.device.DeviceOperator;
 import org.jetlinks.core.device.DeviceProductOperator;
@@ -483,18 +484,38 @@ public class DeviceInstanceController implements
         parameter.setPaging(false);
         parameter.toNestQuery(q -> q.is(DeviceInstanceEntity::getProductId, productId));
         return getDeviceProductDetail(productId)
-            .map(tp4 -> DeviceExcelInfo.getExportHeaderMapping(tp4.getT3().getTags(), tp4.getT4()))
-            .defaultIfEmpty(DeviceExcelInfo.getExportHeaderMapping(Collections.emptyList(), Collections.emptyList()))
-            .flatMapMany(headers ->
+            .map(tp4 -> Tuples
+                .of(
+                    //表头
+                    DeviceExcelInfo.getExportHeaderMapping(tp4.getT3().getTags(), tp4.getT4()),
+                    //配置key集合
+                    tp4
+                        .getT4()
+                        .stream()
+                        .map(ConfigPropertyMetadata::getProperty)
+                        .collect(Collectors.toList())
+                ))
+            .defaultIfEmpty(Tuples.of(DeviceExcelInfo.getExportHeaderMapping(Collections.emptyList(),
+                                                                             Collections.emptyList()),
+                                      Collections.emptyList()))
+            .flatMapMany(headerAndConfigKey ->
                              ReactorExcel.<DeviceExcelInfo>writer(format)
-                                 .headers(headers)
+                                 .headers(headerAndConfigKey.getT1())
                                  .converter(DeviceExcelInfo::toMap)
                                  .writeBuffer(
                                      service.query(parameter)
-                                            .map(entity -> {
+                                            .flatMap(entity -> {
                                                 DeviceExcelInfo exportEntity = FastBeanCopier.copy(entity, new DeviceExcelInfo(), "state");
                                                 exportEntity.setState(entity.getState().getText());
-                                                return exportEntity;
+                                                return registry
+                                                    .getDevice(entity.getId())
+                                                    .flatMap(deviceOperator -> deviceOperator
+                                                        .getSelfConfigs(headerAndConfigKey.getT2())
+                                                        .map(Values::getAllValues))
+                                                    .doOnNext(configs -> exportEntity
+                                                        .getConfiguration()
+                                                        .putAll(configs))
+                                                    .thenReturn(exportEntity);
                                             })
                                             .buffer(200)
                                             .flatMap(list -> {