feat(时序数据库集成): tdengine\influxdb\iotdb数据库集成

This commit is contained in:
gx_ma
2025-12-17 14:57:18 +08:00
parent 8501632079
commit e0e9f19d85
58 changed files with 6078 additions and 154 deletions

View File

@@ -143,6 +143,28 @@
<version>19.3.0.0</version>
</dependency>
<!-- TDengine连接 START-->
<dependency>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>${tdengine.version}</version>
</dependency>
<!-- TDengine连接 END-->
<!--influxdb-->
<dependency>
<groupId>com.influxdb</groupId>
<artifactId>influxdb-client-java</artifactId>
<version>6.7.0</version>
</dependency>
<!--iotdb-->
<dependency>
<groupId>org.apache.iotdb</groupId>
<artifactId>iotdb-jdbc</artifactId>
<version>${iotdb.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -66,7 +66,7 @@ public class DeviceLog extends BaseEntity
/** 标识符 */
@ApiModelProperty("标识符")
@Excel(name = "标识符")
private String identity;
private String identify;
/** 是否监测数据1=是0=否) */
@ApiModelProperty("是否监测数据1=是0=否)")
@@ -320,14 +320,14 @@ public class DeviceLog extends BaseEntity
{
return deviceName;
}
public void setIdentity(String identity)
public void setIdentify(String identify)
{
this.identity = identity;
this.identify = identify;
}
public String getIdentity()
public String getIdentify()
{
return identity;
return identify;
}
public void setIsMonitor(Integer isMonitor)
{
@@ -347,7 +347,7 @@ public class DeviceLog extends BaseEntity
.append("logValue", getLogValue())
.append("deviceId", getDeviceId())
.append("deviceName", getDeviceName())
.append("identity", getIdentity())
.append("identify", getIdentify())
.append("createBy", getCreateBy())
.append("isMonitor", getIsMonitor())
.append("createTime", getCreateTime())

View File

@@ -23,7 +23,7 @@ public class EventLog extends BaseEntity {
/** 标识符 */
@ApiModelProperty("标识符")
@Excel(name = "标识符")
private String identity;
private String identify;
/** 物模型名称 */
@ApiModelProperty("物模型名称")
@@ -94,14 +94,14 @@ public class EventLog extends BaseEntity {
{
return logId;
}
public void setIdentity(String identity)
public void setIdentify(String identify)
{
this.identity = identity;
this.identify = identify;
}
public String getIdentity()
public String getIdentify()
{
return identity;
return identify;
}
public void setModelName(String modelName)
{
@@ -216,7 +216,7 @@ public class EventLog extends BaseEntity {
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("logId", getLogId())
.append("identity", getIdentity())
.append("identify", getIdentify())
.append("modelName", getModelName())
.append("logType", getLogType())
.append("logValue", getLogValue())

View File

@@ -3,13 +3,10 @@ package com.fastbee.iot.mapper;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.model.DeviceStatistic;
import com.fastbee.iot.model.HistoryModel;
import com.fastbee.iot.model.MonitorModel;
import com.fastbee.iot.tdengine.service.model.TdLogDto;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.Date;
import java.util.List;
/**
@@ -44,6 +41,13 @@ public interface DeviceLogMapper
*/
public List<MonitorModel> selectMonitorList(DeviceLog deviceLog);
/**
* 新增设备日志
*
* @param deviceLog 设备日志
* @return 结果
*/
public int insertDeviceLog(DeviceLog deviceLog);
/**
* 批量保存图片

View File

@@ -0,0 +1,38 @@
package com.fastbee.iot.mapper;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.model.MonitorModel;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface IotDbLogMapper {
void createDB(String database);
Long countDB(String database);
int save(DeviceLog deviceLog);
int deleteDeviceLogByDeviceNumber(@Param("serialNumber") String deviceNumber);
Long selectPropertyLogCount(@Param("device") Device device);
Long selectEventLogCount(@Param("device") Device device);
Long selectMonitorLogCount(@Param("device") Device device);
/***
* 监测数据列表
*/
List<MonitorModel> selectMonitorList(@Param("device") DeviceLog deviceLog);
/***
* 日志列表
*/
List<DeviceLog> selectDeviceLogList(@Param("device") DeviceLog deviceLog);
List<DeviceLog> selectEventLogList(@Param("device") DeviceLog deviceLog);
}

View File

@@ -0,0 +1,84 @@
package com.fastbee.iot.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.model.HistoryModel;
import com.fastbee.iot.model.MonitorModel;
import com.fastbee.iot.tsdb.model.TdLogDto;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @package com.fastbee.mysql.mysql.tdengine
* 类名: DatabaseMapper
* 时间: 2022/5/16,0016 1:27
* 开发人: wxy
*/
@Repository
public interface TDDeviceLogMapper {
/***
* 创建数据库
*/
int createDB(String database);
/***
* 创建超级表
*/
int createSTable(String database);
/***
* 新增设备日志
*/
int save(@Param("database") String database, @Param("device") DeviceLog deviceLog);
/**
* 批量插入数据
*
* @param database 数据库名
* @param data list集合
*/
int saveBatch(@Param("database") String database, @Param("data") TdLogDto data);
/***
* 设备属性数据总数
*/
Long selectPropertyLogCount(@Param("database") String database, @Param("device") Device device);
/***
* 设备功能数据总数
*/
Long selectFunctionLogCount(@Param("database") String database, @Param("device") Device device);
/***
* 设备事件数据总数
*/
Long selectEventLogCount(@Param("database") String database, @Param("device") Device device);
/***
* 设备监测数据总数
*/
Long selectMonitorLogCount(@Param("database") String database, @Param("device") Device device);
/***
* 监测数据列表
*/
List<MonitorModel> selectMonitorList(@Param("database") String database, @Param("device") DeviceLog deviceLog);
/***
* 日志列表
*/
List<DeviceLog> selectDeviceLogList(@Param("database") String database, @Param("device") DeviceLog deviceLog);
Page<DeviceLog> selectEventLogList(Page<DeviceLog> page, @Param("database") String database, @Param("device") DeviceLog deviceLog);
/***
* 根据设备ID删除设备日志
*/
int deleteDeviceLogByDeviceNumber(@Param("database") String dbName, @Param("serialNumber") String serialNumber);
}

View File

@@ -16,5 +16,5 @@ public class HistoryModel {
private String value;
private String identity;
private String identify;
}

View File

@@ -18,6 +18,10 @@ public class PropertyDto
private String id;
/** 物模型名称 */
private String name;
/**
* 物模型值
*/
private String value;
/** 是否图表展示0-否1-是) */
private Integer isChart;
/** 是否历史存储0-否1-是) */

View File

@@ -32,4 +32,12 @@ public interface IDeviceLogService
*/
public List<DeviceLog> selectDeviceLogList(DeviceLog deviceLog);
/**
* 新增设备日志
*
* @param deviceLog 设备日志
* @return 结果
*/
public int insertDeviceLog(DeviceLog deviceLog);
}

View File

@@ -1,17 +1,16 @@
package com.fastbee.iot.service.impl;
import com.fastbee.common.core.domain.model.LoginUser;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.SecurityUtils;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.model.HistoryModel;
import com.fastbee.iot.tdengine.service.ILogService;
import com.fastbee.iot.mapper.DeviceLogMapper;
import com.fastbee.iot.tsdb.service.ILogService;
import com.fastbee.iot.model.MonitorModel;
import com.fastbee.iot.service.IDeviceLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* 设备日志Service业务层处理
@@ -52,4 +51,20 @@ public class DeviceLogServiceImpl implements IDeviceLogService
}
return logService.selectDeviceLogList(deviceLog);
}
/**
* 新增设备日志
*
* @param deviceLog 设备日志
* @return 结果
*/
@Override
public int insertDeviceLog(DeviceLog deviceLog) {
deviceLog.setCreateTime(DateUtils.getNowDate());
LoginUser loginUser = SecurityUtils.getLoginUser();
deviceLog.setTenantId(loginUser.getDeptUserId());
deviceLog.setUserId(loginUser.getUserId());
deviceLog.setCreateBy(loginUser.getUsername());
return logService.saveDeviceLog(deviceLog);
}
}

View File

@@ -67,7 +67,7 @@ public class DeviceRuntimeServiceImpl implements IDeviceRuntimeService {
log.setModelName(specs.getName());
log.setLogType(type.getCode());
log.setSpecs(JSONObject.toJSONString(specs.getDatatype()));
log.setIdentity(specs.getId());
log.setIdentify(specs.getId());
log.setSerialNumber(serialNumber);
log.setSlaveId(specs.getSlaveId());
log.setIsMonitor(specs.getIsMonitor());

View File

@@ -14,6 +14,7 @@ import com.fastbee.common.core.thingsModel.ThingsModelSimpleItem;
import com.fastbee.common.core.thingsModel.ThingsModelValuesInput;
import com.fastbee.common.enums.DataEnum;
import com.fastbee.common.enums.DeviceStatus;
import com.fastbee.common.enums.ThingsModelType;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.StringUtils;
@@ -34,7 +35,7 @@ import com.fastbee.iot.model.ThingsModels.ThingsModelValueItem;
import com.fastbee.iot.model.ThingsModels.ValueItem;
import com.fastbee.iot.service.*;
import com.fastbee.iot.service.cache.IDeviceCache;
import com.fastbee.iot.tdengine.service.ILogService;
import com.fastbee.iot.tsdb.service.ILogService;
import com.fastbee.system.service.ISysUserService;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
@@ -220,6 +221,10 @@ public class DeviceServiceImpl implements IDeviceService {
String key = RedisKeyBuilder.buildTSLVCacheKey(input.getProductId(), input.getDeviceNumber());
Map<String, String> maps = new HashMap<String, String>();
List<ThingsModelSimpleItem> list = new ArrayList<>();
//属性存储集合
List<DeviceLog> deviceLogList = new ArrayList<>();
//指令存储集合
List<FunctionLog> functionLogList = new ArrayList<>();
for (ThingsModelSimpleItem item : input.getThingsModelValueRemarkItem()) {
String identity = item.getId();
Integer slaveId = input.getSlaveId() == null ? item.getSlaveId() : input.getSlaveId();
@@ -281,12 +286,82 @@ public class DeviceServiceImpl implements IDeviceService {
/* ★★★★★★★★★★★★★★★★★★★★★★ 处理数据 - 结束 ★★★★★★★★★★★★★★★★★★★★★★*/
/*★★★★★★★★★★★★★★★★★★★★★★ 存储数据 - 开始 ★★★★★★★★★★★★★★★★★★★★★★*/
if (null != dto.getIsHistory()) {
}
ThingsModelType modelType = ThingsModelType.getType(dto.getType());
Device device = this.selectDeviceBySerialNumber(serialNumber);
switch (modelType) {
case PROP:
if (1 == dto.getIsHistory()) {
DeviceLog deviceLog = new DeviceLog();
deviceLog.setSerialNumber(serialNumber);
deviceLog.setLogType(type);
// 1=影子模式2=在线模式3=其他
deviceLog.setMode(isShadow ? 1 : 2);
// 设备日志值
deviceLog.setLogValue(value);
deviceLog.setRemark(item.getRemark());
deviceLog.setIdentify(id);
deviceLog.setCreateTime(DateUtils.getNowDate());
deviceLog.setCreateBy(device.getCreateBy());
deviceLog.setUserId(device.getTenantId());
deviceLog.setUserName(device.getTenantName());
deviceLog.setTenantId(device.getTenantId());
deviceLog.setTenantName(device.getTenantName());
deviceLog.setModelName(dto.getName());
deviceLog.setIsMonitor(dto.getIsMonitor());
deviceLogList.add(deviceLog);
}
break;
case SERVICE:
if (1 == dto.getIsHistory()) {
FunctionLog function = new FunctionLog();
function.setCreateTime(DateUtils.getNowDate());
function.setFunValue(value);
function.setSerialNumber(input.getDeviceNumber());
function.setIdentify(id);
function.setShowValue(value);
// 属性获取
function.setFunType(2);
function.setUserId(device.getTenantId());
function.setCreateBy(device.getCreateBy());
function.setModelName(dto.getName());
functionLogList.add(function);
}
break;
case EVENT:
DeviceLog event = new DeviceLog();
event.setDeviceId(device.getDeviceId());
event.setDeviceName(device.getDeviceName());
event.setLogValue(value);
event.setSerialNumber(serialNumber);
event.setIdentify(id);
event.setLogType(3);
event.setIsMonitor(0);
event.setUserId(device.getTenantId());
event.setUserName(device.getTenantName());
event.setTenantId(device.getTenantId());
event.setTenantName(device.getTenantName());
event.setCreateTime(DateUtils.getNowDate());
event.setCreateBy(device.getCreateBy());
// 1=影子模式2=在线模式3=其他
event.setMode(2);
event.setModelName(dto.getName());
deviceLogList.add(event);
break;
}
list.add(item);
}
redisCache.hashPutAll(key, maps);
if (!CollectionUtils.isEmpty(functionLogList) && !isShadow) {
functionLogService.insertBatch(functionLogList);
}
if (!CollectionUtils.isEmpty(deviceLogList) && !isShadow) {
long baseTs = System.currentTimeMillis();
for (int i = 0; i < deviceLogList.size(); i++) {
// 每条间隔1毫秒避免TDengine时间冲突
deviceLogList.get(i).setTs(new Date(baseTs + i));
logService.saveDeviceLog(deviceLogList.get(i));
}
}
/* ★★★★★★★★★★★★★★★★★★★★★★ 存储数据 - 结束 ★★★★★★★★★★★★★★★★★★★★★★*/
return list;
}
@@ -891,31 +966,38 @@ public class DeviceServiceImpl implements IDeviceService {
}
}
int result = deviceMapper.updateDeviceStatus(device);
// 添加到设备日志
EventLog event = new EventLog();
event.setDeviceId(device.getDeviceId());
event.setDeviceName(device.getDeviceName());
event.setSerialNumber(device.getSerialNumber());
event.setIsMonitor(0);
event.setUserId(device.getUserId());
event.setUserName(device.getUserName());
event.setTenantId(device.getTenantId());
event.setTenantName(device.getTenantName());
event.setCreateTime(DateUtils.getNowDate());
// 日志模式 1=影子模式2=在线模式3=其他
event.setMode(3);
DeviceLog deviceLog = new DeviceLog();
deviceLog.setDeviceId(device.getDeviceId());
deviceLog.setDeviceName(device.getDeviceName());
deviceLog.setSerialNumber(device.getSerialNumber());
deviceLog.setIsMonitor(0);
deviceLog.setTenantId(device.getTenantId());
deviceLog.setUserId(device.getTenantId());
deviceLog.setUserName(device.getTenantName());
deviceLog.setTenantName(device.getTenantName());
deviceLog.setCreateTime(DateUtils.getNowDate());
deviceLog.setCreateBy(device.getCreateBy());
deviceLog.setMode(3);
if (device.getStatus() == 3) {
event.setLogValue("1");
event.setRemark("设备上线");
event.setIdentity("online");
event.setLogType(5);
deviceLog.setLogValue("1");
deviceLog.setRemark("设备上线");
deviceLog.setIdentify("online");
deviceLog.setLogType(5);
log.info("设备上线,sn{}", device.getSerialNumber());
} else if (device.getStatus() == 4) {
event.setLogValue("0");
event.setRemark("设备离线");
event.setIdentity("offline");
event.setLogType(6);
deviceLog.setLogValue("0");
deviceLog.setRemark("设备离线");
deviceLog.setIdentify("offline");
deviceLog.setLogType(6);
log.info("设备离线,sn{}", device.getSerialNumber());
} else if (device.getStatus() == 2) {
deviceLog.setLogValue("2");
deviceLog.setRemark("设备禁用");
deviceLog.setIdentify("disable");
deviceLog.setLogType(8);
log.info("设备禁用,sn{}", device.getSerialNumber());
}
eventLogMapper.insertEventLog(event);
logService.saveDeviceLog(deviceLog);
return result;
}

View File

@@ -1,63 +0,0 @@
package com.fastbee.iot.tdengine.service.impl;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.model.DeviceStatistic;
import com.fastbee.iot.model.HistoryModel;
import com.fastbee.iot.tdengine.service.ILogService;
import com.fastbee.iot.mapper.DeviceLogMapper;
import com.fastbee.iot.model.MonitorModel;
import com.fastbee.iot.tdengine.service.model.TdLogDto;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class MySqlLogServiceImpl implements ILogService {
private DeviceLogMapper deviceLogMapper;
public MySqlLogServiceImpl(DeviceLogMapper _deviceLogMapper){
this.deviceLogMapper=_deviceLogMapper;
}
/***
* 根据设备ID删除设备日志
* @return
*/
@Override
public int deleteDeviceLogByDeviceNumber(String deviceNumber) {
return deviceLogMapper.deleteDeviceLogByDeviceNumber(deviceNumber);
}
/***
* 设备属性、功能、事件和监测数据总数
* @return
*/
@Override
public DeviceStatistic selectCategoryLogCount(Device device){
return deviceLogMapper.selectCategoryLogCount(device);
}
/***
* 监测数据列表
* @return
*/
@Override
public List<MonitorModel> selectMonitorList(DeviceLog deviceLog) {
return deviceLogMapper.selectMonitorList(deviceLog);
}
/***
* 日志列表
* @return
*/
@Override
public List<DeviceLog> selectDeviceLogList(DeviceLog deviceLog) {
return deviceLogMapper.selectDeviceLogList(deviceLog);
}
}

View File

@@ -0,0 +1,75 @@
package com.fastbee.iot.tsdb.config;
import com.influxdb.client.*;
import lombok.Data;
import okhttp3.OkHttpClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
/**
* @Author gx_ma
* @Date: 2025/03/04/ 11:19
* @description
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.influx")
public class InfluxConfig {
private boolean enabled;
private String url;
private String token;
private String org;
private String bucket;
private String measurement;
/**
* 创建 OkHttpClient 实例,用于 HTTP 请求配置(单例)
*
* @return OkHttpClient 实例
*/
@Bean
@ConditionalOnProperty(prefix = "spring.datasource.dynamic.datasource.influx", name = "enabled", havingValue = "true")
public OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.connectionPool(new okhttp3.ConnectionPool(50, 1, TimeUnit.MINUTES))
.build();
}
/**
* 创建 InfluxDBClient 客户端实例
*
* @return InfluxDBClient 实例
*/
@Bean
@ConditionalOnProperty(prefix = "spring.datasource.dynamic.datasource.influx", name = "enabled", havingValue = "true")
public InfluxDBClient influxDBClient(OkHttpClient okHttpClient) {
return InfluxDBClientFactory.create(
InfluxDBClientOptions.builder()
.url(this.url)
.org(this.org)
.bucket(this.bucket)
.authenticateToken(this.token.toCharArray())
.okHttpClient(okHttpClient.newBuilder())
.build()
);
}
/**
* 创建 WriteApiBlocking 写入 API 实例
*
* @param influxDBClient InfluxDBClient 实例
* @return WriteApiBlocking 实例
*/
@Bean
@ConditionalOnProperty(prefix = "spring.datasource.dynamic.datasource.influx", name = "enabled", havingValue = "true")
public WriteApiBlocking writeApi(final InfluxDBClient influxDBClient) {
return influxDBClient.getWriteApiBlocking();
}
}

