|
|
@@ -15,6 +15,7 @@ import org.jetlinks.community.device.enums.DeviceFeature;
|
|
|
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.gateway.annotation.Subscribe;
|
|
|
import org.jetlinks.community.utils.ErrorUtils;
|
|
|
import org.jetlinks.core.device.DeviceConfigKey;
|
|
|
import org.jetlinks.core.device.DeviceOperator;
|
|
|
@@ -23,17 +24,20 @@ 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.DeviceMessage;
|
|
|
import org.jetlinks.core.message.DeviceMessageReply;
|
|
|
import org.jetlinks.core.message.FunctionInvokeMessageSender;
|
|
|
import org.jetlinks.core.message.WritePropertyMessageSender;
|
|
|
import org.jetlinks.core.message.function.FunctionInvokeMessageReply;
|
|
|
import org.jetlinks.core.message.property.ReadPropertyMessageReply;
|
|
|
+import org.jetlinks.core.message.property.ReportPropertyMessage;
|
|
|
import org.jetlinks.core.message.property.WritePropertyMessageReply;
|
|
|
-import org.jetlinks.core.metadata.ConfigMetadata;
|
|
|
-import org.jetlinks.core.metadata.PropertyMetadata;
|
|
|
+import org.jetlinks.core.metadata.*;
|
|
|
import org.jetlinks.core.metadata.types.StringType;
|
|
|
import org.reactivestreams.Publisher;
|
|
|
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;
|
|
|
@@ -72,8 +76,8 @@ public class LocalDeviceInstanceService extends GenericReactiveCrudService<Devic
|
|
|
@Override
|
|
|
public Mono<SaveResult> save(Publisher<DeviceInstanceEntity> entityPublisher) {
|
|
|
return Flux.from(entityPublisher)
|
|
|
- .doOnNext(instance -> instance.setState(null))
|
|
|
- .as(super::save);
|
|
|
+ .doOnNext(instance -> instance.setState(null))
|
|
|
+ .as(super::save);
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -96,13 +100,13 @@ public class LocalDeviceInstanceService extends GenericReactiveCrudService<Devic
|
|
|
if (MapUtils.isNotEmpty(product.getConfiguration())) {
|
|
|
if (MapUtils.isNotEmpty(device.getConfiguration())) {
|
|
|
product.getConfiguration()
|
|
|
- .keySet()
|
|
|
- .forEach(device.getConfiguration()::remove);
|
|
|
+ .keySet()
|
|
|
+ .forEach(device.getConfiguration()::remove);
|
|
|
}
|
|
|
//重置注册中心里的配置
|
|
|
return registry.getDevice(deviceId)
|
|
|
- .flatMap(opts -> opts.removeConfigs(product.getConfiguration().keySet()))
|
|
|
- .then();
|
|
|
+ .flatMap(opts -> opts.removeConfigs(product.getConfiguration().keySet()))
|
|
|
+ .then();
|
|
|
}
|
|
|
return Mono.empty();
|
|
|
}).then(
|
|
|
@@ -186,9 +190,9 @@ public class LocalDeviceInstanceService extends GenericReactiveCrudService<Devic
|
|
|
.flatMap(product -> registry
|
|
|
.unregisterDevice(id)
|
|
|
.then(createUpdate()
|
|
|
- .set(DeviceInstanceEntity::getState, DeviceState.notActive.getValue())
|
|
|
- .where(DeviceInstanceEntity::getId, id)
|
|
|
- .execute()));
|
|
|
+ .set(DeviceInstanceEntity::getState, DeviceState.notActive.getValue())
|
|
|
+ .where(DeviceInstanceEntity::getId, id)
|
|
|
+ .execute()));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -199,12 +203,12 @@ public class LocalDeviceInstanceService extends GenericReactiveCrudService<Devic
|
|
|
*/
|
|
|
public Mono<Integer> unregisterDevice(String id) {
|
|
|
return this.findById(Mono.just(id))
|
|
|
- .flatMap(device -> registry
|
|
|
- .unregisterDevice(id)
|
|
|
- .then(createUpdate()
|
|
|
- .set(DeviceInstanceEntity::getState, DeviceState.notActive.getValue())
|
|
|
- .where(DeviceInstanceEntity::getId, id)
|
|
|
- .execute()));
|
|
|
+ .flatMap(device -> registry
|
|
|
+ .unregisterDevice(id)
|
|
|
+ .then(createUpdate()
|
|
|
+ .set(DeviceInstanceEntity::getState, DeviceState.notActive.getValue())
|
|
|
+ .where(DeviceInstanceEntity::getId, id)
|
|
|
+ .execute()));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -215,12 +219,12 @@ public class LocalDeviceInstanceService extends GenericReactiveCrudService<Devic
|
|
|
*/
|
|
|
public Mono<Integer> unregisterDevice(Publisher<String> ids) {
|
|
|
return Flux.from(ids)
|
|
|
- .flatMap(id -> registry.unregisterDevice(id).thenReturn(id))
|
|
|
- .collectList()
|
|
|
- .flatMap(list -> createUpdate()
|
|
|
- .set(DeviceInstanceEntity::getState, DeviceState.notActive.getValue())
|
|
|
- .where().in(DeviceInstanceEntity::getId, list)
|
|
|
- .execute());
|
|
|
+ .flatMap(id -> registry.unregisterDevice(id).thenReturn(id))
|
|
|
+ .collectList()
|
|
|
+ .flatMap(list -> createUpdate()
|
|
|
+ .set(DeviceInstanceEntity::getState, DeviceState.notActive.getValue())
|
|
|
+ .where().in(DeviceInstanceEntity::getId, list)
|
|
|
+ .execute());
|
|
|
}
|
|
|
|
|
|
protected Mono<DeviceDetail> createDeviceDetail(DeviceProductEntity product,
|
|
|
@@ -281,11 +285,11 @@ public class LocalDeviceInstanceService extends GenericReactiveCrudService<Devic
|
|
|
.findById(deviceId)
|
|
|
.zipWhen(device -> deviceProductService.findById(device.getProductId()))//合并型号
|
|
|
.zipWith(tagRepository
|
|
|
- .createQuery()
|
|
|
- .where(DeviceTagEntity::getDeviceId, deviceId)
|
|
|
- .fetch()
|
|
|
- .collectList()
|
|
|
- .defaultIfEmpty(Collections.emptyList()) //合并标签
|
|
|
+ .createQuery()
|
|
|
+ .where(DeviceTagEntity::getDeviceId, deviceId)
|
|
|
+ .fetch()
|
|
|
+ .collectList()
|
|
|
+ .defaultIfEmpty(Collections.emptyList()) //合并标签
|
|
|
, (left, right) -> Tuples.of(left.getT2(), left.getT1(), right))
|
|
|
.flatMap(tp3 -> createDeviceDetail(tp3.getT1(), tp3.getT2(), tp3.getT3()));
|
|
|
}
|
|
|
@@ -366,9 +370,9 @@ public class LocalDeviceInstanceService extends GenericReactiveCrudService<Devic
|
|
|
.defaultIfEmpty(0)
|
|
|
)
|
|
|
.thenReturn(deviceId
|
|
|
- .stream()
|
|
|
- .map(id -> DeviceStateInfo.of(id, state))
|
|
|
- .collect(Collectors.toList()));
|
|
|
+ .stream()
|
|
|
+ .map(id -> DeviceStateInfo.of(id, state))
|
|
|
+ .collect(Collectors.toList()));
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
@@ -441,6 +445,40 @@ public class LocalDeviceInstanceService extends GenericReactiveCrudService<Devic
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+ @Subscribe("/device/*/*/message/property/report")
|
|
|
+ @Transactional(propagation = Propagation.NEVER)
|
|
|
+ public Mono<Void> writeProperties(DeviceMessage deviceMessage){
|
|
|
+ return registry.getDevice(deviceMessage.getDeviceId())
|
|
|
+ .flatMap(DeviceOperator::getMetadata)
|
|
|
+ .switchIfEmpty(Mono.just(new SimpleDeviceMetadata()))
|
|
|
+ .doOnNext(metadataMono -> {
|
|
|
+ ReportPropertyMessage message= (ReportPropertyMessage) deviceMessage;
|
|
|
+ List<PropertyMetadata> properties = metadataMono.getProperties();
|
|
|
+ if(properties==null||properties.size()<1){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Map<String, Object> sendProperties = message.getProperties();
|
|
|
+ Map<String, List<PropertyMetadata>> metadataNameMap = properties.parallelStream()
|
|
|
+ .collect(Collectors.groupingBy(Metadata::getId));
|
|
|
+ //获取有效的属性值
|
|
|
+ Set<String> existProperties = sendProperties.keySet().stream().filter(name -> metadataNameMap.containsKey(name)).collect(Collectors.toSet());
|
|
|
+ List<String> validateProperties = existProperties.stream().filter(propertyName -> {
|
|
|
+ Object value = sendProperties.get(propertyName);
|
|
|
+ PropertyMetadata propertyMetadata = Optional.ofNullable(Optional.ofNullable(metadataNameMap.get(propertyName)).orElse(new ArrayList<>()).get(0)).orElse(new SimplePropertyMetadata());
|
|
|
+ DataType valueType = propertyMetadata.getValueType();
|
|
|
+ try {
|
|
|
+ valueType.validate(value);
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ validateProperties.forEach(key->map.put(key,sendProperties.get(key)));
|
|
|
+ writeProperties(deviceMessage.getDeviceId(),map);
|
|
|
+ }).then();
|
|
|
+}
|
|
|
+
|
|
|
//设备功能调用
|
|
|
@SneakyThrows
|
|
|
public Flux<?> invokeFunction(String deviceId,
|