Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
11abcb6834
|
|
@ -1,7 +1,7 @@
|
|||
# JetLinks 物联网基础平台
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ services:
|
|||
links:
|
||||
- jetlinks:jetlinks
|
||||
jetlinks:
|
||||
image: registry.cn-shenzhen.aliyuncs.com/jetlinks/jetlinks-standalone:1.8.0-SNAPSHOT
|
||||
image: registry.cn-shenzhen.aliyuncs.com/jetlinks/jetlinks-standalone:1.8.0
|
||||
container_name: jetlinks-ce
|
||||
ports:
|
||||
- 8848:8848 # API端口
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jetlinks-components</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,37 @@
|
|||
package org.jetlinks.community;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONType;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@JsonDeserialize(using = Interval.IntervalJSONDeserializer.class)
|
||||
@JSONType(deserializer = Interval.IntervalJSONDeserializer.class)
|
||||
public class Interval {
|
||||
|
||||
public static String year = "y";
|
||||
public static String quarter = "q";
|
||||
public static String month = "M";
|
||||
public static String weeks = "w";
|
||||
public static String days = "d";
|
||||
public static String hours = "h";
|
||||
public static String minutes = "m";
|
||||
public static String seconds = "s";
|
||||
public static final String year = "y";
|
||||
public static final String quarter = "q";
|
||||
public static final String month = "M";
|
||||
public static final String weeks = "w";
|
||||
public static final String days = "d";
|
||||
public static final String hours = "h";
|
||||
public static final String minutes = "m";
|
||||
public static final String seconds = "s";
|
||||
|
||||
private final BigDecimal number;
|
||||
private BigDecimal number;
|
||||
|
||||
private final String expression;
|
||||
private String expression;
|
||||
|
||||
public boolean isFixed() {
|
||||
return expression.equalsIgnoreCase(hours) ||
|
||||
|
|
@ -61,18 +72,55 @@ public class Interval {
|
|||
|
||||
public static Interval of(String expr) {
|
||||
|
||||
char[] number = new char[32];
|
||||
char[] chars = expr.toCharArray();
|
||||
int numIndex = 0;
|
||||
for (char c : expr.toCharArray()) {
|
||||
if (c == '-' || c == '.' || (c >= '0' && c <= '9')) {
|
||||
number[numIndex++] = c;
|
||||
continue;
|
||||
numIndex++;
|
||||
} else {
|
||||
BigDecimal val = new BigDecimal(chars, 0, numIndex);
|
||||
return new Interval(val, expr.substring(numIndex));
|
||||
}
|
||||
BigDecimal val = new BigDecimal(number, 0, numIndex);
|
||||
return new Interval(val, expr.substring(numIndex));
|
||||
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("can not parse interval expression:" + expr);
|
||||
}
|
||||
|
||||
public String getDefaultFormat() {
|
||||
switch (getExpression()) {
|
||||
case year:
|
||||
return "yyyy";
|
||||
case quarter:
|
||||
case month:
|
||||
return "yyyy-MM";
|
||||
case days:
|
||||
return "yyyy-MM-dd";
|
||||
case hours:
|
||||
return "MM-dd HH";
|
||||
case minutes:
|
||||
return "MM-dd HH:mm";
|
||||
case seconds:
|
||||
return "HH:mm:ss";
|
||||
default:
|
||||
return "yyyy-MM-dd HH:mm:ss";
|
||||
}
|
||||
}
|
||||
|
||||
public static class IntervalJSONDeserializer extends JsonDeserializer<Interval> {
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public Interval deserialize(JsonParser jp, DeserializationContext ctxt) {
|
||||
JsonNode node = jp.getCodec().readTree(jp);
|
||||
|
||||
String currentName = jp.currentName();
|
||||
Object currentValue = jp.getCurrentValue();
|
||||
if (currentName == null || currentValue == null) {
|
||||
return null;
|
||||
}
|
||||
return of(node.textValue());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@ public class Version {
|
|||
|
||||
private final String edition = "community";
|
||||
|
||||
private final String version = "1.8.0-SNAPSHOT";
|
||||
private final String version = "1.8.0";
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jetlinks-components</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jetlinks-components</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
|||
|
|
@ -88,17 +88,17 @@ public class ReactiveAggregationService implements AggregationService {
|
|||
builder.timeZone(ZoneId.systemDefault());
|
||||
builder.order(BucketOrder.key(false));
|
||||
if (timeGroup.getInterval() != null) {
|
||||
Interval interval = timeGroup.getInterval();
|
||||
String intervalString = interval.toString();
|
||||
if (restClient.serverVersion().after(Version.V_7_2_0)) {
|
||||
Interval interval = timeGroup.getInterval();
|
||||
if (interval.isFixed()) {
|
||||
builder.fixedInterval(new DateHistogramInterval(timeGroup.getInterval().toString()));
|
||||
} else if (interval.isCalendar()) {
|
||||
builder.calendarInterval(new DateHistogramInterval(timeGroup.getInterval().toString()));
|
||||
if (DateHistogramAggregationBuilder.DATE_FIELD_UNITS.containsKey(intervalString)) {
|
||||
builder.calendarInterval(new DateHistogramInterval(intervalString));
|
||||
} else {
|
||||
builder.dateHistogramInterval(new DateHistogramInterval(timeGroup.getInterval().toString()));
|
||||
builder.fixedInterval(new DateHistogramInterval(intervalString));
|
||||
// builder.dateHistogramInterval(new DateHistogramInterval(intervalString));
|
||||
}
|
||||
} else {
|
||||
builder.dateHistogramInterval(new DateHistogramInterval(timeGroup.getInterval().toString()));
|
||||
builder.dateHistogramInterval(new DateHistogramInterval(intervalString));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jetlinks-components</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jetlinks-components</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jetlinks-components</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>network-component</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>network-component</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jetlinks-components</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<packaging>pom</packaging>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>network-component</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>notify-component</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>notify-component</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>notify-component</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>notify-component</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>notify-component</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>notify-component</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jetlinks-components</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jetlinks-community</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jetlinks-components</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jetlinks-components</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<artifactId>jetlinks-manager</artifactId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>authentication-manager</artifactId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<artifactId>jetlinks-manager</artifactId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>device-manager</artifactId>
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ public class DeviceInstanceEntity extends GenericEntity<String> implements Recor
|
|||
@Schema(description = "派生物模型(预留)")
|
||||
private String deriveMetadata;
|
||||
|
||||
@Column(name = "state")
|
||||
@Column(name = "state",length = 16)
|
||||
@EnumCodec
|
||||
@ColumnType(javaType = String.class)
|
||||
@DefaultValue("notActive")
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ import org.hswebframework.web.api.crud.entity.GenericEntity;
|
|||
import org.hswebframework.web.crud.annotation.EnableEntityEvent;
|
||||
import org.hswebframework.web.crud.generator.Generators;
|
||||
import org.hswebframework.web.validator.CreateGroup;
|
||||
import org.jetlinks.core.metadata.Converter;
|
||||
import org.jetlinks.core.metadata.DataType;
|
||||
import org.jetlinks.core.metadata.PropertyMetadata;
|
||||
|
||||
import javax.persistence.Column;
|
||||
|
|
@ -73,6 +75,21 @@ public class DeviceTagEntity extends GenericEntity<String> {
|
|||
return entity;
|
||||
}
|
||||
|
||||
public static DeviceTagEntity of(PropertyMetadata property, Object value) {
|
||||
DeviceTagEntity tag = of(property);
|
||||
|
||||
DataType type = property.getValueType();
|
||||
if (type instanceof Converter) {
|
||||
Object newValue = ((Converter<?>) type).convert(value);
|
||||
if (newValue != null) {
|
||||
value = newValue;
|
||||
}
|
||||
}
|
||||
tag.setValue(String.valueOf(value));
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
public static String createTagId(String deviceId, String key) {
|
||||
return DigestUtils.md5Hex(deviceId + ":" + key);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import lombok.Getter;
|
|||
import lombok.Setter;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.jetlinks.community.device.enums.DeviceType;
|
||||
import org.jetlinks.core.Values;
|
||||
import org.jetlinks.core.device.DeviceOperator;
|
||||
import org.jetlinks.community.device.entity.DeviceInstanceEntity;
|
||||
import org.jetlinks.community.device.entity.DeviceProductEntity;
|
||||
|
|
@ -116,6 +117,9 @@ public class DeviceDetail {
|
|||
@Schema(description = "标签信息")
|
||||
private List<DeviceTagEntity> tags = new ArrayList<>();
|
||||
|
||||
@Schema(description = "设备描述")
|
||||
private String description;
|
||||
|
||||
public DeviceDetail notActive() {
|
||||
|
||||
state = DeviceState.notActive;
|
||||
|
|
@ -138,6 +142,7 @@ public class DeviceDetail {
|
|||
.stream()
|
||||
.map(ConfigPropertyMetadata::getProperty)
|
||||
.collect(Collectors.toList()))
|
||||
.defaultIfEmpty(Values.of(Collections.emptyMap()))
|
||||
)
|
||||
.doOnNext(tp -> {
|
||||
setOnlineTime(tp.getT2());
|
||||
|
|
@ -205,6 +210,7 @@ public class DeviceDetail {
|
|||
setState(device.getState());
|
||||
setOrgId(device.getOrgId());
|
||||
setParentId(device.getParentId());
|
||||
setDescription(device.getDescribe());
|
||||
Optional.ofNullable(device.getRegistryTime())
|
||||
.ifPresent(this::setRegisterTime);
|
||||
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ public class DeviceMessageBusinessHandler {
|
|||
.map(e -> {
|
||||
DeviceTagEntity tagEntity = metadata
|
||||
.getTag(e.getKey())
|
||||
.map(DeviceTagEntity::of)
|
||||
.map(tagMeta -> DeviceTagEntity.of(tagMeta, e.getValue()))
|
||||
.orElseGet(() -> {
|
||||
DeviceTagEntity entity = new DeviceTagEntity();
|
||||
entity.setKey(e.getKey());
|
||||
|
|
@ -171,9 +171,9 @@ public class DeviceMessageBusinessHandler {
|
|||
entity.setName(e.getKey());
|
||||
entity.setCreateTime(new Date());
|
||||
entity.setDescription("设备上报");
|
||||
entity.setValue(String.valueOf(e.getValue()));
|
||||
return entity;
|
||||
});
|
||||
tagEntity.setValue(String.valueOf(e.getValue()));
|
||||
tagEntity.setDeviceId(deviceId);
|
||||
tagEntity.setId(DeviceTagEntity.createTagId(deviceId, tagEntity.getKey()));
|
||||
return tagEntity;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ import org.hswebframework.web.authorization.annotation.*;
|
|||
import org.hswebframework.web.bean.FastBeanCopier;
|
||||
import org.hswebframework.web.crud.web.reactive.ReactiveServiceCrudController;
|
||||
import org.hswebframework.web.exception.BusinessException;
|
||||
import org.hswebframework.web.exception.NotFoundException;
|
||||
import org.hswebframework.web.exception.ValidationException;
|
||||
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;
|
||||
|
|
@ -37,17 +39,20 @@ 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;
|
||||
import org.jetlinks.core.device.DeviceRegistry;
|
||||
import org.jetlinks.core.device.*;
|
||||
import org.jetlinks.core.device.manager.DeviceBindHolder;
|
||||
import org.jetlinks.core.device.manager.DeviceBindProvider;
|
||||
import org.jetlinks.core.exception.DeviceOperationException;
|
||||
import org.jetlinks.core.message.DeviceMessage;
|
||||
import org.jetlinks.core.message.Message;
|
||||
import org.jetlinks.core.message.MessageType;
|
||||
import org.jetlinks.core.message.RepayableDeviceMessage;
|
||||
import org.jetlinks.core.metadata.ConfigMetadata;
|
||||
import org.jetlinks.core.metadata.ConfigPropertyMetadata;
|
||||
import org.jetlinks.core.metadata.DeviceMetadata;
|
||||
import org.springframework.core.io.buffer.DataBufferFactory;
|
||||
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
|
|
@ -64,6 +69,7 @@ import java.io.IOException;
|
|||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
|
@ -630,4 +636,106 @@ public class DeviceInstanceController implements
|
|||
.map(AggregationData::values);
|
||||
}
|
||||
|
||||
//发送设备指令
|
||||
@PostMapping("/{deviceId:.+}/message")
|
||||
@SneakyThrows
|
||||
@QueryAction
|
||||
@Operation(summary = "发送指令到设备")
|
||||
@SuppressWarnings("all")
|
||||
public Flux<?> sendMessage(@PathVariable @Parameter(description = "设备ID") String deviceId,
|
||||
@RequestBody Mono<Map<String, Object>> properties) {
|
||||
return properties
|
||||
.flatMapMany(props -> {
|
||||
return Mono
|
||||
.zip(
|
||||
registry
|
||||
.getDevice(deviceId)
|
||||
.map(DeviceOperator::messageSender)
|
||||
.switchIfEmpty(Mono.error(() -> new NotFoundException("设备不存在或未激活"))),
|
||||
Mono.<Message>justOrEmpty(MessageType.convertMessage(props))
|
||||
.cast(DeviceMessage.class)
|
||||
.switchIfEmpty(Mono.error(() -> new UnsupportedOperationException("不支持的消息格式")))
|
||||
).flatMapMany(tp2 -> {
|
||||
DeviceMessageSender sender = tp2.getT1();
|
||||
DeviceMessage message = tp2.getT2();
|
||||
|
||||
Map<String, String> copy = new HashMap<>();
|
||||
copy.put("deviceId", deviceId);
|
||||
if (!StringUtils.hasText(message.getMessageId())) {
|
||||
copy.put("messageId", IDGenerator.SNOW_FLAKE_STRING.generate());
|
||||
}
|
||||
FastBeanCopier.copy(copy, message);
|
||||
return sender
|
||||
.send(message)
|
||||
.onErrorResume(DeviceOperationException.class, error -> {
|
||||
if (message instanceof RepayableDeviceMessage) {
|
||||
return Mono.just(
|
||||
((RepayableDeviceMessage) message).newReply().error(error)
|
||||
);
|
||||
}
|
||||
return Mono.error(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//发送设备指令
|
||||
@PostMapping("/messages")
|
||||
@SneakyThrows
|
||||
@QueryAction
|
||||
@Operation(summary = "批量发送指令到设备")
|
||||
@SuppressWarnings("all")
|
||||
public Flux<?> sendMessage(@RequestParam(required = false)
|
||||
@Parameter(description = "按查询条件发送指令") String where,
|
||||
@RequestBody Flux<Map<String, Object>> messages) {
|
||||
|
||||
Lazy<Flux<DeviceOperator>> operators = Lazy.of(() -> {
|
||||
if (StringUtils.isEmpty(where)) {
|
||||
throw new ValidationException("where", "[where]参数不能为空");
|
||||
}
|
||||
QueryParamEntity entity = new QueryParamEntity();
|
||||
entity.setWhere(where);
|
||||
entity.includes("id");
|
||||
return service.query(entity)
|
||||
.flatMap(device -> registry.getDevice(device.getId()))
|
||||
.cache();
|
||||
});
|
||||
return messages
|
||||
.flatMap(message -> {
|
||||
DeviceMessage msg = MessageType
|
||||
.convertMessage(message)
|
||||
.filter(DeviceMessage.class::isInstance)
|
||||
.map(DeviceMessage.class::cast)
|
||||
.orElseThrow(() -> new UnsupportedOperationException("不支持的消息格式:" + message));
|
||||
|
||||
String deviceId = msg.getDeviceId();
|
||||
Flux<DeviceOperator> devices = StringUtils.isEmpty(deviceId)
|
||||
? operators.get()
|
||||
: registry.getDevice(deviceId).flux();
|
||||
|
||||
return devices
|
||||
.flatMap(device -> {
|
||||
Map<String, Object> copy = new HashMap<>(message);
|
||||
copy.put("deviceId", device.getDeviceId());
|
||||
copy.putIfAbsent("messageId", IDGenerator.SNOW_FLAKE_STRING.generate());
|
||||
//复制为新的消息,防止冲突
|
||||
DeviceMessage copiedMessage = MessageType
|
||||
.convertMessage(copy)
|
||||
.map(DeviceMessage.class::cast)
|
||||
.orElseThrow(() -> new UnsupportedOperationException("不支持的消息格式"));
|
||||
return device
|
||||
.messageSender()
|
||||
.send(copiedMessage)
|
||||
.onErrorResume(Exception.class, error -> {
|
||||
if (copiedMessage instanceof RepayableDeviceMessage) {
|
||||
return Mono.just(
|
||||
((RepayableDeviceMessage) copiedMessage).newReply().error(error)
|
||||
);
|
||||
}
|
||||
return Mono.error(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,20 @@ public class ProtocolSupportController
|
|||
.flatMap(support -> support.getConfigMetadata(transport));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/{transport}/metadata")
|
||||
@QueryAction
|
||||
@Authorize(merge = false)
|
||||
@Operation(summary = "获取协议设置的默认物模型")
|
||||
public Mono<String> getDefaultMetadata(@PathVariable @Parameter(description = "协议ID") String id,
|
||||
@PathVariable @Parameter(description = "传输协议") DefaultTransport transport) {
|
||||
return protocolSupports
|
||||
.getProtocol(id)
|
||||
.flatMap(support ->support
|
||||
.getDefaultMetadata(transport)
|
||||
.flatMap(metadata-> support.getMetadataCodec().encode(metadata))
|
||||
).defaultIfEmpty("{}");
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/transports")
|
||||
@Authorize(merge = false)
|
||||
@Operation(summary = "获取协议支持的传输协议")
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<artifactId>jetlinks-manager</artifactId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
</parent>
|
||||
<artifactId>logging-manager</artifactId>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<artifactId>jetlinks-manager</artifactId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>network-manager</artifactId>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<artifactId>jetlinks-manager</artifactId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>notify-manager</artifactId>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jetlinks-community</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
</parent>
|
||||
<packaging>pom</packaging>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<artifactId>jetlinks-manager</artifactId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>rule-engine-manager</artifactId>
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public class RuleInstanceEntity extends GenericEntity<String> implements RecordC
|
|||
@Schema(description = "创建者ID")
|
||||
private String creatorId;
|
||||
|
||||
@Column(name = "state")
|
||||
@Column(name = "state",length = 16)
|
||||
@EnumCodec
|
||||
@ColumnType(javaType = String.class)
|
||||
@DefaultValue("stopped")
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<artifactId>jetlinks-manager</artifactId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>visualization-manager</artifactId>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jetlinks-community</artifactId>
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
@ -49,41 +49,6 @@
|
|||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.spotify</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<version>1.2.0</version>
|
||||
<configuration>
|
||||
<imageName>${docker.image.name}</imageName>
|
||||
<imageTags>
|
||||
<imageTag>${project.version}</imageTag>
|
||||
</imageTags>
|
||||
<baseImage>openjdk:8</baseImage>
|
||||
<workdir>/</workdir>
|
||||
<env>
|
||||
<TZ>Asia/Shanghai</TZ>
|
||||
<APP_JAR>/${project.build.finalName}.jar</APP_JAR>
|
||||
</env>
|
||||
<runs>
|
||||
<run>chmod +x docker-entrypoint.sh</run>
|
||||
</runs>
|
||||
<entryPoint>["/docker-entrypoint.sh"]</entryPoint>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>/</targetPath>
|
||||
<directory>${project.basedir}</directory>
|
||||
<include>docker-entrypoint.sh</include>
|
||||
</resource>
|
||||
<resource>
|
||||
<targetPath>/</targetPath>
|
||||
<directory>${project.build.directory}</directory>
|
||||
<include>${project.build.finalName}.jar</include>
|
||||
</resource>
|
||||
</resources>
|
||||
<serverId>docker-repo</serverId>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
@ -115,7 +80,6 @@
|
|||
<dependency>
|
||||
<groupId>io.projectreactor.netty</groupId>
|
||||
<artifactId>reactor-netty</artifactId>
|
||||
<version>0.9.10.RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
|
|
|
|||
|
|
@ -96,24 +96,10 @@ public class AutoDownloadJarProtocolSupportLoader extends JarProtocolSupportLoad
|
|||
.retrieve()
|
||||
.bodyToFlux(DataBuffer.class)
|
||||
.as(dataStream -> {
|
||||
Path filePath = file.toPath();
|
||||
log.debug("write protocol file {} to {}", location, file.getAbsolutePath());
|
||||
try {
|
||||
@SuppressWarnings("all")
|
||||
AsynchronousFileChannel asynchronousFileChannel = AsynchronousFileChannel.open(filePath, CREATE,WRITE);
|
||||
return DataBufferUtils
|
||||
.write(dataStream, asynchronousFileChannel)
|
||||
.doOnNext(DataBufferUtils.releaseConsumer())
|
||||
.doAfterTerminate(() -> {
|
||||
try {
|
||||
asynchronousFileChannel.close();
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
})
|
||||
.then(Mono.just(file.getAbsolutePath()));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
log.debug("download protocol file {} to {}", location, file.getAbsolutePath());
|
||||
return DataBufferUtils
|
||||
.write(dataStream, file.toPath(), CREATE, WRITE)
|
||||
.thenReturn(file.getAbsolutePath());
|
||||
})
|
||||
.subscribeOn(Schedulers.elastic())
|
||||
.doOnNext(path -> config.put("location", path))
|
||||
|
|
|
|||
10
pom.xml
10
pom.xml
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<groupId>org.jetlinks.community</groupId>
|
||||
<artifactId>jetlinks-community</artifactId>
|
||||
<version>1.8.0-SNAPSHOT</version>
|
||||
<version>1.8.0</version>
|
||||
<modules>
|
||||
<module>jetlinks-components</module>
|
||||
<module>jetlinks-manager</module>
|
||||
|
|
@ -16,13 +16,13 @@
|
|||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.build.locales>zh_CN</project.build.locales>
|
||||
<spring.boot.version>2.3.4.RELEASE</spring.boot.version>
|
||||
<spring.boot.version>2.3.8.RELEASE</spring.boot.version>
|
||||
<java.version>1.8</java.version>
|
||||
<project.build.jdk>${java.version}</project.build.jdk>
|
||||
<hsweb.framework.version>4.0.9-SNAPSHOT</hsweb.framework.version>
|
||||
<easyorm.version>4.0.9-SNAPSHOT</easyorm.version>
|
||||
<hsweb.framework.version>4.0.9</hsweb.framework.version>
|
||||
<easyorm.version>4.0.9</easyorm.version>
|
||||
<hsweb.expands.version>3.0.2</hsweb.expands.version>
|
||||
<jetlinks.version>1.1.5-SNAPSHOT</jetlinks.version>
|
||||
<jetlinks.version>1.1.5</jetlinks.version>
|
||||
<r2dbc.version>Arabba-SR7</r2dbc.version>
|
||||
<vertx.version>3.8.5</vertx.version>
|
||||
<netty.version>4.1.51.Final</netty.version>
|
||||
|
|
|
|||
Loading…
Reference in New Issue