View File

@@ -0,0 +1,16 @@
package com.fastbee.iot.tsdb.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@Data
@ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.iotdb")
public class IotDbConfig {
private boolean enabled;
private String dbName;
private String url;
private String username;
private String password;
}

View File

@@ -0,0 +1,22 @@
package com.fastbee.iot.tsdb.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 类名: TDengineConfig
* 描述: TDengine配置类
* 时间: 2022/5/13,0016 1:14
* 开发人: wxy
*/
@Configuration
@Data
@ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.taos")
public class TDengineConfig {
private boolean enabled;
private String dbName;
private String url;
private String username;
private String password;
}

View File

@@ -0,0 +1,131 @@
package com.fastbee.iot.tsdb.init;
import com.alibaba.druid.pool.DruidDataSource;
import com.fastbee.iot.tsdb.config.InfluxConfig;
import com.fastbee.iot.tsdb.config.IotDbConfig;
import com.fastbee.iot.tsdb.config.TDengineConfig;
import com.fastbee.iot.tsdb.service.ILogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.PreparedStatement;
/**
* 类名: ApplicationStarted
* 时间: 2022/5/18,0018 1:41
* 开发人: wxy
*/
@Slf4j
@Component
public class ApplicationStarted {
@Resource
private ILogService tsdbService;
@Resource
private TDengineConfig tDengineConfig;
@Resource
private InfluxConfig influxConfig;
@Resource
private IotDbConfig iotDbConfig;
@PostConstruct
public void run() {
//同时只能启用一个时序数据库
// 缓存配置状态以减少重复调用
boolean isTDengineEnabled = tDengineConfig.isEnabled();
boolean isInfluxEnabled = influxConfig.isEnabled();
boolean isIoTDBEnabled = iotDbConfig.isEnabled();
// 检查是否同时启用了多个时序数据库
int enabledCount = (isTDengineEnabled ? 1 : 0) + (isInfluxEnabled ? 1 : 0) + (isIoTDBEnabled ? 1 : 0);
if (enabledCount > 1) {
log.error("只能启用一个时序数据库,当前启用的数据库包括:"
+ (isTDengineEnabled ? "TDengine, " : "")
+ (isInfluxEnabled ? "Influx, " : "")
+ (isIoTDBEnabled ? "IoTDB" : ""));
return;
}
// 根据配置选择时序数据库
if (isTDengineEnabled) {
try {
initTDengine(tDengineConfig.getDbName());
log.info("使用TDengine存储设备数据初始化成功数据库名称: {}", tDengineConfig.getDbName());
} catch (Exception e) {
log.error("TDengine初始化失败数据库名称: {}, 错误信息: {}", tDengineConfig.getDbName(), e.getMessage(), e);
}
} else if (isInfluxEnabled) {
log.info("使用Influx存储设备数据初始化成功");
} else if (isIoTDBEnabled) {
initIoTDB(iotDbConfig.getDbName());
log.info("使用IoTDB存储设备数据初始化成功");
} else {
log.info("未启用任何时序数据库使用Mysql存储设备数据初始化成功");
}
}
public void initIoTDB(String dbName) {
tsdbService.createSTable(dbName);
log.info("完成IoTDB超级表的创建");
}
/**
* @return
* @Method
* @Description 开始初始化加载系统参数, 创建数据库和超级表
* @Param null
* @date 2022/5/22,0022 14:27
* @author wxy
*/
public void initTDengine(String dbName) {
try {
createDatabase();
//创建数据库表
tsdbService.createSTable(dbName);
log.info("完成超级表的创建");
} catch (Exception e) {
log.error("错误", e.getMessage());
e.printStackTrace();
}
}
/**
* @return
* @Method
* @Description 根据数据库连接自动创建数据库
* @Param null
* @date 2022/5/24,0024 14:32
* @author wxy
*/
private void createDatabase() {
try {
//去掉数据库名
String jdbcUrl = tDengineConfig.getUrl();
int startIndex = jdbcUrl.indexOf('/', 15);
int endIndex = jdbcUrl.indexOf('?');
String newJdbcUrl = jdbcUrl.substring(0, startIndex);
newJdbcUrl = newJdbcUrl + jdbcUrl.substring(endIndex);
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(newJdbcUrl);
dataSource.setUsername(tDengineConfig.getUsername());
dataSource.setPassword(tDengineConfig.getPassword());
if (tDengineConfig.getUrl().contains("jdbc:TAOS://")) {
dataSource.setDriverClassName("com.taosdata.jdbc.TSDBDriver");
} else if (tDengineConfig.getUrl().contains("jdbc:TAOS-WS://")) {
dataSource.setDriverClassName("com.taosdata.jdbc.ws.WebSocketDriver");
} else if(tDengineConfig.getUrl().contains("jdbc:TAOS-RS://")) {
dataSource.setDriverClassName("com.taosdata.jdbc.rs.RestfulDriver");
}
Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(String.format("create database if not exists %s;", tDengineConfig.getDbName()));
boolean resultS = ps.execute();
log.info("完成数据库创建:{}",resultS);
} catch (Exception e) {
log.info("错误", e.getMessage());
e.printStackTrace();
}
}
}

View File

@@ -1,4 +1,4 @@
package com.fastbee.iot.tdengine.service.model;
package com.fastbee.iot.tsdb.model;
import com.fastbee.iot.domain.DeviceLog;
import lombok.AllArgsConstructor;

View File

@@ -1,17 +1,13 @@
package com.fastbee.iot.tdengine.service;
package com.fastbee.iot.tsdb.service;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.model.DeviceStatistic;
import com.fastbee.iot.model.HistoryModel;
import com.fastbee.iot.model.MonitorModel;
import com.fastbee.iot.tdengine.service.model.TdLogDto;
import org.springframework.stereotype.Service;
import com.fastbee.iot.tsdb.model.TdLogDto;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @package iot.iot.log
@@ -22,6 +18,16 @@ import java.util.Map;
*/
public interface ILogService {
int createSTable(String database);
/** 保存设备日志 **/
int saveDeviceLog(DeviceLog deviceLog);
/**
* 批量保存日志
*/
int saveBatch(TdLogDto dto);
/** 根据设备编号删除设备日志 **/
int deleteDeviceLogByDeviceNumber(String deviceNumber);

View File

@@ -0,0 +1,514 @@
package com.fastbee.iot.tsdb.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.model.DeviceStatistic;
import com.fastbee.iot.model.HistoryModel;
import com.fastbee.iot.model.MonitorModel;
import com.fastbee.iot.tsdb.config.InfluxConfig;
import com.fastbee.iot.tsdb.service.ILogService;
import com.fastbee.iot.tsdb.model.TdLogDto;
import com.fastbee.iot.util.SnowflakeIdWorker;
import com.influxdb.client.InfluxDBClient;
import com.influxdb.client.QueryApi;
import com.influxdb.client.WriteApiBlocking;
import com.influxdb.client.domain.WritePrecision;
import com.influxdb.client.write.Point;
import com.influxdb.query.FluxRecord;
import com.influxdb.query.FluxTable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Author gx_ma
* @Date: 2025/03/04/ 11:16
* @description
*/
@Slf4j
@Primary
@ConditionalOnProperty(name = "spring.datasource.dynamic.datasource.influx.enabled", havingValue = "true")
@DS("influx")
@Service("Influx")
public class InfluxLogService implements ILogService {
@Resource
private InfluxConfig influxConfig;
@Resource
private InfluxDBClient influxDBClient;
@Resource
private WriteApiBlocking writeApi;
private SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(1);
@Override
public int createSTable(String database) {
return 0;
}
@Override
public int saveDeviceLog(DeviceLog deviceLog) {
long logId = snowflakeIdWorker.nextId();
deviceLog.setLogId(logId);
Point point = Point.measurement(influxConfig.getMeasurement())
.addTag("serialNumber", deviceLog.getSerialNumber())
.addField("logId", deviceLog.getLogId())
.addField("logType", deviceLog.getLogType())
.addField("logValue", deviceLog.getLogValue())
.addField("deviceId", deviceLog.getDeviceId())
.addField("deviceName", deviceLog.getDeviceName())
.addField("identify", deviceLog.getIdentify())
.addField("createBy", deviceLog.getCreateBy())
.addField("isMonitor", deviceLog.getIsMonitor())
.addField("mode", deviceLog.getMode())
.addField("remark", deviceLog.getRemark())
.addField("userId", deviceLog.getUserId())
.addField("userName", deviceLog.getUserName())
.addField("tenantId", deviceLog.getTenantId())
.addField("tenantName", deviceLog.getTenantName())
.addField("modelName", deviceLog.getModelName())
.time(deviceLog.getCreateTime().toInstant(), WritePrecision.NS);
writeApi.writePoint(influxConfig.getBucket(), influxConfig.getOrg(), point);
return 1;
}
@Override
public int saveBatch(TdLogDto dto) {
int ret = 0;
for (DeviceLog deviceLog : dto.getList()) {
ret += this.saveDeviceLog(deviceLog);
}
return ret;
}
@Override
public int deleteDeviceLogByDeviceNumber(String deviceNumber) {
QueryApi queryApi = influxDBClient.getQueryApi();
// 查询待删除的日志数量
String countQuery = String.format(
"from(bucket: \"%s\")\n" +
" |> range(start: 0)\n" +
" |> filter(fn: (r) => r._measurement == \"%s\")\n" +
" |> filter(fn: (r) => r.serialNumber == \"%s\")\n" +
" |> limit(n: 1)\n" +
" |> count()",
influxConfig.getBucket(),
influxConfig.getMeasurement(),
deviceNumber
);
long count = queryApi.queryRaw(countQuery, influxConfig.getOrg()).length();
if (count > 0) {
// 构建删除语句
String deleteQuery = String.format(
"import \"influxdata/influxdb/schema\"\n" +
"schema.delete(\n" +
" bucket: \"%s\",\n" +
" predicate: (r) => r.serialNumber == \"%s\" and r._measurement == \"%s\",\n" +
" start: 0,\n" +
" stop: now()\n" +
")",
influxConfig.getBucket(),
deviceNumber,
influxConfig.getMeasurement()
);
try {
queryApi.queryRaw(deleteQuery, influxConfig.getOrg());
} catch (Exception e) {
log.error("Failed to delete logs for device: {}", deviceNumber, e);
return 0;
}
}
return (int) count;
}
@Override
public DeviceStatistic selectCategoryLogCount(Device device) {
DeviceStatistic statistic = new DeviceStatistic();
Long property = this.selectPropertyLogCount(device);
Long event = this.selectEventLogCount(device);
Long monitor = this.selectMonitorLogCount(device);
statistic.setPropertyCount(property == null ? 0 : property);
statistic.setEventCount(event == null ? 0 : event);
statistic.setMonitorCount(monitor == null ? 0 : monitor);
return statistic;
}
private Long selectMonitorLogCount(Device device) {
QueryApi queryApi = influxDBClient.getQueryApi();
// 构建 Flux 查询语句
StringBuilder fluxQuery = new StringBuilder();
fluxQuery.append("from(bucket: \"").append(influxConfig.getBucket()).append("\")\n")
.append(" |> range(start: 0)\n")
.append(" |> filter(fn: (r) => r[\"_measurement\"] == \"").append(influxConfig.getMeasurement()).append("\")\n")
.append(" |> pivot(rowKey: [\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\") ")
.append(" |> filter(fn: (r) => r[\"logType\"] == 1 and r[\"isMonitor\"] == 1)");
if (device.getTenantId() != null) {
fluxQuery.append(" |> filter(fn: (r) => r[\"tenantId\"] == ").append(device.getTenantId()).append(")");
}
if (!Objects.isNull(device.getCreateBy())) {
fluxQuery.append(" |> filter(fn: (r) => r[\"createBy\"] == \"").append(device.getCreateBy()).append("\")");
}
fluxQuery.append(" |> group()").append(" |> count(column: \"mode\")");
// 执行查询
System.out.println("Monitor查询条件Flux Query: " + fluxQuery);
List<FluxTable> tables = queryApi.query(fluxQuery.toString());
// 处理查询结果
if (!tables.isEmpty() && !tables.get(0).getRecords().isEmpty()) {
FluxRecord record = tables.get(0).getRecords().get(0);
return record.getValueByKey("mode") != null ? ((Long) record.getValueByKey("mode")) : 0L;
}
return 0L;
}
private Long selectEventLogCount(Device device) {
QueryApi queryApi = influxDBClient.getQueryApi();
StringBuilder fluxQuery = new StringBuilder();
fluxQuery.append("from(bucket: \"").append(influxConfig.getBucket()).append("\")\n")
.append(" |> range(start: 0)\n")
.append(" |> filter(fn: (r) => r[\"_measurement\"] == \"").append(influxConfig.getMeasurement()).append("\")\n")
.append(" |> pivot(rowKey: [\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\") ")
.append(" |> filter(fn: (r) => r[\"logType\"] == 3)");
if (device.getTenantId() != null) {
fluxQuery.append(" |> filter(fn: (r) => r[\"tenantId\"] == ").append(device.getTenantId()).append(")");
}
if (!Objects.isNull(device.getCreateBy())) {
fluxQuery.append(" |> filter(fn: (r) => r[\"createBy\"] == \"").append(device.getCreateBy()).append("\")");
}
fluxQuery.append("|> group()").append("|> count(column: \"mode\")\n");
List<FluxTable> tables = queryApi.query(fluxQuery.toString());
System.out.println("Event查询条件Flux Query: " + fluxQuery);
if (!tables.isEmpty() && !tables.get(0).getRecords().isEmpty()) {
FluxRecord record = tables.get(0).getRecords().get(0);
return record.getValueByKey("mode") != null ? ((Long) record.getValueByKey("mode")) : 0L;
}
return 0L;
}
private Long selectPropertyLogCount(Device device) {
QueryApi queryApi = influxDBClient.getQueryApi();
StringBuilder fluxQuery = new StringBuilder();
fluxQuery.append("from(bucket: \"").append(influxConfig.getBucket()).append("\")\n")
.append(" |> range(start: 0)\n")
.append(" |> filter(fn: (r) => r[\"_measurement\"] == \"").append(influxConfig.getMeasurement()).append("\")\n")
.append(" |> pivot(rowKey: [\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\") ")
.append(" |> filter(fn: (r) => r[\"logType\"] == 1)\n");
if (device.getTenantId() != null) {
fluxQuery.append(" |> filter(fn: (r) => r[\"tenantId\"] == ").append(device.getTenantId()).append(")");
}
if (!Objects.isNull(device.getCreateBy())) {
fluxQuery.append(" |> filter(fn: (r) => r[\"createBy\"] == \"").append(device.getCreateBy()).append("\")");
}
fluxQuery.append("|> group()").append(" |> count(column: \"mode\")\n");
List<FluxTable> tables = queryApi.query(fluxQuery.toString());
System.out.println("Property查询条件 Flux Query: " + fluxQuery);
if (!tables.isEmpty() && !tables.get(0).getRecords().isEmpty()) {
FluxRecord record = tables.get(0).getRecords().get(0);
return record.getValueByKey("mode") != null ? ((Long) record.getValueByKey("mode")) : 0L;
}
return 0L;
}
@Override
public List<DeviceLog> selectDeviceLogList(DeviceLog deviceLog) {
QueryApi queryApi = influxDBClient.getQueryApi();
StringBuilder fluxQuery = new StringBuilder();
fluxQuery.append("from(bucket: \"").append(influxConfig.getBucket()).append("\") ")
.append("|> range(start: 0) ")
.append("|> filter(fn: (r) => r._measurement == \"").append(influxConfig.getMeasurement()).append("\") ");
fluxQuery.append("|> pivot(\n" +
" rowKey:[\"_time\"], \n" +
" columnKey: [\"_field\"], \n" +
" valueColumn: \"_value\"\n" +
" )");
fluxQuery.append("|> sort(columns: [\"_time\"], desc: true)")
.append("|> group()");
List<String> filterConditions = new ArrayList<>();
if (deviceLog.getIsMonitor() != null) {
filterConditions.add("r.isMonitor == " + deviceLog.getIsMonitor());
}
if (deviceLog.getSerialNumber() != null && !deviceLog.getSerialNumber().isEmpty()) {
filterConditions.add("r.serialNumber == \"" + deviceLog.getSerialNumber() + "\"");
}
if (deviceLog.getLogType() != null) {
filterConditions.add("r.logType == " + deviceLog.getLogType());
} else {
filterConditions.add("r.logType != 7");
}
if (deviceLog.getIdentify() != null && !deviceLog.getIdentify().isEmpty()) {
filterConditions.add("r.identify =~ /.*" + deviceLog.getIdentify() + ".*/");
}
fluxQuery.append("|> filter(fn: (r) => ");
for (int i = 0; i < filterConditions.size(); i++) {
if (i > 0) {
fluxQuery.append(" and ");
}
fluxQuery.append(filterConditions.get(i));
}
fluxQuery.append(") ");
// 计算偏移量
int pageNum = deviceLog.getPageNum();
int pageSize = deviceLog.getPageSize();
int offset = (pageNum - 1) * pageSize;
// 添加分页查询
StringBuilder originalQuery = new StringBuilder(fluxQuery);
originalQuery.append("|> limit(n: ").append(pageSize).append(", offset: ").append(offset).append(")");
List<FluxTable> tables = queryApi.query(originalQuery.toString());
List<DeviceLog> deviceLogList = new ArrayList<>();
for (FluxTable table : tables) {
for (FluxRecord record : table.getRecords()) {
DeviceLog log = new DeviceLog();
setDeviceLog(deviceLogList, record, log);
}
}
return deviceLogList;
// 注意:由于使用了 limit 和 offset这里无法直接获取总记录数需要额外查询
// List<FluxTable> countTables = queryApi.query(fluxQuery.toString());
// long total = 0;
// if (!countTables.isEmpty() && !countTables.get(0).getRecords().isEmpty()) {
// total = countTables.get(0).getRecords().size();
// }
// // 创建 MyBatis-Plus 的 Page 对象
// Page<DeviceLog> page = new Page<>(deviceLog.getPageNum(), deviceLog.getPageSize());
// page.setRecords(deviceLogList);
// page.setTotal(total);
// return page;
}
private void setDeviceLog(List<DeviceLog> deviceLogList, FluxRecord record, DeviceLog log) {
log.setLogId((Long) record.getValueByKey("logId"));
log.setLogType(((Number) Objects.requireNonNull(record.getValueByKey("logType"))).intValue());
log.setLogValue((String) record.getValueByKey("logValue"));
log.setDeviceId((Long) record.getValueByKey("deviceId"));
log.setDeviceName((String) record.getValueByKey("deviceName"));
log.setSerialNumber((String) record.getValueByKey("serialNumber"));
log.setIdentify((String) record.getValueByKey("identify"));
log.setCreateBy((String) record.getValueByKey("createBy"));
log.setIsMonitor(((Number) Objects.requireNonNull(record.getValueByKey("isMonitor"))).intValue());
log.setMode(((Number) Objects.requireNonNull(record.getValueByKey("mode"))).intValue());
log.setCreateTime(Date.from(Objects.requireNonNull(record.getTime())));
log.setRemark((String) record.getValueByKey("remark"));
log.setUserId((Long) record.getValueByKey("userId"));
log.setUserName((String) record.getValueByKey("userName"));
log.setTenantId((Long) record.getValueByKey("tenantId"));
log.setTenantName((String) record.getValueByKey("tenantName"));
log.setModelName((String) record.getValueByKey("modelName"));
deviceLogList.add(log);
}
// @Override
// public Page<DeviceLog> selectEventLogList(DeviceLog deviceLog) {
// //事件日志的时间筛选时间范围放在param参数中格式yyyy-MM-dd需要自行封装 HH:mm:ss
// if (deviceLog.getParams().get("beginTime") != null && deviceLog.getParams().get("beginTime") != "" && deviceLog.getParams().get("endTime") != null && deviceLog.getParams().get("endTime") != "") {
// String beginTime = deviceLog.getParams().get("beginTime").toString();
// String endTime = deviceLog.getParams().get("endTime").toString();
// beginTime = beginTime + " 00:00:00";
// endTime = endTime + " 23:59:59";
// deviceLog.setBeginTime(beginTime);
// deviceLog.setEndTime(endTime);
// }
// QueryApi queryApi = influxDBClient.getQueryApi();
//
// StringBuilder fluxQuery = new StringBuilder();
// fluxQuery.append("from(bucket: \"").append(influxConfig.getBucket()).append("\") ");
//
// // 处理时间范围
// if (deviceLog.getBeginTime() != null && !deviceLog.getBeginTime().isEmpty()
// && deviceLog.getEndTime() != null && !deviceLog.getEndTime().isEmpty()) {
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// try {
// Date beginDate = sdf.parse(deviceLog.getBeginTime());
// Date endDate = sdf.parse(deviceLog.getEndTime());
// // 转换为RFC3339格式时间字符串
// String startRFC3339 = beginDate.toInstant().toString();
// String stopRFC3339 = endDate.toInstant().toString();
//
// fluxQuery.append("|> range(start: ")
// .append(startRFC3339)
// .append(", stop: ")
// .append(stopRFC3339)
// .append(") ");
// } catch (ParseException e) {
// e.printStackTrace();
// // 若解析失败,可使用默认时间范围
// fluxQuery.append("|> range(start: 0) ");
// }
// } else {
// fluxQuery.append("|> range(start: 0) ");
// }
//
// fluxQuery.append("|> filter(fn: (r) => r._measurement == \"").append(influxConfig.getMeasurement()).append("\") ");
//
// // 原始查询添加 pivot 和分页操作
// fluxQuery.append("|> pivot(\n" +
// " rowKey:[\"_time\"], \n" +
// " columnKey: [\"_field\"], \n" +
// " valueColumn: \"_value\"\n" +
// " )");
//
// List<String> filterConditions = new ArrayList<>();
// if (deviceLog.getIsMonitor() != null) {
// filterConditions.add("r.isMonitor == " + deviceLog.getIsMonitor());
// }
// if (deviceLog.getLogType() != null) {
// filterConditions.add("r.logType == " + deviceLog.getLogType());
// } else {
// filterConditions.add("r.logType != 1 and r.logType != 2 and r.logType != 4 and r.logType != 7");
// }
// if (deviceLog.getSerialNumber() != null && !deviceLog.getSerialNumber().isEmpty()) {
// filterConditions.add("r.serialNumber == \"" + deviceLog.getSerialNumber() + "\"");
// }
// if (deviceLog.getIdentify() != null && !deviceLog.getIdentify().isEmpty()) {
// filterConditions.add("r.identify =~ /.*" + deviceLog.getIdentify() + ".*/");
// }
//
// fluxQuery.append("|> filter(fn: (r) => ");
// for (int i = 0; i < filterConditions.size(); i++) {
// if (i > 0) {
// fluxQuery.append(" and ");
// }
// fluxQuery.append(filterConditions.get(i));
// }
// fluxQuery.append(") ");
// fluxQuery.append("|> sort(columns: [\"_time\"], desc: true)")
// .append("|> group()");
//
// // 计算偏移量
// int pageNum = deviceLog.getPageNum();
// int pageSize = deviceLog.getPageSize();
// int offset = (pageNum - 1) * pageSize;
// // 添加分页查询
// StringBuilder originalQuery = new StringBuilder(fluxQuery);
// originalQuery.append("|> limit(n: ").append(pageSize).append(", offset: ").append(offset).append(")");
//
// List<FluxTable> tables = queryApi.query(originalQuery.toString());
// System.out.println("EventList查询Flux语句" + originalQuery);
//
// List<DeviceLog> deviceLogList = new ArrayList<>();
// for (FluxTable table : tables) {
// for (FluxRecord record : table.getRecords()) {
// DeviceLog log = new DeviceLog();
// setDeviceLog(deviceLogList, record, log);
// }
// }
//
// // 注意:由于使用了 limit 和 offset这里无法直接获取总记录数需要额外查询
// List<FluxTable> countTables = queryApi.query(fluxQuery.toString());
// System.out.println("分页查询Flux语句" + fluxQuery);
// long total = 0;
// if (!countTables.isEmpty() && !countTables.get(0).getRecords().isEmpty()) {
// total = (long) countTables.get(0).getRecords().size();
// }
//
// Page<DeviceLog> page = new Page<>(deviceLog.getPageNum(), deviceLog.getPageSize());
// page.setRecords(deviceLogList);
// page.setTotal(total);
// return page;
// }
@Override
public List<MonitorModel> selectMonitorList(DeviceLog deviceLog) {
QueryApi queryApi = influxDBClient.getQueryApi();
StringBuilder fluxQuery = new StringBuilder();
fluxQuery.append("from(bucket: \"").append(influxConfig.getBucket()).append("\") ");
// 处理时间范围
if (deviceLog.getBeginTime() != null && !deviceLog.getBeginTime().isEmpty()
&& deviceLog.getEndTime() != null && !deviceLog.getEndTime().isEmpty()) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date beginDate = sdf.parse(deviceLog.getBeginTime());
Date endDate = sdf.parse(deviceLog.getEndTime());
// 转换为RFC3339格式时间字符串
String startRFC3339 = beginDate.toInstant().toString();
String stopRFC3339 = endDate.toInstant().toString();
fluxQuery.append("|> range(start: ")
.append(startRFC3339)
.append(", stop: ")
.append(stopRFC3339)
.append(") ");
} catch (ParseException e) {
e.printStackTrace();
// 若解析失败,可使用默认时间范围
fluxQuery.append("|> range(start: 0) ");
}
} else {
fluxQuery.append("|> range(start: 0) ");
}
fluxQuery.append("|> filter(fn: (r) => r._measurement == \"").append(influxConfig.getMeasurement()).append("\") ");
fluxQuery.append("|> pivot(\n" +
" rowKey:[\"_time\"], \n" +
" columnKey: [\"_field\"], \n" +
" valueColumn: \"_value\"\n" +
" )");
fluxQuery.append("|> filter(fn: (r) => r.isMonitor == 1) ");
List<String> filterConditions = new ArrayList<>();
if (deviceLog.getSerialNumber() != null && !deviceLog.getSerialNumber().isEmpty()) {
filterConditions.add("r.serialNumber == \"" + deviceLog.getSerialNumber() + "\"");
}
if (deviceLog.getIdentify() != null && !deviceLog.getIdentify().isEmpty()) {
filterConditions.add("r.identify =~ /.*" + deviceLog.getIdentify() + ".*/");
}
if (!filterConditions.isEmpty()) {
fluxQuery.append("|> filter(fn: (r) => ");
for (int i = 0; i < filterConditions.size(); i++) {
if (i > 0) {
fluxQuery.append(" and ");
}
fluxQuery.append(filterConditions.get(i));
}
fluxQuery.append(") ");
}
fluxQuery.append("|> sort(columns: [\"_time\"], desc: true) ");
fluxQuery.append("|> keep(columns: [\"_value\", \"_time\"]) ");
List<FluxTable> tables = queryApi.query(fluxQuery.toString());
List<MonitorModel> monitorList = new ArrayList<>();
for (FluxTable table : tables) {
for (FluxRecord record : table.getRecords()) {
MonitorModel model = new MonitorModel();
model.setValue((String) record.getValue());
model.setTime(new Date(record.getTime().getEpochSecond() * 1000));
monitorList.add(model);
}
}
return monitorList;
}
}

