feat(iot): 添加温度异常事件处理功能
- 在 RecordData 实体中添加处理记录数据的方法- 新增 TemperatureExceededEvent 类用于温度异常事件 - 在 DeviceController 中集成事件处理逻辑 - 更新数据库结构,增加参数对比类型和默认值字段 - 优化 Param 实体,添加 CompareType枚举
This commit is contained in:
parent
58a9f08c3b
commit
640e7f5286
@ -1,8 +1,6 @@
|
|||||||
package com.zsc.edu.gateway.framework.message.sse;
|
package com.zsc.edu.gateway.framework.message.sse;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package com.zsc.edu.gateway.modules.iot.device.controller;
|
|||||||
|
|
||||||
import com.alibaba.fastjson2.JSONException;
|
import com.alibaba.fastjson2.JSONException;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.zsc.edu.gateway.framework.message.sse.SseConfig;
|
import com.zsc.edu.gateway.framework.message.sse.SseConfig;
|
||||||
@ -13,15 +12,11 @@ import com.zsc.edu.gateway.modules.iot.device.dto.DeviceServeDto;
|
|||||||
import com.zsc.edu.gateway.modules.iot.device.entity.Device;
|
import com.zsc.edu.gateway.modules.iot.device.entity.Device;
|
||||||
import com.zsc.edu.gateway.modules.iot.device.query.DeviceQuery;
|
import com.zsc.edu.gateway.modules.iot.device.query.DeviceQuery;
|
||||||
import com.zsc.edu.gateway.modules.iot.device.service.DeviceService;
|
import com.zsc.edu.gateway.modules.iot.device.service.DeviceService;
|
||||||
import com.zsc.edu.gateway.modules.iot.device.vo.DeviceStatusVo;
|
|
||||||
import com.zsc.edu.gateway.modules.iot.device.vo.DeviceVo;
|
import com.zsc.edu.gateway.modules.iot.device.vo.DeviceVo;
|
||||||
import com.zsc.edu.gateway.modules.iot.record.entity.DataWarningVo;
|
|
||||||
import com.zsc.edu.gateway.modules.iot.record.entity.RecordData;
|
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.service.RecordDataService;
|
import com.zsc.edu.gateway.modules.iot.record.service.RecordDataService;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.zsc.edu.gateway.modules.iot.record.entity;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author zhuang
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TemperatureExceededEvent extends ApplicationEvent {
|
||||||
|
private final RecordData recordData;
|
||||||
|
private final double reducedParameter;
|
||||||
|
|
||||||
|
public TemperatureExceededEvent(Object source, RecordData recordData, double reducedParameter) {
|
||||||
|
super(source);
|
||||||
|
this.recordData = recordData;
|
||||||
|
this.reducedParameter = reducedParameter;
|
||||||
|
}
|
||||||
|
}
|
@ -5,16 +5,25 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.zsc.edu.gateway.modules.iot.device.entity.Device;
|
||||||
|
import com.zsc.edu.gateway.modules.iot.device.repo.DeviceRepository;
|
||||||
import com.zsc.edu.gateway.modules.iot.record.entity.DataWarningVo;
|
import com.zsc.edu.gateway.modules.iot.record.entity.DataWarningVo;
|
||||||
import com.zsc.edu.gateway.modules.iot.record.entity.RecordData;
|
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.entity.TemperatureExceededEvent;
|
||||||
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.Event;
|
||||||
|
import com.zsc.edu.gateway.modules.iot.tsl.entity.Param;
|
||||||
|
import com.zsc.edu.gateway.modules.iot.tsl.repo.EventRepository;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zhuang
|
* @author zhuang
|
||||||
@ -23,8 +32,12 @@ import java.util.List;
|
|||||||
@Service
|
@Service
|
||||||
public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, RecordData> implements RecordDataService {
|
public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, RecordData> implements RecordDataService {
|
||||||
|
|
||||||
private final RecordDataRepository recordDataRepository;
|
@Resource
|
||||||
|
private final ApplicationEventPublisher eventPublisher;
|
||||||
|
@Resource
|
||||||
|
private final DeviceRepository deviceRepository;
|
||||||
|
@Resource
|
||||||
|
private final EventRepository eventRepository;
|
||||||
@Override
|
@Override
|
||||||
public RecordData recordData(String clientId, JSONObject data) {
|
public RecordData recordData(String clientId, JSONObject data) {
|
||||||
RecordData recordData = new RecordData();
|
RecordData recordData = new RecordData();
|
||||||
@ -32,6 +45,7 @@ public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, Rec
|
|||||||
recordData.setContent(data);
|
recordData.setContent(data);
|
||||||
recordData.setRecordTime(LocalDateTime.now());
|
recordData.setRecordTime(LocalDateTime.now());
|
||||||
baseMapper.insert(recordData);
|
baseMapper.insert(recordData);
|
||||||
|
processRecordData(recordData);
|
||||||
return recordData;
|
return recordData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,6 +78,64 @@ public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, Rec
|
|||||||
public IPage<RecordData> query(Page<RecordData> page, String clientId) {
|
public IPage<RecordData> query(Page<RecordData> page, String clientId) {
|
||||||
LambdaQueryWrapper<RecordData> queryWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<RecordData> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
queryWrapper.eq(RecordData::getClientId, clientId);
|
queryWrapper.eq(RecordData::getClientId, clientId);
|
||||||
return recordDataRepository.selectPage(page, queryWrapper);
|
return baseMapper.selectPage(page, queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processRecordData(RecordData recordData) {
|
||||||
|
// 根据 clientId 查询设备信息
|
||||||
|
Device device = deviceRepository.selectOne(new LambdaQueryWrapper<Device>().eq(Device::getClientId, recordData.getClientId()));
|
||||||
|
|
||||||
|
// 获取产品下的所有事件
|
||||||
|
List<Event> events = eventRepository.selectList(new LambdaQueryWrapper<Event>().eq(Event::getProductId, device.getProductId()));
|
||||||
|
|
||||||
|
// 遍历每个事件
|
||||||
|
for (Event event : events) {
|
||||||
|
// 遍历事件的 outputs 列表中的每个参数
|
||||||
|
event.getOutputs().forEach(param -> {
|
||||||
|
processParam(recordData, param);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void processParam(RecordData recordData, Param param) {
|
||||||
|
// 获取参数的默认值和比较类型
|
||||||
|
Double defaultValue = param.getDefaultValue();
|
||||||
|
Param.CompareType compareType = param.getCompareType();
|
||||||
|
String identifier = param.getIdentifier();
|
||||||
|
|
||||||
|
// 检查 recordData 的内容中是否包含该参数的标识符
|
||||||
|
if (recordData.getContent().get(identifier) != null) {
|
||||||
|
try {
|
||||||
|
// 获取参数的实际值
|
||||||
|
double value = Double.parseDouble(recordData.getContent().get(identifier).toString());
|
||||||
|
|
||||||
|
// 根据比较类型进行不同的处理
|
||||||
|
switch (compareType) {
|
||||||
|
case GT:
|
||||||
|
if (value > defaultValue) {
|
||||||
|
eventPublisher.publishEvent(new TemperatureExceededEvent(this, recordData, value));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LT:
|
||||||
|
if (value < defaultValue) {
|
||||||
|
eventPublisher.publishEvent(new TemperatureExceededEvent(this, recordData, value));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EQ:
|
||||||
|
if (value == defaultValue) {
|
||||||
|
eventPublisher.publishEvent(new TemperatureExceededEvent(this, recordData, value));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 处理未知的比较类型
|
||||||
|
System.err.println("Unknown compare type: " + compareType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// 处理数值转换异常
|
||||||
|
System.err.println("Failed to parse value for identifier: " + identifier + ". Error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -44,6 +44,16 @@ public class Param extends BaseParam {
|
|||||||
*/
|
*/
|
||||||
private Long foreignId;
|
private Long foreignId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对比类型
|
||||||
|
*/
|
||||||
|
private CompareType compareType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认数值
|
||||||
|
*/
|
||||||
|
private Double defaultValue;
|
||||||
|
|
||||||
public enum Type implements IEnum<String>, IState<Type> {
|
public enum Type implements IEnum<String>, IState<Type> {
|
||||||
/**
|
/**
|
||||||
* 物模型输入
|
* 物模型输入
|
||||||
@ -109,4 +119,36 @@ public class Param extends BaseParam {
|
|||||||
return this.description;
|
return this.description;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum CompareType implements IEnum<Integer>, IState<CompareType> {
|
||||||
|
/**
|
||||||
|
* 大于
|
||||||
|
*/
|
||||||
|
GT(1, ">"),
|
||||||
|
/**
|
||||||
|
* 小于
|
||||||
|
*/
|
||||||
|
LT(2, "<"),
|
||||||
|
/**
|
||||||
|
* 等于
|
||||||
|
*/
|
||||||
|
EQ(3, "=");
|
||||||
|
private final int value;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
CompareType(int value, String description) {
|
||||||
|
this.value = value;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.description;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,10 @@ import com.zsc.edu.gateway.modules.iot.tsl.mapper.EventMapper;
|
|||||||
import com.zsc.edu.gateway.modules.iot.tsl.repo.EventRepository;
|
import com.zsc.edu.gateway.modules.iot.tsl.repo.EventRepository;
|
||||||
import com.zsc.edu.gateway.modules.iot.tsl.service.EventService;
|
import com.zsc.edu.gateway.modules.iot.tsl.service.EventService;
|
||||||
import com.zsc.edu.gateway.modules.iot.tsl.service.ParamService;
|
import com.zsc.edu.gateway.modules.iot.tsl.service.ParamService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@ -934,5 +934,10 @@ ALTER TABLE iot_device
|
|||||||
ALTER COLUMN longitude SET DEFAULT 113.39,
|
ALTER COLUMN longitude SET DEFAULT 113.39,
|
||||||
ALTER COLUMN latitude SET DEFAULT 22.52;
|
ALTER COLUMN latitude SET DEFAULT 22.52;
|
||||||
|
|
||||||
|
ALTER TABLE iot_param
|
||||||
|
ALTER COLUMN contrast_type SET DEFAULT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE iot_param
|
||||||
|
ALTER COLUMN "default_value " SET DEFAULT NULL;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
create table iot_param
|
create table iot_param
|
||||||
(
|
(
|
||||||
id bigserial not null
|
id bigint generated by default as identity
|
||||||
constraint iot_param_name_pk
|
constraint iot_param_name_pk
|
||||||
primary key,
|
primary key,
|
||||||
data_type integer,
|
data_type integer,
|
||||||
uint varchar,
|
uint varchar,
|
||||||
type integer,
|
type varchar,
|
||||||
identifier varchar,
|
identifier varchar,
|
||||||
name varchar,
|
name varchar,
|
||||||
remark varchar
|
remark varchar,
|
||||||
|
foreign_id bigint,
|
||||||
|
foreign_type integer,
|
||||||
|
dept_id bigint,
|
||||||
|
create_id bigint,
|
||||||
|
contrast_type integer,
|
||||||
|
"default_value " double precision
|
||||||
);
|
);
|
||||||
|
|
||||||
comment on table iot_param is '参数';
|
comment on table iot_param is '参数';
|
||||||
@ -27,6 +33,18 @@ comment on column iot_param.name is '名称';
|
|||||||
|
|
||||||
comment on column iot_param.remark is '备注';
|
comment on column iot_param.remark is '备注';
|
||||||
|
|
||||||
|
comment on column iot_param.foreign_id is '联表id';
|
||||||
|
|
||||||
|
comment on column iot_param.foreign_type is '关联类型';
|
||||||
|
|
||||||
|
comment on column iot_param.dept_id is '部门权限id';
|
||||||
|
|
||||||
|
comment on column iot_param.create_id is '创建人id';
|
||||||
|
|
||||||
|
comment on column iot_param.contrast_type is '对比类型';
|
||||||
|
|
||||||
|
comment on column iot_param."default_value " is '默认数值';
|
||||||
|
|
||||||
alter table iot_param
|
alter table iot_param
|
||||||
owner to gitea;
|
owner to gitea;
|
||||||
|
|
||||||
|
@ -60,9 +60,9 @@ public class ParamServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createParams() {
|
void createParams() {
|
||||||
ParamDto dto = new ParamDto("PARAM_NAME_3", "测试1", "备注", DataType.DATE, Param.Type.OUTPUT);
|
// ParamDto dto = new ParamDto("PARAM_NAME_3", "测试1", "备注", DataType.DATE, Param.Type.OUTPUT);
|
||||||
List<ParamDto> params = new ArrayList<>();
|
List<ParamDto> params = new ArrayList<>();
|
||||||
params.add(dto);
|
// params.add(dto);
|
||||||
Long foreignId = 1L;
|
Long foreignId = 1L;
|
||||||
Boolean result = service.create(params, foreignId, null);
|
Boolean result = service.create(params, foreignId, null);
|
||||||
assertTrue(result);
|
assertTrue(result);
|
||||||
|
Loading…
Reference in New Issue
Block a user