增加tdengine支持
parent
4866c27ed9
commit
19d454697e
|
@ -1,6 +1,6 @@
|
|||
FROM openjdk:11-jre-slim
|
||||
WORKDIR /app
|
||||
ADD iot-standalone/target/iot-standalone-0.4.0-SNAPSHOT.tar /app
|
||||
ADD iot-standalone/target/iot-standalone-0.4.1-SNAPSHOT.tar /app
|
||||
ADD data/init /app/data/init
|
||||
ADD data/components /app/data/components
|
||||
ADD data/converters /app/data/converters
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iotkit-parent</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iotkit-parent</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-components</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-components</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-components</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ public class DeviceBehaviourService {
|
|||
ThingModelMessage modelMessage = new ThingModelMessage(
|
||||
UUID.randomUUID().toString(),
|
||||
UniqueIdUtil.newRequestId(), "",
|
||||
pk, dn,
|
||||
pk, dn, uid,
|
||||
ThingModelMessage.TYPE_LIFETIME, "register",
|
||||
0, new HashMap<>(), System.currentTimeMillis(),
|
||||
System.currentTimeMillis()
|
||||
|
@ -193,7 +193,7 @@ public class DeviceBehaviourService {
|
|||
//否则为父设备,同步透传子设备状态
|
||||
List<String> subDeviceIds = deviceInfoData.findSubDeviceIds(device.getDeviceId());
|
||||
for (String subDeviceId : subDeviceIds) {
|
||||
DeviceInfo subDevice=deviceInfoData.findByDeviceId(subDeviceId);
|
||||
DeviceInfo subDevice = deviceInfoData.findByDeviceId(subDeviceId);
|
||||
Product product = productData.findById(subDevice.getProductKey());
|
||||
Boolean transparent = product.getTransparent();
|
||||
//透传设备父设备上线,子设备也上线。非透传设备父设备离线,子设备才离线
|
||||
|
@ -217,7 +217,7 @@ public class DeviceBehaviourService {
|
|||
ThingModelMessage modelMessage = new ThingModelMessage(
|
||||
UUID.randomUUID().toString(),
|
||||
UniqueIdUtil.newRequestId(), "",
|
||||
device.getProductKey(), device.getDeviceName(),
|
||||
device.getProductKey(), device.getDeviceName(), device.getUid(),
|
||||
ThingModelMessage.TYPE_STATE,
|
||||
online ? DeviceState.STATE_ONLINE : DeviceState.STATE_OFFLINE,
|
||||
0,
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
package cc.iotkit.comps.service;
|
||||
|
||||
import cc.iotkit.common.Constants;
|
||||
import cc.iotkit.data.IDeviceInfoData;
|
||||
import cc.iotkit.model.device.DeviceInfo;
|
||||
import cc.iotkit.model.device.message.ThingModelMessage;
|
||||
import cc.iotkit.mq.ConsumerHandler;
|
||||
import cc.iotkit.mq.MqConsumer;
|
||||
|
@ -17,6 +19,7 @@ import cc.iotkit.mq.MqProducer;
|
|||
import cc.iotkit.temporal.IThingModelMessageData;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
@ -29,6 +32,9 @@ public class DeviceMessageConsumer implements ConsumerHandler<ThingModelMessage>
|
|||
@Autowired
|
||||
private IThingModelMessageData thingModelMessageData;
|
||||
@Autowired
|
||||
@Qualifier("deviceInfoDataCache")
|
||||
private IDeviceInfoData deviceInfoData;
|
||||
@Autowired
|
||||
private MqConsumer<ThingModelMessage> thingModelMessageConsumer;
|
||||
@Autowired
|
||||
private MqProducer<ThingModelMessage> thingModelMessageMqProducer;
|
||||
|
@ -52,6 +58,12 @@ public class DeviceMessageConsumer implements ConsumerHandler<ThingModelMessage>
|
|||
thingModelMessageMqProducer.publish(Constants.DEVICE_CONFIG_TOPIC, msg);
|
||||
}
|
||||
|
||||
DeviceInfo device = deviceInfoData.findByDeviceId(msg.getDeviceId());
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
msg.setUid(device.getUid());
|
||||
|
||||
//设备消息入库
|
||||
thingModelMessageData.add(msg);
|
||||
} catch (Throwable e) {
|
||||
|
|
|
@ -12,7 +12,6 @@ package cc.iotkit.comps.service;
|
|||
import cc.iotkit.common.Constants;
|
||||
import cc.iotkit.common.utils.JsonUtil;
|
||||
import cc.iotkit.data.IDeviceInfoData;
|
||||
import cc.iotkit.model.device.message.DeviceProperty;
|
||||
import cc.iotkit.model.device.message.ThingModelMessage;
|
||||
import cc.iotkit.mq.ConsumerHandler;
|
||||
import cc.iotkit.mq.MqConsumer;
|
||||
|
@ -23,8 +22,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
|||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -59,22 +56,9 @@ public class DevicePropertyConsumer implements ConsumerHandler<ThingModelMessage
|
|||
//更新设备当前属性
|
||||
updateDeviceCurrentProperties(deviceId, properties);
|
||||
|
||||
//设备属性历史数据存储
|
||||
List<DeviceProperty> batch = new ArrayList<>();
|
||||
for (String key : properties.keySet()) {
|
||||
batch.add(new DeviceProperty(
|
||||
//防止重复id被覆盖
|
||||
msg.getMid() + "_" + key,
|
||||
deviceId,
|
||||
key,
|
||||
properties.get(key),
|
||||
msg.getOccurred()
|
||||
));
|
||||
}
|
||||
|
||||
//批量保存
|
||||
//保存属性记录
|
||||
try {
|
||||
devicePropertyData.addProperties(batch);
|
||||
devicePropertyData.addProperties(deviceId, properties, msg.getOccurred());
|
||||
} catch (Throwable e) {
|
||||
log.warn("save property data error", e);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-components</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-components</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>iot-emqx-component</artifactId>
|
||||
|
@ -84,25 +84,25 @@
|
|||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-model</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-common</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-component-base</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-data-service</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-components</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-components</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>iot-http-biz-component</artifactId>
|
||||
|
@ -58,7 +58,7 @@
|
|||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-component-base</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-components</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-components</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>iot-mqtt-component</artifactId>
|
||||
|
@ -82,19 +82,19 @@
|
|||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-common</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-component-base</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-data-service</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-components</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iotkit-parent</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-data</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-data</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-data</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package cc.iotkit.temporal.es.service;
|
||||
|
||||
import cc.iotkit.model.product.ThingModel;
|
||||
import cc.iotkit.temporal.IDbStructureData;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class DbStructureDataImpl implements IDbStructureData {
|
||||
@Override
|
||||
public void defineThingModel(ThingModel thingModel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undefineThingModel(ThingModel thingModel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initDbStructure() {
|
||||
|
||||
}
|
||||
}
|
|
@ -23,7 +23,10 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
|
|||
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
@ -50,9 +53,13 @@ public class DevicePropertyDataImpl implements IDevicePropertyData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addProperties(List<DeviceProperty> properties) {
|
||||
template.save(properties.stream().map(DevicePropertyMapper.M::toVo)
|
||||
.collect(Collectors.toList()));
|
||||
public void addProperties(String deviceId, Map<String, Object> properties, long time) {
|
||||
List<DocDeviceProperty> deviceProperties = new ArrayList<>();
|
||||
properties.forEach((key, val) -> deviceProperties.add(
|
||||
new DocDeviceProperty(UUID.randomUUID().toString(), deviceId, key, val, time)
|
||||
));
|
||||
|
||||
template.save(deviceProperties);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ public class ThingModelMessageDataImpl implements IThingModelMessageData {
|
|||
queryBuilder.must(QueryBuilders.termQuery("uid", uid));
|
||||
}
|
||||
|
||||
//按小时统计消息数量
|
||||
NativeSearchQuery query = new NativeSearchQueryBuilder()
|
||||
.withQuery(queryBuilder)
|
||||
.withAggregations(AggregationBuilders.dateHistogram("agg")
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
<parent>
|
||||
<artifactId>iot-data</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>iot-model</artifactId>
|
||||
|
|
|
@ -48,6 +48,11 @@ public class ThingModelMessage {
|
|||
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 所属用户ID
|
||||
*/
|
||||
private String uid;
|
||||
|
||||
/**
|
||||
* 消息类型
|
||||
* lifetime:生命周期
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
<parent>
|
||||
<artifactId>iot-data</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>iot-rdb-data-service</artifactId>
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package cc.iotkit.data.config;
|
||||
|
||||
|
||||
import org.springframework.boot.autoconfigure.jdbc.JdbcProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@Configuration(
|
||||
proxyBeanMethods = false
|
||||
)
|
||||
class JdbcTemplateConfig {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
JdbcTemplate jdbcTemplate(DataSource dataSource, JdbcProperties properties) {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
JdbcProperties.Template template = properties.getTemplate();
|
||||
jdbcTemplate.setFetchSize(template.getFetchSize());
|
||||
jdbcTemplate.setMaxRows(template.getMaxRows());
|
||||
if (template.getQueryTimeout() != null) {
|
||||
jdbcTemplate.setQueryTimeout((int) template.getQueryTimeout().getSeconds());
|
||||
}
|
||||
|
||||
return jdbcTemplate;
|
||||
}
|
||||
}
|
|
@ -23,7 +23,6 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.ToIntFunction;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Primary
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>iot-data</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>iot-td-temporal-service</artifactId>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.40</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-http</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-temporal-service</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-data-cache</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,5 @@
|
|||
### 时序数据库服务接口的TDengine实现
|
||||
|
||||
版本:v0.4.1
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package cc.iotkit.temporal.td.config;
|
||||
|
||||
public interface Constants {
|
||||
|
||||
/**
|
||||
* 根据产品key获取产品属性超级表名
|
||||
*/
|
||||
static String getProductPropertySTableName(String productKey) {
|
||||
return String.format("product_property_%s", productKey.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据deviceId获取设备属性表名
|
||||
*/
|
||||
static String getDevicePropertyTableName(String deviceId) {
|
||||
return String.format("device_property_%s", deviceId.toLowerCase());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package cc.iotkit.temporal.td.config;
|
||||
|
||||
import cc.iotkit.temporal.td.dao.TdTemplate;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class TdDatasourceConfig {
|
||||
|
||||
@Value("${spring.td-datasource.url}")
|
||||
private String url;
|
||||
|
||||
@Value("${spring.td-datasource.driverClassName}")
|
||||
private String driverClassName;
|
||||
|
||||
@Value("${spring.td-datasource.username}")
|
||||
private String username;
|
||||
|
||||
@Value("${spring.td-datasource.password}")
|
||||
private String password;
|
||||
|
||||
@Bean("tdJdbcTemplate")
|
||||
public TdTemplate tdJdbcTemplate() {
|
||||
HikariDataSource dataSource = new HikariDataSource();
|
||||
dataSource.setJdbcUrl(url);
|
||||
dataSource.setUsername(username);
|
||||
dataSource.setPassword(password);
|
||||
dataSource.setDriverClassName(driverClassName);
|
||||
return new TdTemplate(dataSource);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package cc.iotkit.temporal.td.dao;
|
||||
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
public class TdTemplate extends JdbcTemplate {
|
||||
|
||||
public TdTemplate() {
|
||||
}
|
||||
|
||||
public TdTemplate(DataSource dataSource) {
|
||||
super(dataSource);
|
||||
}
|
||||
|
||||
public TdTemplate(DataSource dataSource, boolean lazyInit) {
|
||||
super(dataSource, lazyInit);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package cc.iotkit.temporal.td.dm;
|
||||
|
||||
import cc.iotkit.model.product.ThingModel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class FieldParser {
|
||||
|
||||
/**
|
||||
* 物模型到td数据类型映射
|
||||
*/
|
||||
private static final Map<String, String> TYPE_MAPPING = Map.of(
|
||||
"int32", "INT",
|
||||
"float", "FLOAT",
|
||||
"bool", "TINYINT",
|
||||
"enum", "TINYINT",
|
||||
"text", "NCHAR",
|
||||
"date", "NCHAR"
|
||||
);
|
||||
|
||||
/**
|
||||
* 将物模型字段转换为td字段
|
||||
*/
|
||||
public static TdField parse(ThingModel.Property property) {
|
||||
String filedName = property.getIdentifier().toLowerCase();
|
||||
ThingModel.DataType dataType = property.getDataType();
|
||||
String type = dataType.getType();
|
||||
|
||||
//将物模型字段类型映射为td字段类型
|
||||
String fType = TYPE_MAPPING.get(type);
|
||||
Object specs = dataType.getSpecs();
|
||||
int len = -1;
|
||||
if (specs instanceof Map) {
|
||||
Object objLen = ((Map<?, ?>) specs).get("length");
|
||||
if (objLen != null) {
|
||||
len = Integer.parseInt(objLen.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return new TdField(filedName, fType, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物模型中的字段列表
|
||||
*/
|
||||
public static List<TdField> parse(ThingModel thingModel) {
|
||||
return thingModel.getModel().getProperties().stream().map(FieldParser::parse).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 将从库中查出来的字段信息转换为td字段对象
|
||||
*/
|
||||
public static List<TdField> parse(List rows) {
|
||||
return (List<TdField>) rows.stream().map((r) -> {
|
||||
List row = (List) r;
|
||||
String type = row.get(1).toString().toUpperCase();
|
||||
return new TdField(
|
||||
row.get(0).toString(),
|
||||
type,
|
||||
type.equals("NCHAR") ? Integer.parseInt(row.get(2).toString()) : -1);
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字段字义
|
||||
*/
|
||||
public static String getFieldDefine(TdField field) {
|
||||
return field.getName() + " " + (field.getLength() > 0 ?
|
||||
String.format("%s(%d)", field.getType(), field.getLength())
|
||||
: field.getType());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
package cc.iotkit.temporal.td.dm;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TableManager {
|
||||
|
||||
/**
|
||||
* 创建超级表模板(含存在判断)
|
||||
*/
|
||||
private static final String CREATE_STABLE_INE_TPL = "CREATE STABLE IF NOT EXISTS %s (%s) TAGS (%s);";
|
||||
|
||||
/**
|
||||
* 删除超级表
|
||||
*/
|
||||
private static final String DROP_STABLE_TPL = "DROP STABLE IF EXISTS %s;";
|
||||
|
||||
/**
|
||||
* 获取表的结构信息
|
||||
*/
|
||||
private static final String DESC_TB_TPL = "DESCRIBE %s;";
|
||||
|
||||
/**
|
||||
* 超级表增加列
|
||||
*/
|
||||
private static final String ALTER_STABLE_ADD_COL_TPL = "ALTER STABLE %s ADD COLUMN %s;";
|
||||
|
||||
/**
|
||||
* 超级表修改列
|
||||
*/
|
||||
private static final String ALTER_STABLE_MODIFY_COL_TPL = "ALTER STABLE %s MODIFY COLUMN %s;";
|
||||
|
||||
/**
|
||||
* 超级表删除列
|
||||
*/
|
||||
private static final String ALTER_STABLE_DROP_COL_TPL = "ALTER STABLE %s DROP COLUMN %s;";
|
||||
|
||||
/**
|
||||
* 获取创建表sql
|
||||
*/
|
||||
public static String getCreateSTableSql(String tbName, List<TdField> fields, TdField... tags) {
|
||||
if (fields.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//生成字段片段
|
||||
StringBuilder sbField = new StringBuilder("time timestamp,");
|
||||
|
||||
for (TdField field : fields) {
|
||||
sbField.append(FieldParser.getFieldDefine(field));
|
||||
sbField.append(",");
|
||||
}
|
||||
sbField.deleteCharAt(sbField.length() - 1);
|
||||
|
||||
String fieldFrag = sbField.toString();
|
||||
|
||||
//生成tag
|
||||
StringBuilder sbTag = new StringBuilder();
|
||||
for (TdField tag : tags) {
|
||||
sbTag.append(FieldParser.getFieldDefine(tag))
|
||||
.append(",");
|
||||
}
|
||||
sbTag.deleteCharAt(sbTag.length() - 1);
|
||||
|
||||
return String.format(CREATE_STABLE_INE_TPL, tbName, fieldFrag, sbTag.toString());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 取正确的表名
|
||||
*
|
||||
* @param name 表象
|
||||
*/
|
||||
public static String rightTbName(String name) {
|
||||
return name.toLowerCase().replace("-", "_");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表详情的sql
|
||||
*/
|
||||
public static String getDescTableSql(String tbName) {
|
||||
return String.format(DESC_TB_TPL, tbName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取添加字段sql
|
||||
*/
|
||||
public static String getAddSTableColumnSql(String tbName, List<TdField> fields) {
|
||||
StringBuilder sbAdd = new StringBuilder();
|
||||
for (TdField field : fields) {
|
||||
sbAdd.append(String.format(ALTER_STABLE_ADD_COL_TPL,
|
||||
tbName,
|
||||
FieldParser.getFieldDefine(field)
|
||||
));
|
||||
}
|
||||
return sbAdd.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取修改字段sql
|
||||
*/
|
||||
public static String getModifySTableColumnSql(String tbName, List<TdField> fields) {
|
||||
StringBuilder sbModify = new StringBuilder();
|
||||
for (TdField field : fields) {
|
||||
sbModify.append(String.format(ALTER_STABLE_MODIFY_COL_TPL,
|
||||
tbName,
|
||||
FieldParser.getFieldDefine(field)
|
||||
));
|
||||
}
|
||||
return sbModify.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取删除字段sql
|
||||
*/
|
||||
public static String getDropSTableColumnSql(String tbName, List<TdField> fields) {
|
||||
StringBuilder sbDrop = new StringBuilder();
|
||||
for (TdField field : fields) {
|
||||
sbDrop.append(String.format(ALTER_STABLE_DROP_COL_TPL,
|
||||
tbName,
|
||||
field.getName()
|
||||
));
|
||||
}
|
||||
return sbDrop.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package cc.iotkit.temporal.td.dm;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TdField {
|
||||
private String name;
|
||||
private String type;
|
||||
private int length;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package cc.iotkit.temporal.td.dm;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TdResponse {
|
||||
|
||||
public static final int CODE_SUCCESS = 0;
|
||||
public static final int CODE_TB_NOT_EXIST = 866;
|
||||
|
||||
private String status;
|
||||
|
||||
private int code;
|
||||
|
||||
private String desc;
|
||||
|
||||
//[["time","TIMESTAMP",8,""],["powerstate","TINYINT",1,""],["brightness","INT",4,""],["deviceid","NCHAR",32,"TAG"]]
|
||||
private List data;
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package cc.iotkit.temporal.td.dm;
|
||||
|
||||
import cc.iotkit.common.utils.JsonUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class TdRestApi {
|
||||
|
||||
@Value("${spring.td-datasource.url}")
|
||||
private String url;
|
||||
|
||||
@Value("${spring.td-datasource.username}")
|
||||
private String username;
|
||||
|
||||
@Value("${spring.td-datasource.password}")
|
||||
private String password;
|
||||
|
||||
private String getRestApiUrl() {
|
||||
//jdbc:TAOS-RS://127.0.0.1:6041/iotkit?xxxx
|
||||
String restUrl = url.replace("jdbc:TAOS-RS://", "")
|
||||
.replaceAll("\\?.*", "");
|
||||
// /rest/sql/iotkit
|
||||
int idx = restUrl.lastIndexOf("/");
|
||||
//127.0.0.1:6041/rest/sql/iotkit
|
||||
return String.format("%s/rest/sql/%s", restUrl.substring(0, idx), restUrl.substring(idx + 1));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 新建td api请求对象
|
||||
*/
|
||||
public HttpRequest newApiRequest(String sql) {
|
||||
return HttpRequest
|
||||
.post(getRestApiUrl())
|
||||
.body(sql)
|
||||
.basicAuth(username, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行sql
|
||||
*/
|
||||
public TdResponse execSql(String sql) {
|
||||
log.info("exec td sql:{}", sql);
|
||||
HttpRequest request = newApiRequest(sql);
|
||||
HttpResponse response = request.execute();
|
||||
return JsonUtil.parse(response.body(), TdResponse.class);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cc.iotkit.temporal.td.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TbDeviceProperty {
|
||||
|
||||
private Long time;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String name;
|
||||
|
||||
private Object value;
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package cc.iotkit.temporal.td.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TbRuleLog {
|
||||
|
||||
private Long time;
|
||||
|
||||
private String ruleId;
|
||||
|
||||
private String state1;
|
||||
|
||||
private String content;
|
||||
|
||||
private Boolean success;
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package cc.iotkit.temporal.td.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TbTaskLog {
|
||||
|
||||
private Long time;
|
||||
|
||||
private String taskId;
|
||||
|
||||
private String content;
|
||||
|
||||
private Boolean success;
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package cc.iotkit.temporal.td.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TbThingModelMessage {
|
||||
|
||||
private Long time;
|
||||
|
||||
private String mid;
|
||||
|
||||
private String deviceId;
|
||||
|
||||
private String productKey;
|
||||
|
||||
private String deviceName;
|
||||
|
||||
private String uid;
|
||||
|
||||
private String type;
|
||||
|
||||
private String identifier;
|
||||
|
||||
private int code;
|
||||
|
||||
private String data;
|
||||
|
||||
private Long reportTime;
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package cc.iotkit.temporal.td.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TbVirtualDeviceLog {
|
||||
|
||||
private Long time;
|
||||
|
||||
private String virtualDeviceId;
|
||||
|
||||
private String virtualDeviceName;
|
||||
|
||||
private int deviceTotal;
|
||||
|
||||
private String result;
|
||||
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
package cc.iotkit.temporal.td.service;
|
||||
|
||||
import cc.iotkit.common.utils.JsonUtil;
|
||||
import cc.iotkit.model.product.ThingModel;
|
||||
import cc.iotkit.temporal.IDbStructureData;
|
||||
import cc.iotkit.temporal.td.config.Constants;
|
||||
import cc.iotkit.temporal.td.dm.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class DbStructureDataImpl implements IDbStructureData {
|
||||
|
||||
@Autowired
|
||||
private TdRestApi tdRestApi;
|
||||
|
||||
/**
|
||||
* 根据物模型创建超级表
|
||||
*/
|
||||
@Override
|
||||
public void defineThingModel(ThingModel thingModel) {
|
||||
//获取物模型中的属性定义
|
||||
List<TdField> fields = FieldParser.parse(thingModel);
|
||||
String tbName = Constants.getProductPropertySTableName(thingModel.getProductKey());
|
||||
//生成sql
|
||||
String sql = TableManager.getCreateSTableSql(tbName,
|
||||
fields,
|
||||
new TdField("device_id", "NCHAR", 50));
|
||||
if (sql == null) {
|
||||
return;
|
||||
}
|
||||
log.info("executing sql:{}", sql);
|
||||
|
||||
//执行sql
|
||||
TdResponse response = tdRestApi.execSql(sql);
|
||||
if (TdResponse.CODE_SUCCESS != response.getCode()) {
|
||||
throw new RuntimeException(String.format(
|
||||
"create td stable failed,code:%s,desc:%s"
|
||||
, response.getCode(), response.getDesc()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据物模型更新超级表结构
|
||||
*/
|
||||
@Override
|
||||
public void undefineThingModel(ThingModel thingModel) {
|
||||
//获取旧字段信息
|
||||
String tbName = Constants.getProductPropertySTableName(thingModel.getProductKey());
|
||||
String sql = TableManager.getDescTableSql(tbName);
|
||||
TdResponse response = tdRestApi.execSql(sql);
|
||||
if (response.getCode() != TdResponse.CODE_SUCCESS) {
|
||||
throw new RuntimeException("get des table error:" + JsonUtil.toJsonString(response));
|
||||
}
|
||||
|
||||
List<TdField> oldFields = FieldParser.parse(response.getData());
|
||||
List<TdField> newFields = FieldParser.parse(thingModel);
|
||||
//对比差异
|
||||
|
||||
//找出新增的字段
|
||||
List<TdField> addFields = newFields.stream().filter((f) -> oldFields.stream()
|
||||
.noneMatch(old -> old.getName().equals(f.getName())))
|
||||
.collect(Collectors.toList());
|
||||
if (addFields.size() > 0) {
|
||||
sql = TableManager.getAddSTableColumnSql(tbName, addFields);
|
||||
response = tdRestApi.execSql(sql);
|
||||
if (response.getCode() != TdResponse.CODE_SUCCESS) {
|
||||
throw new RuntimeException("add table column error:" + JsonUtil.toJsonString(response));
|
||||
}
|
||||
}
|
||||
|
||||
//找出修改的字段
|
||||
List<TdField> modifyFields = newFields.stream().filter((f) -> oldFields.stream()
|
||||
.anyMatch(old ->
|
||||
old.getName().equals(f.getName()) //字段名相同
|
||||
//字段类型或长度不同
|
||||
&& (old.getType().equals(f.getType()) || old.getLength() != f.getLength())
|
||||
))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (modifyFields.size() > 0) {
|
||||
sql = TableManager.getModifySTableColumnSql(tbName, modifyFields);
|
||||
response = tdRestApi.execSql(sql);
|
||||
if (response.getCode() != TdResponse.CODE_SUCCESS) {
|
||||
throw new RuntimeException("modify table column error:" + JsonUtil.toJsonString(response));
|
||||
}
|
||||
}
|
||||
|
||||
//找出删除的字段
|
||||
List<TdField> dropFields = oldFields.stream().filter((f) -> newFields.stream()
|
||||
.noneMatch(old -> old.getName().equals(f.getName())))
|
||||
.collect(Collectors.toList());
|
||||
if (dropFields.size() > 0) {
|
||||
sql = TableManager.getDropSTableColumnSql(tbName, dropFields);
|
||||
response = tdRestApi.execSql(sql);
|
||||
if (response.getCode() != TdResponse.CODE_SUCCESS) {
|
||||
throw new RuntimeException("drop table column error:" + JsonUtil.toJsonString(response));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化其它数据结构
|
||||
*/
|
||||
@Override
|
||||
@PostConstruct
|
||||
public void initDbStructure() {
|
||||
//创建规则日志超级表
|
||||
String sql = TableManager.getCreateSTableSql("rule_log", List.of(
|
||||
new TdField("state1", "NCHAR", 32),
|
||||
new TdField("content", "NCHAR", 255),
|
||||
new TdField("success", "BOOL", -1)
|
||||
), new TdField("rule_id", "NCHAR", 50));
|
||||
TdResponse response = tdRestApi.execSql(sql);
|
||||
if (response.getCode() != TdResponse.CODE_SUCCESS) {
|
||||
throw new RuntimeException("create stable rule_log error:" + JsonUtil.toJsonString(response));
|
||||
}
|
||||
|
||||
//创建规则日志超级表
|
||||
sql = TableManager.getCreateSTableSql("task_log", List.of(
|
||||
new TdField("content", "NCHAR", 255),
|
||||
new TdField("success", "BOOL", -1)
|
||||
), new TdField("task_id", "NCHAR", 50));
|
||||
response = tdRestApi.execSql(sql);
|
||||
if (response.getCode() != TdResponse.CODE_SUCCESS) {
|
||||
throw new RuntimeException("create stable task_log error:" + JsonUtil.toJsonString(response));
|
||||
}
|
||||
|
||||
//创建物模型消息超级表
|
||||
sql = TableManager.getCreateSTableSql("thing_model_message", List.of(
|
||||
new TdField("mid", "NCHAR", 50),
|
||||
new TdField("product_key", "NCHAR", 50),
|
||||
new TdField("device_name", "NCHAR", 50),
|
||||
new TdField("uid", "NCHAR", 50),
|
||||
new TdField("type", "NCHAR", 20),
|
||||
new TdField("identifier", "NCHAR", 50),
|
||||
new TdField("code", "INT", -1),
|
||||
new TdField("data", "NCHAR", 255),
|
||||
new TdField("report_time", "BIGINT", -1)
|
||||
), new TdField("device_id", "NCHAR", 50));
|
||||
response = tdRestApi.execSql(sql);
|
||||
if (response.getCode() != TdResponse.CODE_SUCCESS) {
|
||||
throw new RuntimeException("create stable thing_model_message error:" + JsonUtil.toJsonString(response));
|
||||
}
|
||||
|
||||
//创建虚拟设备日志超级表
|
||||
sql = TableManager.getCreateSTableSql("virtual_device_log", List.of(
|
||||
new TdField("virtual_device_name", "NCHAR", 50),
|
||||
new TdField("device_total", "INT", -1),
|
||||
new TdField("result", "NCHAR", 255)
|
||||
), new TdField("virtual_device_id", "NCHAR", 50));
|
||||
response = tdRestApi.execSql(sql);
|
||||
if (response.getCode() != TdResponse.CODE_SUCCESS) {
|
||||
throw new RuntimeException("create stable virtual_device_log error:" + JsonUtil.toJsonString(response));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 奇特物联 2021-2022 All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed 未经许可不能去掉「奇特物联」相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: xw2sy@163.com
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
package cc.iotkit.temporal.td.service;
|
||||
|
||||
import cc.iotkit.data.IDeviceInfoData;
|
||||
import cc.iotkit.model.device.DeviceInfo;
|
||||
import cc.iotkit.model.device.message.DeviceProperty;
|
||||
import cc.iotkit.temporal.IDevicePropertyData;
|
||||
import cc.iotkit.temporal.td.config.Constants;
|
||||
import cc.iotkit.temporal.td.dao.TdTemplate;
|
||||
import cc.iotkit.temporal.td.model.TbDeviceProperty;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class DevicePropertyDataImpl implements IDevicePropertyData {
|
||||
|
||||
@Autowired
|
||||
private TdTemplate tdTemplate;
|
||||
@Autowired
|
||||
@Qualifier("deviceInfoDataCache")
|
||||
private IDeviceInfoData deviceInfoData;
|
||||
|
||||
public List<DeviceProperty> findDevicePropertyHistory(String deviceId, String name, long start, long end) {
|
||||
DeviceInfo device = deviceInfoData.findByDeviceId(deviceId);
|
||||
if (device == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
String tbName = Constants.getProductPropertySTableName(device.getProductKey());
|
||||
List<TbDeviceProperty> deviceProperties = tdTemplate.query(String.format(
|
||||
"select time,%s as value,device_id from %s where device_id=? and time>=? and time<=?",
|
||||
name.toLowerCase(), tbName),
|
||||
new BeanPropertyRowMapper<>(TbDeviceProperty.class),
|
||||
deviceId, start, end
|
||||
);
|
||||
return deviceProperties.stream().map(p -> new DeviceProperty(
|
||||
p.getTime().toString(),
|
||||
p.getDeviceId(),
|
||||
name,
|
||||
p.getValue(),
|
||||
p.getTime()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProperties(String deviceId, Map<String, Object> properties, long time) {
|
||||
DeviceInfo device = deviceInfoData.findByDeviceId(deviceId);
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
//获取设备旧属性
|
||||
Map<String, Object> oldProperties = deviceInfoData.getProperties(deviceId);
|
||||
//用新属性覆盖
|
||||
oldProperties.putAll(properties);
|
||||
|
||||
StringBuilder sbFieldNames = new StringBuilder();
|
||||
StringBuilder sbFieldPlaces = new StringBuilder();
|
||||
List<Object> args = new ArrayList<>();
|
||||
args.add(time);
|
||||
|
||||
//组织sql
|
||||
oldProperties.forEach((key, val) -> {
|
||||
sbFieldNames.append(key)
|
||||
.append(",");
|
||||
sbFieldPlaces.append("?,");
|
||||
args.add(val);
|
||||
});
|
||||
sbFieldNames.deleteCharAt(sbFieldNames.length() - 1);
|
||||
sbFieldPlaces.deleteCharAt(sbFieldPlaces.length() - 1);
|
||||
|
||||
String sql = String.format("INSERT INTO %s (time,%s) USING %s TAGS ('%s') VALUES (?,%s);",
|
||||
Constants.getDevicePropertyTableName(deviceId),
|
||||
sbFieldNames.toString(),
|
||||
Constants.getProductPropertySTableName(device.getProductKey()),
|
||||
deviceId,
|
||||
sbFieldPlaces.toString());
|
||||
|
||||
tdTemplate.update(sql, args.toArray());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 奇特物联 2021-2022 All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed 未经许可不能去掉「奇特物联」相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: xw2sy@163.com
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
package cc.iotkit.temporal.td.service;
|
||||
|
||||
import cc.iotkit.model.Paging;
|
||||
import cc.iotkit.model.rule.RuleLog;
|
||||
import cc.iotkit.temporal.IRuleLogData;
|
||||
import cc.iotkit.temporal.td.dao.TdTemplate;
|
||||
import cc.iotkit.temporal.td.dm.TableManager;
|
||||
import cc.iotkit.temporal.td.model.TbRuleLog;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class RuleLogDataImpl implements IRuleLogData {
|
||||
|
||||
@Autowired
|
||||
private TdTemplate tdTemplate;
|
||||
|
||||
@Override
|
||||
public void deleteByRuleId(String ruleId) {
|
||||
tdTemplate.update("delete from rule_log where rule_id=?", ruleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Paging<RuleLog> findByRuleId(String ruleId, int page, int size) {
|
||||
String sql = "select time,state1,content,success,rule_id from rule_log where rule_id=? " +
|
||||
"order by time desc limit %d offset %d";
|
||||
sql = String.format(sql, size, (page - 1) * size);
|
||||
List<TbRuleLog> ruleLogs = tdTemplate.query(sql, new BeanPropertyRowMapper<>(TbRuleLog.class), ruleId);
|
||||
|
||||
sql = "select count(*) from rule_log where rule_id=?";
|
||||
List<Long> counts = tdTemplate.queryForList(sql, Long.class, ruleId);
|
||||
|
||||
return new Paging<>(counts.size() > 0 ? counts.get(0) : 0, ruleLogs.stream().map(r ->
|
||||
new RuleLog(r.getTime().toString(), ruleId, r.getState1(),
|
||||
r.getContent(), r.getSuccess(), r.getTime()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(RuleLog log) {
|
||||
//使用ruleId作表名
|
||||
String sql = String.format("INSERT INTO %s (%s) USING %s TAGS ('%s') VALUES (%s);",
|
||||
"rule_log_" + TableManager.rightTbName(log.getRuleId()),
|
||||
"time,state1,content,success",
|
||||
"rule_log",
|
||||
log.getRuleId(),
|
||||
"?,?,?,?"
|
||||
);
|
||||
tdTemplate.update(sql, System.currentTimeMillis(), log.getState(), log.getContent(), log.getSuccess());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 奇特物联 2021-2022 All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed 未经许可不能去掉「奇特物联」相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: xw2sy@163.com
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
package cc.iotkit.temporal.td.service;
|
||||
|
||||
import cc.iotkit.model.Paging;
|
||||
import cc.iotkit.model.rule.TaskLog;
|
||||
import cc.iotkit.temporal.ITaskLogData;
|
||||
import cc.iotkit.temporal.td.dao.TdTemplate;
|
||||
import cc.iotkit.temporal.td.dm.TableManager;
|
||||
import cc.iotkit.temporal.td.model.TbTaskLog;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class TaskLogDataImpl implements ITaskLogData {
|
||||
|
||||
@Autowired
|
||||
private TdTemplate tdTemplate;
|
||||
|
||||
@Override
|
||||
public void deleteByTaskId(String taskId) {
|
||||
tdTemplate.update("delete from task_log where task_id=?", taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Paging<TaskLog> findByTaskId(String taskId, int page, int size) {
|
||||
String sql = "select time,content,success,task_id from task_log where task_id=? order by time desc limit %d offset %d";
|
||||
sql = String.format(sql, size, (page - 1) * size);
|
||||
List<TbTaskLog> taskLogs = tdTemplate.query(sql, new BeanPropertyRowMapper<>(TbTaskLog.class), taskId);
|
||||
|
||||
sql = "select count(*) from task_log where task_id=?";
|
||||
List<Long> counts = tdTemplate.queryForList(sql, Long.class, taskId);
|
||||
|
||||
return new Paging<>(counts.size() > 0 ? counts.get(0) : 0, taskLogs.stream().map(r ->
|
||||
new TaskLog(r.getTime().toString(), taskId,
|
||||
r.getContent(), r.getSuccess(), r.getTime()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(TaskLog log) {
|
||||
//使用taskId作表名
|
||||
String sql = String.format("INSERT INTO %s (%s) USING %s TAGS ('%s') VALUES (%s);",
|
||||
"task_log_" + TableManager.rightTbName(log.getTaskId()),
|
||||
"time,content,success",
|
||||
"task_log",
|
||||
log.getTaskId(),
|
||||
"?,?,?"
|
||||
);
|
||||
tdTemplate.update(sql, System.currentTimeMillis(), log.getContent(), log.getSuccess());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 奇特物联 2021-2022 All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed 未经许可不能去掉「奇特物联」相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: xw2sy@163.com
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
package cc.iotkit.temporal.td.service;
|
||||
|
||||
import cc.iotkit.common.utils.JsonUtil;
|
||||
import cc.iotkit.model.Paging;
|
||||
import cc.iotkit.model.device.message.ThingModelMessage;
|
||||
import cc.iotkit.model.stats.TimeData;
|
||||
import cc.iotkit.temporal.IThingModelMessageData;
|
||||
import cc.iotkit.temporal.td.dao.TdTemplate;
|
||||
import cc.iotkit.temporal.td.model.TbThingModelMessage;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class ThingModelMessageDataImpl implements IThingModelMessageData {
|
||||
|
||||
@Autowired
|
||||
private TdTemplate tdTemplate;
|
||||
|
||||
public Paging<ThingModelMessage> findByTypeAndIdentifier(String deviceId, String type,
|
||||
String identifier,
|
||||
int page, int size) {
|
||||
String sql = "select time,mid,product_key,device_name,type,identifier,code,data,report_time " +
|
||||
"from thing_model_message_%s %s order by time desc limit %d offset %d";
|
||||
|
||||
//构建动态条件
|
||||
List<Object> args = new ArrayList<>();
|
||||
List<String> cons = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(type)) {
|
||||
cons.add("type=?");
|
||||
args.add(type);
|
||||
}
|
||||
if (StringUtils.isNotBlank(identifier)) {
|
||||
cons.add("identifier=?");
|
||||
args.add(identifier);
|
||||
}
|
||||
String condition = "";
|
||||
if (cons.size() > 0) {
|
||||
condition = "where " + String.join(" and ", cons);
|
||||
}
|
||||
|
||||
sql = String.format(sql, deviceId.toLowerCase(), condition, size, (page - 1) * size);
|
||||
List<TbThingModelMessage> ruleLogs = tdTemplate.query(sql,
|
||||
new BeanPropertyRowMapper<>(TbThingModelMessage.class),
|
||||
args.toArray()
|
||||
);
|
||||
|
||||
sql = String.format("select count(*) from thing_model_message_%s %s",
|
||||
deviceId.toLowerCase(), condition);
|
||||
List<Long> counts = tdTemplate.queryForList(sql, Long.class, args.toArray());
|
||||
long count = counts.size() > 0 ? counts.get(0) : 0;
|
||||
|
||||
return new Paging<>(count, ruleLogs.stream().map(r ->
|
||||
new ThingModelMessage(r.getTime().toString(), r.getMid(),
|
||||
deviceId, r.getProductKey(), r.getDeviceName(),
|
||||
r.getUid(), r.getType(), r.getIdentifier(), r.getCode(),
|
||||
JsonUtil.parse(r.getData(), Map.class),
|
||||
r.getTime(), r.getReportTime()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TimeData> getDeviceMessageStatsWithUid(String uid, long start, long end) {
|
||||
String sql = "select time,count(*) as data from(" +
|
||||
"select TIMETRUNCATE(time,1h) as time from thing_model_message " +
|
||||
"where time>=? and time<=? " + (uid != null ? "and uid=?" : "") +
|
||||
") a group by time order by time asc";
|
||||
|
||||
List<Object> args = new ArrayList<>();
|
||||
args.add(start);
|
||||
args.add(end);
|
||||
if (uid != null) {
|
||||
args.add(uid);
|
||||
}
|
||||
|
||||
return tdTemplate.query(sql, new BeanPropertyRowMapper<>(TimeData.class), args.toArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(ThingModelMessage msg) {
|
||||
//使用deviceId作表名
|
||||
String sql = String.format("INSERT INTO %s (%s) USING %s TAGS ('%s') VALUES (%s);",
|
||||
"thing_model_message_" + msg.getDeviceId().toLowerCase(),
|
||||
"time,mid,product_key,device_name,uid,type,identifier,code,data,report_time",
|
||||
"thing_model_message",
|
||||
msg.getDeviceId(),
|
||||
"?,?,?,?,?,?,?,?,?,?"
|
||||
);
|
||||
tdTemplate.update(sql, msg.getOccurred(), msg.getMid(),
|
||||
msg.getProductKey(), msg.getDeviceName(),
|
||||
msg.getUid(), msg.getType(),
|
||||
msg.getIdentifier(), msg.getCode(),
|
||||
msg.getData() == null ? "{}" : JsonUtil.toJsonString(msg.getData()),
|
||||
msg.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
Long c = tdTemplate.queryForObject("select count(*) from thing_model_message", Long.class);
|
||||
return c == null ? 0 : c;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* +----------------------------------------------------------------------
|
||||
* | Copyright (c) 奇特物联 2021-2022 All rights reserved.
|
||||
* +----------------------------------------------------------------------
|
||||
* | Licensed 未经许可不能去掉「奇特物联」相关版权
|
||||
* +----------------------------------------------------------------------
|
||||
* | Author: xw2sy@163.com
|
||||
* +----------------------------------------------------------------------
|
||||
*/
|
||||
package cc.iotkit.temporal.td.service;
|
||||
|
||||
import cc.iotkit.model.Paging;
|
||||
import cc.iotkit.model.device.VirtualDeviceLog;
|
||||
import cc.iotkit.temporal.IVirtualDeviceLogData;
|
||||
import cc.iotkit.temporal.td.dao.TdTemplate;
|
||||
import cc.iotkit.temporal.td.model.TbVirtualDeviceLog;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class VirtualDeviceLogDataImpl implements IVirtualDeviceLogData {
|
||||
|
||||
@Autowired
|
||||
private TdTemplate tdTemplate;
|
||||
|
||||
@Override
|
||||
public Paging<VirtualDeviceLog> findByVirtualDeviceId(String virtualDeviceId, int page, int size) {
|
||||
String sql = "select time,virtual_device_id,virtual_device_name,device_total,result from virtual_device_log_%s order by time desc limit %d offset %d";
|
||||
sql = String.format(sql, virtualDeviceId.toLowerCase(), size, (page - 1) * size);
|
||||
List<TbVirtualDeviceLog> logs = tdTemplate.query(sql, new BeanPropertyRowMapper<>(TbVirtualDeviceLog.class));
|
||||
|
||||
sql = "select count(*) from virtual_device_log_" + virtualDeviceId.toLowerCase();
|
||||
List<Long> counts = tdTemplate.queryForList(sql, Long.class);
|
||||
|
||||
return new Paging<>(counts.size() > 0 ? counts.get(0) : 0, logs.stream().map(r ->
|
||||
new VirtualDeviceLog(r.getTime().toString(), virtualDeviceId,
|
||||
r.getVirtualDeviceName(),
|
||||
r.getDeviceTotal(), r.getResult(),
|
||||
r.getTime()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(VirtualDeviceLog log) {
|
||||
//使用virtualDeviceId作表名
|
||||
String sql = String.format("INSERT INTO %s (%s) USING %s TAGS ('%s') VALUES (%s);",
|
||||
"virtual_device_log_" + log.getVirtualDeviceId().toLowerCase(),
|
||||
"time,virtual_device_name,device_total,result",
|
||||
"virtual_device_log",
|
||||
log.getVirtualDeviceId(),
|
||||
"?,?,?,?"
|
||||
);
|
||||
tdTemplate.update(sql, System.currentTimeMillis(), log.getVirtualDeviceName(),
|
||||
log.getDeviceTotal(), log.getResult());
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-data</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package cc.iotkit.temporal;
|
||||
|
||||
import cc.iotkit.model.product.ThingModel;
|
||||
|
||||
/**
|
||||
* 数据结构接口
|
||||
*/
|
||||
public interface IDbStructureData {
|
||||
|
||||
/**
|
||||
* 定义物模型,根据物模型定义表
|
||||
*/
|
||||
void defineThingModel(ThingModel thingModel);
|
||||
|
||||
/**
|
||||
* 取消物模型定义
|
||||
*/
|
||||
void undefineThingModel(ThingModel thingModel);
|
||||
|
||||
/**
|
||||
* 初始化数据库结构
|
||||
*/
|
||||
void initDbStructure();
|
||||
|
||||
}
|
|
@ -13,6 +13,7 @@ package cc.iotkit.temporal;
|
|||
import cc.iotkit.model.device.message.DeviceProperty;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 设备属性时序数据接口
|
||||
|
@ -32,8 +33,10 @@ public interface IDevicePropertyData {
|
|||
/**
|
||||
* 添加多个属性
|
||||
*
|
||||
* @param properties 属性列表
|
||||
* @param deviceId 设备ID
|
||||
* @param properties 属性
|
||||
* @param time 属性上报时间
|
||||
*/
|
||||
void addProperties(List<DeviceProperty> properties);
|
||||
void addProperties(String deviceId, Map<String, Object> properties, long time);
|
||||
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public interface IThingModelMessageData {
|
|||
String identifier, int page, int size);
|
||||
|
||||
/**
|
||||
* 按用户统计时间段内上报次数
|
||||
* 按用户统计时间段内每小时上报次数
|
||||
*
|
||||
* @param uid 用户id
|
||||
* @param start 开始时间戳
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iotkit-parent</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>pom</packaging>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iotkit-parent</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iotkit-parent</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iotkit-parent</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iotkit-parent</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -13,11 +13,6 @@
|
|||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
|
@ -141,11 +136,18 @@
|
|||
<artifactId>iot-rdb-data-service</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--打开注释 启用es数据库-->
|
||||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-es-temporal-service</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--打开注释 启用tdengine数据库-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cc.iotkit</groupId>-->
|
||||
<!-- <artifactId>iot-td-temporal-service</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-data-cache</artifactId>
|
||||
|
|
|
@ -22,6 +22,7 @@ import cc.iotkit.model.product.Category;
|
|||
import cc.iotkit.model.product.Product;
|
||||
import cc.iotkit.model.product.ProductModel;
|
||||
import cc.iotkit.model.product.ThingModel;
|
||||
import cc.iotkit.temporal.IDbStructureData;
|
||||
import cc.iotkit.utils.AuthUtil;
|
||||
import cn.dev33.satoken.annotation.SaCheckRole;
|
||||
import com.aliyun.oss.OSS;
|
||||
|
@ -55,6 +56,8 @@ public class ProductController {
|
|||
private AliyunConfig aliyunConfig;
|
||||
@Autowired
|
||||
private IProductModelData productModelData;
|
||||
@Autowired
|
||||
private IDbStructureData dbStructureData;
|
||||
|
||||
|
||||
private OSS ossClient;
|
||||
|
@ -87,22 +90,38 @@ public class ProductController {
|
|||
|
||||
@GetMapping("/thingModel/{productKey}")
|
||||
public ThingModel getThingModel(@PathVariable("productKey") String productKey) {
|
||||
productKey = getProduct(productKey).getId();
|
||||
checkProductOwner(productKey);
|
||||
return thingModelData.findById(productKey);
|
||||
}
|
||||
|
||||
@PostMapping("/thingModel/save")
|
||||
public void saveThingModel(String productKey, String model) {
|
||||
productKey = getProduct(productKey).getId();
|
||||
thingModelData.save(new ThingModel(productKey, productKey, JsonUtil.parse(model, ThingModel.Model.class)));
|
||||
checkProductOwner(productKey);
|
||||
ThingModel oldData = thingModelData.findByProductKey(productKey);
|
||||
ThingModel thingModel = new ThingModel(productKey, productKey, JsonUtil.parse(model, ThingModel.Model.class));
|
||||
if (oldData == null) {
|
||||
//定义时序数据库物模型数据结构
|
||||
dbStructureData.defineThingModel(thingModel);
|
||||
} else {
|
||||
//更新时序数据库物模型数据结构
|
||||
dbStructureData.undefineThingModel(thingModel);
|
||||
}
|
||||
thingModelData.save(thingModel);
|
||||
}
|
||||
|
||||
@PostMapping("/thingModel/{productKey}/delete")
|
||||
public void deleteThingModel(String productKey) {
|
||||
productKey = getProduct(productKey).getId();
|
||||
checkProductOwner(productKey);
|
||||
ThingModel thingModel = thingModelData.findByProductKey(productKey);
|
||||
//删除时序数据库物模型数据结构
|
||||
dbStructureData.defineThingModel(thingModel);
|
||||
thingModelData.deleteById(productKey);
|
||||
}
|
||||
|
||||
private void checkProductOwner(String productKey) {
|
||||
dataOwnerService.checkOwner(productData.findById(productKey));
|
||||
}
|
||||
|
||||
@GetMapping("/categories")
|
||||
public List<Category> getCategories() {
|
||||
return categoryData.findAll();
|
||||
|
|
|
@ -151,6 +151,7 @@ public class DeviceService {
|
|||
deviceComponentManager.send(thingService);
|
||||
}
|
||||
String mid = thingService.getMid();
|
||||
DeviceInfo device = deviceInfoData.findByDeviceId(deviceId);
|
||||
|
||||
//保存设备日志
|
||||
ThingModelMessage thingModelMessage = ThingModelMessage.builder()
|
||||
|
@ -158,12 +159,14 @@ public class DeviceService {
|
|||
.deviceId(deviceId)
|
||||
.productKey(pk)
|
||||
.deviceName(dn)
|
||||
.uid(device.getUid())
|
||||
.type(type)
|
||||
.identifier(identifier)
|
||||
.data(data)
|
||||
.occurred(System.currentTimeMillis())
|
||||
.time(System.currentTimeMillis())
|
||||
.build();
|
||||
|
||||
thingModelMessageData.add(thingModelMessage);
|
||||
|
||||
return mid;
|
||||
|
|
|
@ -28,6 +28,7 @@ import cc.iotkit.model.rule.TaskInfo;
|
|||
import cc.iotkit.model.space.Home;
|
||||
import cc.iotkit.model.space.Space;
|
||||
import cc.iotkit.model.space.SpaceDevice;
|
||||
import cc.iotkit.temporal.IDbStructureData;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.google.common.base.Charsets;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -35,10 +36,8 @@ import org.apache.commons.io.FileUtils;
|
|||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
@ -82,11 +81,8 @@ public class ExampleDataInit implements SmartInitializingSingleton {
|
|||
private IUserInfoData userInfoData;
|
||||
@Autowired
|
||||
private IVirtualDeviceData virtualDeviceData;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ElasticsearchRestTemplate restTemplate;
|
||||
|
||||
private IDbStructureData dbStructureData;
|
||||
|
||||
@Override
|
||||
public void afterSingletonsInstantiated() {
|
||||
|
@ -127,8 +123,13 @@ public class ExampleDataInit implements SmartInitializingSingleton {
|
|||
});
|
||||
initData("taskInfo", taskInfoData, new TypeReference<List<TaskInfo>>() {
|
||||
});
|
||||
initData("thingModel", thingModelData, new TypeReference<List<ThingModel>>() {
|
||||
List<ThingModel> thingModels = initData("thingModel", thingModelData, new TypeReference<>() {
|
||||
});
|
||||
//初始化物模型时序数据结构
|
||||
for (ThingModel thingModel : thingModels) {
|
||||
dbStructureData.defineThingModel(thingModel);
|
||||
}
|
||||
|
||||
initData("userInfo", userInfoData, new TypeReference<List<UserInfo>>() {
|
||||
});
|
||||
initData("virtualDevice", virtualDeviceData, new TypeReference<List<VirtualDevice>>() {
|
||||
|
@ -146,13 +147,14 @@ public class ExampleDataInit implements SmartInitializingSingleton {
|
|||
|
||||
}
|
||||
|
||||
private <T> void initData(String name, ICommonData service, TypeReference<T> type) throws IOException {
|
||||
private <T> T initData(String name, ICommonData service, TypeReference<T> type) throws IOException {
|
||||
log.info("init {} data...", name);
|
||||
String json = FileUtils.readFileToString(new File("./data/init/" + name + ".json"), Charsets.UTF_8);
|
||||
List<T> list = (List<T>) JsonUtil.parse(json, type);
|
||||
for (T obj : list) {
|
||||
List list = (List) JsonUtil.parse(json, type);
|
||||
for (Object obj : list) {
|
||||
service.add((Id) obj);
|
||||
}
|
||||
return (T) list;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,22 +8,23 @@ spring:
|
|||
max-file-size: 10MB
|
||||
max-request-size: 12MB
|
||||
|
||||
#注: 切换数据库时需要将项目根目录中的.init文件删除再重启
|
||||
# <<=======内置H2数据库连接设置开始==========
|
||||
jpa:
|
||||
#show-sql: true
|
||||
# show-sql: true
|
||||
hibernate:
|
||||
ddl-auto: update
|
||||
properties:
|
||||
hibernate:
|
||||
format_sql: true
|
||||
|
||||
datasource:
|
||||
url: jdbc:h2:./data/iotkit;MODE=MySQL
|
||||
username: sa
|
||||
password: 123456
|
||||
driverClassName: org.h2.Driver
|
||||
|
||||
#注: 切换数据库时需要将项目根目录中的.init文件删除再重启
|
||||
## 内置h2 web console设置
|
||||
# 内置h2 web console设置
|
||||
platform: h2
|
||||
h2:
|
||||
console:
|
||||
|
@ -31,37 +32,51 @@ spring:
|
|||
path: /h2
|
||||
settings:
|
||||
web-allow-others: true
|
||||
# =======内置H2数据库连接设置结束==========>>
|
||||
#=======内置H2数据库连接设置结束==========>>
|
||||
|
||||
|
||||
# <<==========mysql配置开始==============
|
||||
# datasource:
|
||||
# url: jdbc:mysql://127.0.0.1:3306/iotkit?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
|
||||
# driverClassName: com.mysql.cj.jdbc.Driver
|
||||
# username: root
|
||||
# password: 123456
|
||||
# validationQuery: SELECT 1
|
||||
# testOnBorrow: true
|
||||
# jpa:
|
||||
# database: MySQL
|
||||
# database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
|
||||
## show-sql: true
|
||||
# hibernate:
|
||||
# ddl-auto: update
|
||||
# properties:
|
||||
# hibernate:
|
||||
# format_sql: true
|
||||
# datasource:
|
||||
# url: jdbc:mysql://127.0.0.1:3306/iotkit?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
|
||||
# driverClassName: com.mysql.cj.jdbc.Driver
|
||||
# username: root
|
||||
# password: 123456
|
||||
# validationQuery: SELECT 1
|
||||
# testOnBorrow: true
|
||||
# jpa:
|
||||
# database: MySQL
|
||||
# database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
|
||||
## show-sql: true
|
||||
# hibernate:
|
||||
# ddl-auto: update
|
||||
# properties:
|
||||
# hibernate:
|
||||
# format_sql: true
|
||||
# ============mysql配置结束============>>
|
||||
|
||||
elasticsearch:
|
||||
rest:
|
||||
#使用内置es的配置
|
||||
uris: http://127.0.0.1:9200
|
||||
username:
|
||||
password:
|
||||
connection-timeout: 10s
|
||||
#<<================es时序数据配置开始===============
|
||||
# elasticsearch:
|
||||
# rest:
|
||||
# #使用内置es的配置
|
||||
# #uris: http://elasticsearch:9200
|
||||
# uris: http://127.0.0.1:9200
|
||||
# username:
|
||||
# password:
|
||||
# connection-timeout: 10s
|
||||
#================es时序数据配置结束===============>>
|
||||
|
||||
#<<===========tdengine时序数据库配置开始============
|
||||
td-datasource:
|
||||
url: jdbc:TAOS-RS://127.0.0.1:6041/iotkit?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8
|
||||
username: root
|
||||
password: taosdata
|
||||
driverClassName: com.taosdata.jdbc.rs.RestfulDriver
|
||||
#===========tdengine时序数据库配置开始============>>
|
||||
|
||||
|
||||
redis:
|
||||
#使用内置redis的配置
|
||||
#host: redis
|
||||
host: 127.0.0.1
|
||||
port: 6379
|
||||
database: 0
|
||||
|
@ -73,10 +88,10 @@ spring:
|
|||
|
||||
#图片存储用的是阿里云oss,如果需要上传产品图片才需要配置
|
||||
aliyun:
|
||||
bucketId: iotkit-img
|
||||
endpoint: oss-cn-shenzhen.aliyuncs.com
|
||||
accessKeyId: 填写阿里云accessKeyId
|
||||
accessKeySecret: 填写阿里云accessKeySecret
|
||||
bucketId:
|
||||
endpoint:
|
||||
accessKeyId:
|
||||
accessKeySecret:
|
||||
|
||||
sa-token:
|
||||
# token名称 (同时也是cookie名称)
|
||||
|
|
|
@ -20,7 +20,7 @@ spring:
|
|||
jpa:
|
||||
database: MySQL
|
||||
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
|
||||
# show-sql: true
|
||||
# show-sql: true
|
||||
hibernate:
|
||||
ddl-auto: update
|
||||
properties:
|
||||
|
@ -28,16 +28,29 @@ spring:
|
|||
format_sql: true
|
||||
# ============mysql配置结束============>>
|
||||
|
||||
#<<================es时序数据配置开始===============
|
||||
elasticsearch:
|
||||
rest:
|
||||
#使用内置es的配置
|
||||
#uris: http://elasticsearch:9200
|
||||
uris: http://127.0.0.1:9200
|
||||
username:
|
||||
password:
|
||||
connection-timeout: 10s
|
||||
#================es时序数据配置结束===============>>
|
||||
|
||||
#<<===========tdengine时序数据库配置开始============
|
||||
# td-datasource:
|
||||
# url: jdbc:TAOS-RS://127.0.0.1:6041/iotkit?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8
|
||||
# username: root
|
||||
# password: taosdata
|
||||
# driverClassName: com.taosdata.jdbc.rs.RestfulDriver
|
||||
#===========tdengine时序数据库配置开始============>>
|
||||
|
||||
|
||||
redis:
|
||||
#使用内置redis的配置
|
||||
#host: redis
|
||||
host: 127.0.0.1
|
||||
port: 6379
|
||||
database: 0
|
||||
|
@ -49,10 +62,10 @@ spring:
|
|||
|
||||
#图片存储用的是阿里云oss,如果需要上传产品图片才需要配置
|
||||
aliyun:
|
||||
bucketId: iotkit-img
|
||||
endpoint: oss-cn-shenzhen.aliyuncs.com
|
||||
accessKeyId: 填写阿里云accessKeyId
|
||||
accessKeySecret: 填写阿里云accessKeySecret
|
||||
bucketId:
|
||||
endpoint:
|
||||
accessKeyId:
|
||||
accessKeySecret:
|
||||
|
||||
sa-token:
|
||||
# token名称 (同时也是cookie名称)
|
||||
|
|
|
@ -17,13 +17,14 @@ spring:
|
|||
properties:
|
||||
hibernate:
|
||||
format_sql: true
|
||||
|
||||
datasource:
|
||||
url: jdbc:h2:./data/iotkit;MODE=MySQL
|
||||
username: sa
|
||||
password: 123456
|
||||
driverClassName: org.h2.Driver
|
||||
|
||||
## 内置h2 web console设置
|
||||
# 内置h2 web console设置
|
||||
platform: h2
|
||||
h2:
|
||||
console:
|
||||
|
@ -31,7 +32,8 @@ spring:
|
|||
path: /h2
|
||||
settings:
|
||||
web-allow-others: true
|
||||
# =======内置H2数据库连接设置结束==========>>
|
||||
#=======内置H2数据库连接设置结束==========>>
|
||||
|
||||
|
||||
# <<==========mysql配置开始==============
|
||||
# datasource:
|
||||
|
@ -52,6 +54,7 @@ spring:
|
|||
# format_sql: true
|
||||
# ============mysql配置结束============>>
|
||||
|
||||
#<<================es时序数据配置开始===============
|
||||
elasticsearch:
|
||||
rest:
|
||||
#使用内置es的配置
|
||||
|
@ -60,6 +63,16 @@ spring:
|
|||
username:
|
||||
password:
|
||||
connection-timeout: 10s
|
||||
#================es时序数据配置结束===============>>
|
||||
|
||||
#<<===========tdengine时序数据库配置开始============
|
||||
# td-datasource:
|
||||
# url: jdbc:TAOS-RS://127.0.0.1:6041/iotkit?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8
|
||||
# username: root
|
||||
# password: taosdata
|
||||
# driverClassName: com.taosdata.jdbc.rs.RestfulDriver
|
||||
#===========tdengine时序数据库配置开始============>>
|
||||
|
||||
|
||||
redis:
|
||||
#使用内置redis的配置
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iot-test-tool</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ public class ReportTest {
|
|||
Request request = new Request();
|
||||
request.setId(UUID.randomUUID().toString());
|
||||
Map<String, Object> param = new HashMap<>();
|
||||
param.put("volt", Math.round(Math.random()*100));
|
||||
param.put("volt", Math.round(Math.random() * 100));
|
||||
request.setParams(param);
|
||||
return request;
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iotkit-parent</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>pom</packaging>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>iotkit-parent</artifactId>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
9
pom.xml
9
pom.xml
|
@ -14,6 +14,7 @@
|
|||
<module>iot-message-bus</module>
|
||||
<module>iot-test-tool</module>
|
||||
<module>iot-data</module>
|
||||
<module>iot-data/iot-td-temporal-service</module>
|
||||
</modules>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -24,7 +25,7 @@
|
|||
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iotkit-parent</artifactId>
|
||||
<version>0.4.0-SNAPSHOT</version>
|
||||
<version>0.4.1-SNAPSHOT</version>
|
||||
<name>iotkit-parent</name>
|
||||
<description>iotkit parent</description>
|
||||
<properties>
|
||||
|
@ -292,6 +293,12 @@
|
|||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-td-temporal-service</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cc.iotkit</groupId>
|
||||
<artifactId>iot-data-cache</artifactId>
|
||||
|
|
Loading…
Reference in New Issue