feat(iot): 优化设备和事件相关功能

- 修改设备默认在线状态为 true
-增加设备名称模糊查询功能- 更新事件相关数据库结构和接口
- 优化参数比较逻辑,支持不同数据类型
This commit is contained in:
zhuangtianxiang 2025-03-18 22:15:38 +08:00
parent 247a4b58fd
commit a1a089583f
26 changed files with 183 additions and 42 deletions

View File

@ -84,6 +84,16 @@ public class DeviceController {
return service.query(page, query); return service.query(page, query);
} }
/**
* 根据名字模糊查询
*/
@DataPermission
@GetMapping("/list")
@PreAuthorize("hasAuthority('iot:device:query')")
public List<Device> findByName(String name) {
return service.findByName(name);
}
/** /**
* 删除设备 * 删除设备
*/ */

View File

@ -35,7 +35,7 @@ public class Device extends BaseEntity {
/** /**
* 设备是否在线默认在线 * 设备是否在线默认在线
*/ */
private Boolean online = false; private Boolean online = true;
/** /**
* 设备状态 * 设备状态

View File

@ -34,4 +34,6 @@ public interface DeviceService extends IService<Device> {
DeviceStatusVo status(); DeviceStatusVo status();
String send(Long deviceId, Integer qos, JSONObject paras) throws JSONException; String send(Long deviceId, Integer qos, JSONObject paras) throws JSONException;
List<Device> findByName(String name);
} }

View File

@ -222,4 +222,13 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceRepository, Device> imp
return payload; return payload;
} }
/**
* 根据名称获取设备列表
*/
@Override
public List<Device> findByName(String name) {
LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(Device::getName, name);
return baseMapper.selectList(queryWrapper);
}
} }

View File