View File

@@ -0,0 +1,120 @@
package com.fastbee.iot.tsdb.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.mapper.IotDbLogMapper;
import com.fastbee.iot.model.DeviceStatistic;
import com.fastbee.iot.model.HistoryModel;
import com.fastbee.iot.model.MonitorModel;
import com.fastbee.iot.tsdb.service.ILogService;
import com.fastbee.iot.tsdb.model.TdLogDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Slf4j
@Primary
@ConditionalOnProperty(name = "spring.datasource.dynamic.datasource.iotdb.enabled", havingValue = "true")
@DS("iotdb")
@Service("IotDB")
public class IotDbLogService implements ILogService {
@Resource
private IotDbLogMapper iotDbLogMapper;
@Override
public int createSTable(String database) {
Long count = iotDbLogMapper.countDB(database);
if (count == 0) {
iotDbLogMapper.createDB(database);
}
return 1;
}
@Override
public int saveDeviceLog(DeviceLog deviceLog) {
return iotDbLogMapper.save(deviceLog);
}
@Override
public int saveBatch(TdLogDto dto) {
int ret = 0;
for (DeviceLog deviceLog : dto.getList()) {
ret += this.saveDeviceLog(deviceLog);
}
return ret;
}
@Override
public int deleteDeviceLogByDeviceNumber(String deviceNumber) {
return iotDbLogMapper.deleteDeviceLogByDeviceNumber(deviceNumber);
}
@Override
public DeviceStatistic selectCategoryLogCount(Device device) {
DeviceStatistic statistic = new DeviceStatistic();
Long property = iotDbLogMapper.selectPropertyLogCount(device);
Long event = iotDbLogMapper.selectEventLogCount(device);
Long monitor = iotDbLogMapper.selectMonitorLogCount(device);
statistic.setPropertyCount(property == null ? 0 : property);
statistic.setEventCount(event == null ? 0 : event);
statistic.setMonitorCount(monitor == null ? 0 : monitor);
return statistic;
}
@Override
public List<DeviceLog> selectDeviceLogList(DeviceLog deviceLog) {
if (deviceLog.getIdentify() != null) {
deviceLog.setIdentify("%" + deviceLog.getIdentify() + "%");
}
return iotDbLogMapper.selectDeviceLogList(deviceLog);
}
// @Override
// public Page<DeviceLog> selectEventLogList(DeviceLog deviceLog) {
// if (deviceLog.getParams().get("beginTime") != null && deviceLog.getParams().get("beginTime") != "" && deviceLog.getParams().get("endTime") != null && deviceLog.getParams().get("endTime") != "") {
// String beginTime = deviceLog.getParams().get("beginTime").toString();
// String endTime = deviceLog.getParams().get("endTime").toString();
// beginTime = beginTime + " 00:00:00";
// endTime = endTime + " 23:59:59";
// deviceLog.setBeginTime(beginTime);
// deviceLog.setEndTime(endTime);
// }
// if (deviceLog.getIdentify() != null) {
// deviceLog.setIdentify("%" + deviceLog.getIdentify() + "%");
// }
// // 获取全量数据
// List<DeviceLog> allLogs = iotDbLogMapper.selectEventLogList(deviceLog);
//
// // 手动分页处理
// int pageSize = deviceLog.getPageSize();
// int pageNum = deviceLog.getPageNum();
// int start = (pageNum - 1) * pageSize;
// int end = Math.min(start + pageSize, allLogs.size());
//
// // 构建MyBatis-Plus分页对象
// Page<DeviceLog> page = new Page<>(pageNum, pageSize);
// page.setRecords(allLogs.subList(start, end));
// page.setTotal(allLogs.size());
//
// return page;
// }
@Override
public List<MonitorModel> selectMonitorList(DeviceLog deviceLog) {
if (deviceLog.getIdentify() != null) {
deviceLog.setIdentify("%" + deviceLog.getIdentify() + "%");
}
return iotDbLogMapper.selectMonitorList(deviceLog);
}
}

View File

@@ -0,0 +1,109 @@
package com.fastbee.iot.tsdb.service.impl;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.domain.EventLog;
import com.fastbee.iot.mapper.EventLogMapper;
import com.fastbee.iot.model.DeviceStatistic;
import com.fastbee.iot.tsdb.model.TdLogDto;
import com.fastbee.iot.tsdb.service.ILogService;
import com.fastbee.iot.mapper.DeviceLogMapper;
import com.fastbee.iot.model.MonitorModel;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class MySqlLogServiceImpl implements ILogService {
private DeviceLogMapper deviceLogMapper;
@Resource
private EventLogMapper eventLogMapper;
public MySqlLogServiceImpl(DeviceLogMapper _deviceLogMapper){
this.deviceLogMapper=_deviceLogMapper;
}
@Override
public int createSTable(String database) {
return 0;
}
/***
* 新增设备日志
* @return
*/
@Override
public int saveDeviceLog(DeviceLog deviceLog) {
if (deviceLog.getLogType() == 3 || deviceLog.getLogType() == 5 || deviceLog.getLogType() == 6 || deviceLog.getLogType() == 8) {
EventLog event = new EventLog();
event.setDeviceId(deviceLog.getDeviceId());
event.setDeviceName(deviceLog.getDeviceName());
event.setSerialNumber(deviceLog.getSerialNumber());
event.setIsMonitor(0);
event.setUserId(deviceLog.getTenantId());
event.setUserName(deviceLog.getTenantName());
event.setTenantId(deviceLog.getTenantId());
event.setTenantName(deviceLog.getTenantName());
event.setCreateTime(DateUtils.getNowDate());
event.setCreateBy(deviceLog.getCreateBy());
// 日志模式 1=影子模式2=在线模式3=其他
event.setMode(3);
event.setLogValue(deviceLog.getLogValue());
event.setRemark(deviceLog.getRemark());
event.setIdentify(deviceLog.getIdentify());
event.setLogType(deviceLog.getLogType());
return eventLogMapper.insertEventLog(event);
} else {
return deviceLogMapper.insertDeviceLog(deviceLog);
}
}
@Override
public int saveBatch(TdLogDto dto) {
int ret = 0;
for (DeviceLog deviceLog : dto.getList()) {
ret += this.saveDeviceLog(deviceLog);
}
return ret;
}
/***
* 根据设备ID删除设备日志
* @return
*/
@Override
public int deleteDeviceLogByDeviceNumber(String deviceNumber) {
return deviceLogMapper.deleteDeviceLogByDeviceNumber(deviceNumber);
}
/***
* 设备属性、功能、事件和监测数据总数
* @return
*/
@Override
public DeviceStatistic selectCategoryLogCount(Device device){
return deviceLogMapper.selectCategoryLogCount(device);
}
/***
* 监测数据列表
* @return
*/
@Override
public List<MonitorModel> selectMonitorList(DeviceLog deviceLog) {
return deviceLogMapper.selectMonitorList(deviceLog);
}
/***
* 日志列表
* @return
*/
@Override
public List<DeviceLog> selectDeviceLogList(DeviceLog deviceLog) {
return deviceLogMapper.selectDeviceLogList(deviceLog);
}
}

View File

@@ -0,0 +1,126 @@
package com.fastbee.iot.tsdb.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.domain.DeviceLog;
import com.fastbee.iot.model.DeviceStatistic;
import com.fastbee.iot.tsdb.service.ILogService;
import com.fastbee.iot.model.MonitorModel;
import com.fastbee.iot.mapper.TDDeviceLogMapper;
import com.fastbee.iot.tsdb.model.TdLogDto;
import com.fastbee.iot.util.SnowflakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 类名: TdengineLogServiceImpl
* 描述: TDengine存储日志数据实现类
* 时间: 2022/5/22,0022 13:38
* 开发人: admin
*/
@Slf4j
@Primary
@ConditionalOnProperty(name = "spring.datasource.dynamic.datasource.taos.enabled", havingValue = "true")
@DS("taos")
@Service("Tdengine")
public class TdengineLogServiceImpl implements ILogService {
@Autowired
private TDDeviceLogMapper tDDeviceLogMapper;
private SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(1);
@Value("${spring.datasource.dynamic.datasource.taos.dbName}")
private String dbName;
@Override
public int createSTable(String database) {
return tDDeviceLogMapper.createSTable(database);
}
/***
* 新增设备日志
* @return
*/
@Override
public int saveDeviceLog(DeviceLog deviceLog) {
long logId = snowflakeIdWorker.nextId();
deviceLog.setLogId(logId);
return tDDeviceLogMapper.save(dbName, deviceLog);
}
/**
* 批量保存日志
*/
@Override
public int saveBatch(TdLogDto dto) {
return tDDeviceLogMapper.saveBatch(dbName, dto);
}
/***
* 设备属性、功能、事件和监测数据总数
* @return
*/
@Override
public DeviceStatistic selectCategoryLogCount(Device device) {
DeviceStatistic statistic = new DeviceStatistic();
Long property = tDDeviceLogMapper.selectPropertyLogCount(dbName, device);
Long event = tDDeviceLogMapper.selectEventLogCount(dbName, device);
Long monitor = tDDeviceLogMapper.selectMonitorLogCount(dbName, device);
statistic.setPropertyCount(property == null ? 0 : property);
statistic.setEventCount(event == null ? 0 : event);
statistic.setMonitorCount(monitor == null ? 0 : monitor);
return statistic;
}
/***
* 日志列表
* @return
*/
@Override
public List<DeviceLog> selectDeviceLogList(DeviceLog deviceLog) {
return tDDeviceLogMapper.selectDeviceLogList(dbName, deviceLog);
}
// @Override
// public Page<DeviceLog> selectEventLogList(DeviceLog deviceLog) {
// if (deviceLog.getParams().get("beginTime") != null && deviceLog.getParams().get("beginTime") != "" && deviceLog.getParams().get("endTime") != null && deviceLog.getParams().get("endTime") != "") {
// String beginTime = deviceLog.getParams().get("beginTime").toString();
// String endTime = deviceLog.getParams().get("endTime").toString();
// beginTime = beginTime + " 00:00:00";
// endTime = endTime + " 23:59:59";
// deviceLog.setBeginTime(beginTime);
// deviceLog.setEndTime(endTime);
// }
// return tDDeviceLogMapper.selectEventLogList(new Page<>(deviceLog.getPageNum(), deviceLog.getPageSize()), dbName, deviceLog);
// }
/***
* 监测数据列表
* @return
*/
@Override
public List<MonitorModel> selectMonitorList(DeviceLog deviceLog) {
if (deviceLog.getIdentify() != null) {
deviceLog.setIdentify("%" + deviceLog.getIdentify() + "%");
}
return tDDeviceLogMapper.selectMonitorList(dbName, deviceLog);
}
/***
* 根据设备ID删除设备日志
* @return
*/
@Override
public int deleteDeviceLogByDeviceNumber(String deviceNumber) {
return tDDeviceLogMapper.deleteDeviceLogByDeviceNumber(dbName, deviceNumber);
}
}

View File

@@ -16,7 +16,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="deviceId" column="device_id" />
<result property="deviceName" column="device_name" />
<result property="serialNumber" column="serial_number" />
<result property="identity" column="identify" />
<result property="identify" column="identify" />
<result property="createBy" column="create_by" />
<result property="isMonitor" column="is_monitor" />
<result property="mode" column="mode" />
@@ -31,7 +31,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="com.fastbee.iot.model.HistoryModel" id="HistoryResult">
<result property="value" column="log_value" />
<result property="time" column="create_time" />
<result property="identity" column="identify" />
<result property="identify" column="identify" />
</resultMap>
<sql id="selectDeviceLogVo">
@@ -42,7 +42,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select log_value, create_time from iot_device_log
<where>
<if test="1==1"> and is_monitor=1</if>
<if test="identity != null and identity != ''"> and identify = #{identity}</if>
<if test="identify != null and identify != ''"> and identify = #{identify}</if>
<if test="deviceId != null and deviceId !=0"> and device_id = #{deviceId}</if>
<if test="serialNumber != null and serialNumber !=''"> and serial_number = #{serialNumber}</if>
<if test="beginTime != null and beginTime != '' and endTime != null and endTime != ''"> and create_time between #{beginTime} and #{endTime}</if>
@@ -94,6 +94,45 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select>
<insert id="insertDeviceLog" parameterType="com.fastbee.iot.domain.DeviceLog" useGeneratedKeys="true" keyProperty="logId">
insert into iot_device_log
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="logType != null">log_type,</if>
<if test="logValue != null">log_value,</if>
<if test="deviceId != null">device_id,</if>
<if test="deviceName != null and deviceName != ''">device_name,</if>
<if test="serialNumber != null and serialNumber != ''">serial_number,</if>
<if test="identify != null">identify,</if>
<if test="createBy != null">create_by,</if>
<if test="isMonitor != null">is_monitor,</if>
<if test="mode != null">mode,</if>
<if test="createTime != null">create_time,</if>
<if test="remark != null">remark,</if>
<if test="userId != null">user_id,</if>
<if test="userName != null and userName != ''">user_name,</if>
<if test="tenantId != null">tenant_id,</if>
<if test="tenantName != null and tenantName != ''">tenant_name,</if>
<if test="modelName != null and modelName != ''">model_name,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="logType != null">#{logType},</if>
<if test="logValue != null">#{logValue},</if>
<if test="deviceId != null">#{deviceId},</if>
<if test="deviceName != null and deviceName != ''">#{deviceName},</if>
<if test="serialNumber != null and serialNumber != ''">#{serialNumber},</if>
<if test="identify != null">#{identify},</if>
<if test="createBy != null">#{createBy},</if>
<if test="isMonitor != null">#{isMonitor},</if>
<if test="mode != null">#{mode},</if>
<if test="createTime != null">#{createTime},</if>
<if test="remark != null">#{remark},</if>
<if test="userId != null">#{userId},</if>
<if test="userName != null and userName != ''">#{userName},</if>
<if test="tenantId != null">#{tenantId},</if>
<if test="tenantName != null and tenantName != ''">#{tenantName},</if>
<if test="modelName != null and modelName != ''">#{modelName},</if>
</trim>
</insert>
<insert id="saveBatch" parameterType="com.fastbee.iot.domain.DeviceLog">
insert into iot_device_log (log_type,log_value,device_id,device_name,serial_number,identify,create_by,
@@ -101,7 +140,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
values
<foreach collection="list" item="item" index="index" separator=",">
(#{item.logType},#{item.logValue},#{item.deviceId},#{item.deviceName},#{item.serialNumber},
#{item.identity},#{item.createBy},#{item.isMonitor},#{item.mode},#{item.createTime},#{item.remark},
#{item.identify},#{item.createBy},#{item.isMonitor},#{item.mode},#{item.createTime},#{item.remark},
#{item.userId},#{item.userName},#{item.tenantId},#{item.tenantName},#{item.modelName})
</foreach>
</insert>
@@ -114,7 +153,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deviceId != null">device_id = #{deviceId},</if>
<if test="deviceName != null and deviceName != ''">device_name = #{deviceName},</if>
<if test="serialNumber != null and serialNumber != ''">serial_number = #{serialNumber},</if>
<if test="identity != null">identify = #{identity},</if>
<if test="identify != null">identify = #{identify},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="isMonitor != null">is_monitor = #{isMonitor},</if>
<if test="mode != null">mode = #{mode},</if>
@@ -150,7 +189,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deviceId != null and deviceId !=0"> and device_id = #{deviceId}</if>
<if test="serialNumber != null and serialNumber !=''"> and serial_number = #{serialNumber}</if>
<if test="logType != null "> and log_type = #{logType}</if>
<if test="identity != null and identity != ''"> and identity like concat('%', #{identity}, '%')</if>
<if test="identify != null and identify != ''"> and identify like concat('%', #{identify}, '%')</if>
</where>
order by create_time desc
</select>

View File

@@ -6,7 +6,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="com.fastbee.iot.domain.EventLog" id="EventLogResult">
<result property="logId" column="log_id" />
<result property="identity" column="identify" />
<result property="identify" column="identify" />
<result property="modelName" column="model_name" />
<result property="logType" column="log_type" />
<result property="logValue" column="log_value" />
@@ -31,7 +31,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectEventLogList" parameterType="com.fastbee.iot.domain.EventLog" resultMap="EventLogResult">
<include refid="selectEventLogVo"/>
<where>
<if test="identity != null and identity != ''"> and identify = #{identity}</if>
<if test="identify != null and identify != ''"> and identify = #{identify}</if>
<if test="modelName != null and modelName != ''"> and model_name like concat('%', #{modelName}, '%')</if>
<if test="logType != null "> and log_type = #{logType}</if>
<if test="logValue != null and logValue != ''"> and log_value = #{logValue}</if>
@@ -62,7 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<insert id="insertEventLog" parameterType="com.fastbee.iot.domain.EventLog" useGeneratedKeys="true" keyProperty="logId">
insert into iot_event_log
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="identity != null and identity != ''">identify,</if>
<if test="identify != null and identify != ''">identify,</if>
<if test="modelName != null">model_name,</if>
<if test="logType != null">log_type,</if>
<if test="logValue != null and logValue != ''">log_value,</if>
@@ -80,7 +80,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="identity != null and identity != ''">#{identity},</if>
<if test="identify != null and identify != ''">#{identify},</if>
<if test="modelName != null">#{modelName},</if>
<if test="logType != null">#{logType},</if>
<if test="logValue != null and logValue != ''">#{logValue},</if>
@@ -104,7 +104,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
user_name,tenant_id,tenant_name,create_by,create_time,remark)
values
<foreach collection="list" separator="," index="index" item="item">
(#{item.identity},#{item.modelName},#{item.logType},#{item.logValue},#{item.deviceId},#{item.deviceName},#{item.serialNumber},#{item.isMonitor},
(#{item.identify},#{item.modelName},#{item.logType},#{item.logValue},#{item.deviceId},#{item.deviceName},#{item.serialNumber},#{item.isMonitor},
#{item.mode},#{item.userId},#{item.userName},#{item.tenantId},#{item.tenantName},#{item.createBy},#{item.createTime},#{item.remark})
</foreach>
</insert>
@@ -112,7 +112,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<update id="updateEventLog" parameterType="com.fastbee.iot.domain.EventLog">
update iot_event_log
<trim prefix="SET" suffixOverrides=",">
<if test="identity != null and identity != ''">identify = #{identity},</if>
<if test="identify != null and identify != ''">identify = #{identify},</if>
<if test="modelName != null">model_name = #{modelName},</if>
<if test="logType != null">log_type = #{logType},</if>
<if test="logValue != null and logValue != ''">log_value = #{logValue},</if>

View File

@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fastbee.iot.mapper.IotDbLogMapper">
<resultMap type="com.fastbee.iot.model.MonitorModel" id="MonitorResult">
<result property="value" column="root.ln.device_log.log_value" />
<result property="time" column="Time" />
</resultMap>
<resultMap type="com.fastbee.iot.domain.DeviceLog" id="DeviceLogResult">
<result property="createTime" column="Time" />
<result property="logType" column="root.ln.device_log.log_type" />
<result property="logValue" column="root.ln.device_log.log_value" />
<result property="deviceId" column="root.ln.device_log.device_id" />
<result property="deviceName" column="root.ln.device_log.device_name" />
<result property="serialNumber" column="root.ln.device_log.serial_number" />
<result property="identify" column="root.ln.device_log.identify" />
<result property="createBy" column="root.ln.device_log.create_by" />
<result property="isMonitor" column="root.ln.device_log.is_monitor" />
<result property="mode" column="root.ln.device_log.mode" />
<result property="remark" column="root.ln.device_log.remark" />
<result property="tenantId" column="root.ln.device_log.tenant_id" />
</resultMap>
<resultMap type="com.fastbee.iot.model.HistoryModel" id="HistoryResult">
<result property="time" column="Time" />
<result property="value" column="root.ln.device_log.log_value" />
<result property="identify" column="root.ln.device_log.identify" />
</resultMap>
<!-- <resultMap type="com.fastbee.iot.model.HistoryBo" id="HistoryResultBo">-->
<!-- <result property="value" column="root.ln.device_log.log_value" />-->
<!-- <result property="time" column="Time" />-->
<!-- <result property="identify" column="root.ln.device_log.identify" />-->
<!-- </resultMap>-->
<!-- <resultMap type="com.fastbee.iot.model.vo.ThingsModelLogCountVO" id="ThingsModelLogCountVO">-->
<!-- <result property="identifier" column="root.ln.device_log.identify" />-->
<!-- </resultMap>-->
<update id="createDB">
create database ${database}
</update>
<select id="countDB" resultType="Long">
count databases ${database}
</select>
<insert id="save" parameterType="com.fastbee.iot.domain.DeviceLog" useGeneratedKeys="false">
INSERT INTO root.ln.device_log (
<trim suffixOverrides=",">
<if test="logType != null">log_type</if>
<if test="logValue != null">, log_value</if>
<if test="deviceId != null">, device_id</if>
<if test="deviceName != null and deviceName != ''">, device_name</if>
<if test="serialNumber != null and serialNumber != ''">,serial_number</if>
<if test="identify != null">, identify</if>
<if test="createBy != null">, create_by</if>
<if test="isMonitor != null">, is_monitor</if>
<if test="mode != null">, mode</if>
<if test="remark != null">, remark</if>
<if test="tenantId != null">, tenant_id</if>
</trim>
) VALUES (
<trim suffixOverrides=",">
<if test="logType != null">#{logType}</if>
<if test="logValue != null">, #{logValue}</if>
<if test="deviceId != null">, #{deviceId}</if>
<if test="deviceName != null and deviceName != ''">, #{deviceName}</if>
<if test="serialNumber != null and serialNumber != ''">,#{serialNumber}</if>
<if test="identify != null">, #{identify}</if>
<if test="createBy != null">, #{createBy}</if>
<if test="isMonitor != null">, #{isMonitor}</if>
<if test="mode != null">, #{mode}</if>
<if test="remark != null">, #{remark}</if>
<if test="tenantId != null">, #{tenantId}</if>
</trim>
)
</insert>
<delete id="deleteDeviceLogByDeviceNumber" parameterType="String">
DELETE FROM root.ln.device_log.**
</delete>
<select id="selectPropertyLogCount" parameterType="com.fastbee.iot.domain.Device" resultType="Long">
SELECT COUNT(mode)
FROM root.ln.device_log
WHERE log_type = 1
<if test="device.tenantId != null">AND tenant_id = #{device.tenantId}</if>
<if test="device.createBy != null and device.createBy != ''"> AND create_by = #{device.createBy}</if>
</select>
<select id="selectFunctionLogCount" parameterType="com.fastbee.iot.domain.Device" resultType="Long">
select count(mode)
from root.ln.device_log
where log_type=2
<if test="device.tenantId != null"> and tenant_id = #{device.tenantId}</if>
</select>
<select id="selectEventLogCount" parameterType="com.fastbee.iot.domain.Device" resultType="Long">
select count(mode)
from root.ln.device_log
where log_type=3
<if test="device.tenantId != null"> and tenant_id = #{device.tenantId}</if>
<if test="device.createBy != null and device.createBy != ''"> AND create_by = #{device.createBy}</if>
</select>
<select id="selectMonitorLogCount" parameterType="com.fastbee.iot.domain.Device" resultType="Long">
select count(mode)
from root.ln.device_log
where log_type=1 and is_monitor=1
<if test="device.tenantId != null"> and tenant_id = #{device.tenantId}</if>
<if test="device.createBy != null and device.createBy != ''"> AND create_by = #{device.createBy}</if>
</select>
<select id="selectMonitorList" parameterType="com.fastbee.iot.domain.DeviceLog" resultMap="MonitorResult">
SELECT log_value FROM root.ln.device_log
<where>
is_monitor = 1
<if test="device.serialNumber != null and device.serialNumber != ''">
AND serial_number = '${device.serialNumber}'
</if>
<if test="device.identify != null and device.identify != ''">
AND identify LIKE '${device.identify}'
</if>
<if test="device.beginTime != null and device.endTime != null">
AND time <![CDATA[ >= ]]> ${device.beginTime} and time <![CDATA[ <= ]]> ${device.endTime}
</if>
</where>
ORDER BY time DESC
LIMIT #{device.total}
</select>
<select id="selectDeviceLogList" parameterType="com.fastbee.iot.domain.DeviceLog" resultMap="DeviceLogResult">
SELECT log_type, log_value, device_id, device_name, identify, create_by, is_monitor, mode, tenant_id, remark, model_name
FROM root.ln.device_log
<where>
<if test="device.serialNumber != null and device.serialNumber != ''">
and serial_number = #{device.serialNumber}
</if>
<if test="device.isMonitor != null">
AND is_monitor = #{device.isMonitor}
</if>
<if test="device.logType != null">
AND log_type = #{device.logType}
</if>
<if test="device.logType == null">
AND log_type != 7
</if>
<if test="device.identify != null and device.identify != ''">
AND identify LIKE '${device.identify}'
</if>
</where>
ORDER BY time DESC limit #{page.pageSize} offset #{page.pageNum}
</select>
<select id="selectEventLogList" parameterType="com.fastbee.iot.domain.DeviceLog" resultMap="DeviceLogResult">
SELECT log_type, log_value, device_id, device_name, serial_number, identify, create_by, is_monitor, mode, remark, tenant_id FROM root.ln.device_log
<where>
<if test="device.serialNumber != null and device.serialNumber != ''">
and serial_number = '${device.serialNumber}'
</if>
<if test="device.isMonitor != null"> and is_monitor = #{device.isMonitor}</if>
<if test="device.logType != null "> and log_type = #{device.logType}</if>
<if test="device.logType == null "> and log_type != 1
and log_type != 2
and log_type != 4
and log_type != 7
</if>
<if test="device.identify != null and device.identify != ''"> and identify like '${device.identify}' </if>
<if test="device.beginTime != null and device.beginTime != '' and device.endTime != null and device.endTime != ''">
and time <![CDATA[ >= ]]> ${device.beginTime} and time <![CDATA[ <= ]]> ${device.endTime}
</if>
</where>
order by time desc
</select>
</mapper>

View File

@@ -0,0 +1,176 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fastbee.iot.mapper.TDDeviceLogMapper">
<resultMap type="com.fastbee.iot.model.MonitorModel" id="MonitorResult">
<result property="value" column="log_value" />
<result property="time" column="ts" />
</resultMap>
<resultMap type="com.fastbee.iot.domain.DeviceLog" id="DeviceLogResult">
<result property="logType" column="log_type" />
<result property="logValue" column="log_value" />
<result property="mode" column="mode" />
<result property="deviceId" column="device_id" />
<result property="deviceName" column="device_name" />
<result property="serialNumber" column="serial_number" />
<result property="identify" column="identify" />
<result property="createBy" column="create_by" />
<result property="isMonitor" column="is_monitor" />
<result property="createTime" column="ts" />
<result property="userId" column="user_id" />
<result property="userName" column="user_name" />
<result property="tenantId" column="tenant_id" />
<result property="tenantName" column="tenant_name" />
<result property="remark" column="remark" />
</resultMap>
<!-- <resultMap type="com.fastbee.iot.model.HistoryModel" id="HistoryResult">-->
<!-- <result property="time" column="ts" />-->
<!-- <result property="value" column="log_value" />-->
<!-- <result property="identify" column="identify" />-->
<!-- <result property="moderName" column="mode" />-->
<!-- </resultMap>-->
<!-- <resultMap type="com.fastbee.iot.model.HistoryBo" id="HistoryResultBo">-->
<!-- <result property="value" column="log_value" />-->
<!-- <result property="time" column="ts" />-->
<!-- <result property="identify" column="identify" />-->
<!-- </resultMap>-->
<update id="createDB">
create database if not exists ${database} vgroups 4;
</update>
<update id="createSTable">
create STABLE if not exists ${database}.device_log
(ts timestamp,
log_value BINARY(100),
is_monitor TINYINT,
log_type TINYINT,
identify BINARY(100),
mode TINYINT,
remark BINARY(500),
tenant_id BIGINT,
create_by BINARY(50))
TAGS(serial_number BINARY(50));
</update>
<insert id="save" parameterType="com.fastbee.iot.domain.DeviceLog" useGeneratedKeys="false">
insert into ${database}.device_${device.serialNumber} using device_log
tags (#{device.serialNumber})
values (
<if test="device.ts != null">
#{device.ts},
</if>
<if test="device.ts == null">
now,
</if>
#{device.logValue},
#{device.isMonitor},
#{device.logType},
#{device.identify},
#{device.mode},
#{device.remark},
#{device.tenantId},
#{device.createBy});
</insert>
<insert id="saveBatch" parameterType="com.fastbee.iot.tsdb.model.TdLogDto" useGeneratedKeys="false">
insert into ${database}.device_${data.serialNumber} using device_log
tags (#{data.serialNumber})
values
<foreach collection="data.list" separator=" " item="device" index="index">
(now,
#{device.logValue},
#{device.isMonitor},
#{device.logType},
#{device.identify},
#{device.mode},
#{device.remark},
#{device.tenantId},
#{device.createBy})
</foreach>
</insert>
<delete id="deleteDeviceLogByDeviceNumber" parameterType="com.fastbee.iot.domain.DeviceLog">
DROP TABLE IF EXISTS ${database}.device_${serialNumber};
</delete>
<select id="selectPropertyLogCount" parameterType="com.fastbee.iot.domain.Device" resultType="Long">
select count(mode) as propertyCount
from ${database}.device_log
where log_type=1
<if test="device.tenantId != null"> and tenant_id = #{device.tenantId}</if>
<if test="device.createBy != null and device.createBy != ''"> AND create_by = #{device.createBy}</if>
</select>
<select id="selectFunctionLogCount" parameterType="com.fastbee.iot.domain.Device" resultType="Long">
select count(mode) as functionCount
from ${database}.device_log
where log_type=2
<if test="device.tenantId != null"> and tenant_id = #{device.tenantId}</if>
</select>
<select id="selectEventLogCount" parameterType="com.fastbee.iot.domain.Device" resultType="Long">
select count(mode) as eventCount
from ${database}.device_log
where log_type=3
<if test="device.tenantId != null"> and tenant_id = #{device.tenantId}</if>
<if test="device.createBy != null and device.createBy != ''"> AND create_by = #{device.createBy}</if>
</select>
<select id="selectMonitorLogCount" parameterType="com.fastbee.iot.domain.Device" resultType="Long">
select count(mode) as monitorCount
from ${database}.device_log
where log_type=1 and is_monitor=1
<if test="device.tenantId != null"> and tenant_id = #{device.tenantId}</if>
<if test="device.createBy != null and device.createBy != ''"> AND create_by = #{device.createBy}</if>
</select>
<select id="selectMonitorList" parameterType="com.fastbee.iot.domain.DeviceLog" resultMap="MonitorResult">
select log_value, ts from ${database}.device_log
<where>
is_monitor=1
<if test="device.serialNumber != null and device.serialNumber !=''"> and serial_number = #{device.serialNumber}</if>
<if test="device.identify != null and device.identify != ''"> and identify like #{device.identify}</if>
<if test="device.beginTime != null and device.beginTime != '' and device.endTime != null and device.endTime != ''"> and ts between #{device.beginTime} and #{device.endTime}</if>
order by ts desc
limit #{device.total}
</where>
</select>
<select id="selectDeviceLogList" parameterType="com.fastbee.iot.domain.DeviceLog" resultMap="DeviceLogResult">
select * from ${database}.device_log
<where>
<if test="device.isMonitor != null"> and is_monitor = #{device.isMonitor}</if>
<if test="device.serialNumber != null and device.serialNumber !=''"> and serial_number = #{device.serialNumber}</if>
<if test="device.logType != null "> and log_type = #{device.logType}</if>
<if test="device.logType == null "> and log_type != 7</if>
<if test="device.identify != null and device.identify != ''"> and identify like #{device.identify}</if>
</where>
order by ts desc
</select>
<select id="selectEventLogList" parameterType="com.fastbee.iot.domain.DeviceLog" resultMap="DeviceLogResult">
select * from ${database}.device_log
<where>
<if test="device.isMonitor != null"> and is_monitor = #{device.isMonitor}</if>
<if test="device.logType != null "> and log_type = #{device.logType}</if>
<if test="device.logType == null "> and log_type != 1
and log_type != 2
and log_type != 4
and log_type != 7 </if>
<if test="device.serialNumber != null and device.serialNumber !=''"> and serial_number = #{device.serialNumber}</if>
<if test="device.identify != null and device.identify != ''"> and identify like #{device.identify}</if>
<if test="device.beginTime != null and device.beginTime != '' and device.endTime != null and device.endTime != ''">
and ts between #{device.beginTime} and #{device.endTime}
</if>
</where>
order by ts desc
</select>
</mapper>

View File

@@ -170,7 +170,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="status != null and status != ''">#{status},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="remark != null and remark != ''">#{remark},</if>
sysdate()
current_timestamp
)
</insert>
@@ -189,7 +189,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="loginDate != null">login_date = #{loginDate},</if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
<if test="remark != null">remark = #{remark},</if>
update_time = sysdate()
update_time = current_timestamp
</set>
where user_id = #{userId}
</update>