@ -1,5 +1,7 @@
package com.zsc.edu.gateway.modules.iot.product.dto; package com.zsc.edu.gateway.modules.iot.product.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.zsc.edu.gateway.modules.attachment.entity.Attachment;
import com.zsc.edu.gateway.modules.iot.product.entity.Product; import com.zsc.edu.gateway.modules.iot.product.entity.Product;
import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto; import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -51,4 +53,15 @@ public class ProductDto {
* 说明 * 说明
*/ */
public String remark; public String remark;
/**
* 产品图标附件ID
*/
public String iconId;
/**
* 产品预览图附件ID
*/
public String previewId;
} }

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.zsc.edu.gateway.common.enums.IState; import com.zsc.edu.gateway.common.enums.IState;
import com.zsc.edu.gateway.modules.attachment.entity.Attachment;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Param; import com.zsc.edu.gateway.modules.iot.tsl.entity.Param;
import com.zsc.edu.gateway.modules.system.entity.BaseEntity; import com.zsc.edu.gateway.modules.system.entity.BaseEntity;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -61,6 +62,28 @@ public class Product extends BaseEntity {
*/ */
private Boolean enabled = true; private Boolean enabled = true;
/**
* 产品图标附件ID
*/
public String iconId;
/**
* 产品图标附件
*/
@TableField(exist = false)
public Attachment icon;
/**
* 产品预览图附件ID
*/
public String previewId;
/**
* 产品预览图附件
*/
@TableField(exist = false)
public Attachment preview;
/** /**
* 接入方式 * 接入方式
*/ */

View File

@ -11,6 +11,7 @@ import com.zsc.edu.gateway.modules.iot.record.entity.RecordData;
import com.zsc.edu.gateway.modules.iot.record.entity.RecordDataStatusVo; import com.zsc.edu.gateway.modules.iot.record.entity.RecordDataStatusVo;
import com.zsc.edu.gateway.modules.iot.record.repo.RecordDataRepository; import com.zsc.edu.gateway.modules.iot.record.repo.RecordDataRepository;
import com.zsc.edu.gateway.modules.iot.record.service.RecordDataService; import com.zsc.edu.gateway.modules.iot.record.service.RecordDataService;
import com.zsc.edu.gateway.modules.iot.tsl.entity.DataType;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Event; import com.zsc.edu.gateway.modules.iot.tsl.entity.Event;
import com.zsc.edu.gateway.modules.iot.tsl.entity.EventLog; import com.zsc.edu.gateway.modules.iot.tsl.entity.EventLog;
import com.zsc.edu.gateway.modules.iot.tsl.entity.CompareParam; import com.zsc.edu.gateway.modules.iot.tsl.entity.CompareParam;
@ -24,11 +25,9 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
/** /**
*上报数据 * 上报数据
* *
* @author zhuang * @author zhuang
*/ */
@ -80,7 +79,6 @@ public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, Rec
.build(); .build();
} }
/** /**
* 查询上报数据 * 查询上报数据
* @param page 分页数据 * @param page 分页数据
@ -106,7 +104,7 @@ public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, Rec
} }
// 获取产品下的所有事件 // 获取产品下的所有事件
List<Event> events = eventRepository.selectByProductId(device.getProductId(),true); List<Event> events = eventRepository.selectByProductId(device.getProductId(), true);
if (events.isEmpty()) { if (events.isEmpty()) {
return; // 如果没有事件直接返回 return; // 如果没有事件直接返回
} }
@ -125,34 +123,51 @@ public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, Rec
* @param event 事件 * @param event 事件
*/ */
private void processParam(RecordData recordData, CompareParam param, Event event) { private void processParam(RecordData recordData, CompareParam param, Event event) {
// 获取参数的默认值和比较类型
double defaultValue = Double.parseDouble(param.getDefaultValue());
String identifier = param.getIdentifier(); String identifier = param.getIdentifier();
// 检查 recordData 的内容中是否包含该参数的标识符
Object valueObj = recordData.getContent().get(identifier); Object valueObj = recordData.getContent().get(identifier);
if (valueObj != null) { if (valueObj == null) {
// 获取参数的实际值 return;
double value = Double.parseDouble(valueObj.toString()); }
CompareParam.CompareType compareType = param.getCompareType(); DataType dataType = param.getDataType();
String defaultValueStr = param.getDefaultValue();
Object value = convertValue(valueObj.toString(), dataType);
Object defaultValue = convertValue(defaultValueStr, dataType);
//判断数值类型
if (dataType == DataType.BOOLEAN) {
value = ((Boolean) value) ? 1 : 0;
defaultValue = ((Boolean) defaultValue) ? 1 : 0;
}
//进行监控
processComparison(recordData, param, event, (Number) defaultValue, (Number) value);
}
Predicate<Double> comparison = switch (compareType) { /**
case GT -> v -> v > defaultValue; * 转换数值
case LT -> v -> v < defaultValue; */
case EQ -> v -> v == defaultValue; private Object convertValue(String value, DataType dataType) {
case GE -> v -> v >= defaultValue; return switch (dataType) {
case LE -> v -> v <= defaultValue; case INT -> Integer.parseInt(value);
}; case FLOAT -> Float.parseFloat(value);
case DOUBLE -> Double.parseDouble(value);
case BOOLEAN -> Boolean.parseBoolean(value);
default -> throw new IllegalArgumentException("Unsupported data type: " + dataType);
};
}
// 定义插入日志的 Consumer /**
Consumer<Double> logInsertion = v -> { * 判断数值进行监控
if (comparison.test(v)) { */
eventLogRepository.insert(new EventLog(null, event.getName(), recordData.getId(), recordData, LocalDateTime.now(), null, null)); private void processComparison(RecordData recordData, CompareParam param, Event event, Number defaultValue, Number value) {
} CompareParam.CompareType compareType = param.getCompareType();
}; boolean result = switch (compareType) {
case GT -> value.doubleValue() > defaultValue.doubleValue();
// 执行比较和日志插入 case LT -> value.doubleValue() < defaultValue.doubleValue();
logInsertion.accept(value); case EQ -> value.doubleValue() == defaultValue.doubleValue();
case GE -> value.doubleValue() >= defaultValue.doubleValue();
case LE -> value.doubleValue() <= defaultValue.doubleValue();
};
if (result) {
eventLogRepository.insert(new EventLog(null, event.getName(), recordData.getId(), recordData, LocalDateTime.now(), null, null));
} }
} }

View File

@ -29,6 +29,6 @@ public class ParamDto {
private CompareParam.CompareType compareType; private CompareParam.CompareType compareType;
private Double defaultValue; private String defaultValue;
} }

View File

@ -69,5 +69,4 @@ public class CompareParam extends Param {
return this.description; return this.description;
} }
} }
} }

View File

@ -34,7 +34,7 @@ public class Event extends BaseParam {
/** /**
* 是否启用服务 * 是否启用服务
*/ */
private Boolean enabled; private Boolean enabled = true;
/** /**
* 服务输出的参数 * 服务输出的参数

View File

@ -0,0 +1,14 @@
package com.zsc.edu.gateway.modules.iot.tsl.mapper;
import com.zsc.edu.gateway.common.mapstruct.BaseMapper;
import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto;
import com.zsc.edu.gateway.modules.iot.tsl.entity.CompareParam;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author zhuang
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface CompareParamMapper extends BaseMapper<ParamDto, CompareParam> {
}

View File

@ -0,0 +1,7 @@
package com.zsc.edu.gateway.modules.iot.tsl.repo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zsc.edu.gateway.modules.iot.tsl.entity.CompareParam;
public interface CompareParamRepository extends BaseMapper<CompareParam> {
}

View File

@ -1,6 +1,7 @@
package com.zsc.edu.gateway.modules.iot.tsl.repo; package com.zsc.edu.gateway.modules.iot.tsl.repo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zsc.edu.gateway.modules.iot.tsl.entity.CompareParam;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Param; import com.zsc.edu.gateway.modules.iot.tsl.entity.Param;
/** /**

View File

@ -3,6 +3,7 @@ package com.zsc.edu.gateway.modules.iot.tsl.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto; import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Param; import com.zsc.edu.gateway.modules.iot.tsl.entity.Param;
import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.List;
@ -13,6 +14,8 @@ public interface ParamService extends IService<Param> {
Boolean create(List<ParamDto> params, Long id, Param.ForeignType foreignType); Boolean create(List<ParamDto> params, Long id, Param.ForeignType foreignType);
Boolean createCompareParam(List<ParamDto> params, Long id, Param.ForeignType foreignType);
Boolean update(List<ParamDto> paramDto, Long id); Boolean update(List<ParamDto> paramDto, Long id);
Boolean delete(Long id); Boolean delete(Long id);

View File

@ -36,7 +36,7 @@ public class EventServiceImpl extends ServiceImpl<EventRepository, Event> implem
} }
Event event = mapper.toEntity(dto); Event event = mapper.toEntity(dto);
save(event); save(event);
paramService.create(dto.getOutputs(), event.getId(), Param.ForeignType.EVENT); paramService.createCompareParam(dto.getOutputs(), event.getId(), Param.ForeignType.EVENT);
return event; return event;
} }
/** /**

View File

@ -3,8 +3,11 @@ package com.zsc.edu.gateway.modules.iot.tsl.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto; import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto;
import com.zsc.edu.gateway.modules.iot.tsl.entity.CompareParam;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Param; import com.zsc.edu.gateway.modules.iot.tsl.entity.Param;
import com.zsc.edu.gateway.modules.iot.tsl.mapper.CompareParamMapper;
import com.zsc.edu.gateway.modules.iot.tsl.mapper.ParamMapper; import com.zsc.edu.gateway.modules.iot.tsl.mapper.ParamMapper;
import com.zsc.edu.gateway.modules.iot.tsl.repo.CompareParamRepository;
import com.zsc.edu.gateway.modules.iot.tsl.repo.ParamRepository; import com.zsc.edu.gateway.modules.iot.tsl.repo.ParamRepository;
import com.zsc.edu.gateway.modules.iot.tsl.service.ParamService; import com.zsc.edu.gateway.modules.iot.tsl.service.ParamService;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -24,6 +27,8 @@ import java.util.stream.IntStream;
public class ParamServiceImpl extends ServiceImpl<ParamRepository, Param> implements ParamService { public class ParamServiceImpl extends ServiceImpl<ParamRepository, Param> implements ParamService {
private final ParamMapper mapper; private final ParamMapper mapper;
private final ParamMapper paramMapper; private final ParamMapper paramMapper;
private final CompareParamMapper compareParamMapper;
private final CompareParamRepository compareParamRepository;
@Override @Override
@Transactional @Transactional
public Boolean create(List<ParamDto> params, Long id, Param.ForeignType foreignType) { public Boolean create(List<ParamDto> params, Long id, Param.ForeignType foreignType) {
@ -39,6 +44,21 @@ public class ParamServiceImpl extends ServiceImpl<ParamRepository, Param> implem
return true; return true;
} }
@Override
@Transactional
public Boolean createCompareParam(List<ParamDto> params, Long id, Param.ForeignType foreignType) {
List<CompareParam> paramsToInsert = params.stream()
.map(dto -> {
CompareParam param = compareParamMapper.toEntity(dto);
param.setForeignId(id);
param.setForeignType(foreignType);
return param;
})
.collect(Collectors.toList());
compareParamRepository.insert(paramsToInsert);
return true;
}
@Override @Override
@Transactional @Transactional
public Boolean update(List<ParamDto> paramDto, Long id) { public Boolean update(List<ParamDto> paramDto, Long id) {

View File

@ -59,7 +59,7 @@ jwt:
expiration: 3600 expiration: 3600
gatherer: gatherer:
version: 123 version: 987
mqtt: mqtt:
username: you_mqtt_username username: you_mqtt_username

View File

@ -1,14 +1,16 @@
create table iot_event create table iot_event
( (
id bigint not null id bigint generated by default as identity
constraint iot_event_pk constraint iot_event_pk
primary key, primary key,
product_id bigint, product_id bigint,
type integer, type varchar,
identifier varchar, identifier varchar,
name varchar, name varchar,
remark varchar, remark varchar,
dept_id bigint dept_id bigint,
create_id bigint,
enabled boolean
); );
comment on table iot_event is '物模型服务'; comment on table iot_event is '物模型服务';
@ -27,6 +29,10 @@ comment on column iot_event.remark is '备注';
comment on column iot_event.dept_id is '部门权限id'; comment on column iot_event.dept_id is '部门权限id';
comment on column iot_event.create_id is '创建人id';
comment on column iot_event.enabled is '是否启用';
alter table iot_event alter table iot_event
owner to gitea; owner to gitea;

View File

@ -17,6 +17,20 @@
<result column="remark" jdbcType="VARCHAR" property="remark"/> <result column="remark" jdbcType="VARCHAR" property="remark"/>
<result column="create_id" jdbcType="BIGINT" property="createId"/> <result column="create_id" jdbcType="BIGINT" property="createId"/>
<result column="enabled" jdbcType="BOOLEAN" property="enabled"/> <result column="enabled" jdbcType="BOOLEAN" property="enabled"/>
<result column="icon_id" jdbcType="VARCHAR" property="iconId"/>
<result column="preview_id" jdbcType="VARCHAR" property="previewId"/>
<association property="icon" javaType="com.zsc.edu.gateway.modules.attachment.entity.Attachment"
autoMapping="true"
columnPrefix="icon_">
<id column="id" property="id"/>
<result column="file_name" property="fileName"/>
</association>
<association property="preview" javaType="com.zsc.edu.gateway.modules.attachment.entity.Attachment"
autoMapping="true"
columnPrefix="preview_">
<id column="id" property="id"/>
<result column="file_name" property="fileName"/>
</association>
<collection property="params" ofType="com.zsc.edu.gateway.modules.iot.tsl.entity.Param" autoMapping="true" <collection property="params" ofType="com.zsc.edu.gateway.modules.iot.tsl.entity.Param" autoMapping="true"
columnPrefix="param_"> columnPrefix="param_">
<id column="id" property="id"/> <id column="id" property="id"/>
@ -39,10 +53,15 @@
ip.type as param_type, ip.type as param_type,
ip.identifier as param_identifier, ip.identifier as param_identifier,
ip.name as param_name, ip.name as param_name,
ip.remark as param_remark ip.remark as param_remark,
ai.id as icon_id,
ai.file_name as icon_file_name,
ap.file_name as preview_file_name,
ap.id as preview_id
from iot_product p from iot_product p
left join iot_param ip on p.id = ip.foreign_id left join iot_param ip on p.id = ip.foreign_id and ip.foreign_type = 3
and ip.foreign_type = 3 left join attachment ai on p.icon_id = ai.id
left join attachment ap on p.preview_id = ap.id
where p.id = #{id} where p.id = #{id}
</select> </select>
</mapper> </mapper>

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
storage/temp/1057467817600 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
storage/temp/1880201683900 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
storage/temp/1918234931000 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
storage/temp/4249475669499 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
storage/temp/966226913100 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB