feat(iot): 添加设备状态监控和地理坐标属性

- 在 Device 模型中添加 deviceState 字段,用于表示设备运行状态- 在 DeviceDto 中添加 longitude 和 latitude 字段,用于表示设备经纬度
- 修改 RecordDataServiceImpl 中的数据处理逻辑,增加设备状态更新
- 在数据库中添加相关字段和默认值设置
This commit is contained in:
zhuangtianxiang 2025-03-24 17:29:25 +08:00
parent 4aa7567b93
commit a8beca1640
7 changed files with 57 additions and 12 deletions

View File

@ -64,5 +64,14 @@ public class DeviceDto {
*/ */
public String previewId; public String previewId;
/**
* 设备经度
*/
public Double longitude;
/**
* 设备纬度
*/
public Double latitude;
} }

View File

@ -121,7 +121,11 @@ public class Device extends BaseEntity {
* 设备预览图附件ID * 设备预览图附件ID
*/ */
public String previewId; public String previewId;
//TODO 设备运行状态
/**
* 设备是否正常运行
*/
public Boolean deviceState;
public enum Status implements IEnum<Integer>, IState<Status> { public enum Status implements IEnum<Integer>, IState<Status> {
UNACTIVATED(0, "未激活"), UNACTIVATED(0, "未激活"),
@ -147,5 +151,6 @@ public class Device extends BaseEntity {
return this.description; return this.description;
} }
} }
} }

View File

@ -3,6 +3,7 @@ package com.zsc.edu.gateway.modules.iot.record.service.impl;
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.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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;
@ -36,8 +37,6 @@ import java.util.List;
@Service @Service
public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, RecordData> implements RecordDataService { public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, RecordData> implements RecordDataService {
@Resource
private final ApplicationEventPublisher eventPublisher;
@Resource @Resource
private final DeviceRepository deviceRepository; private final DeviceRepository deviceRepository;
@Resource @Resource
@ -60,7 +59,10 @@ public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, Rec
recordData.setContent(data); recordData.setContent(data);
recordData.setRecordTime(LocalDateTime.now()); recordData.setRecordTime(LocalDateTime.now());
this.save(recordData); this.save(recordData);
processRecordData(recordData);
boolean isProcessed = processRecordData(recordData);
updateDeviceState(clientId, !isProcessed);
return recordData; return recordData;
} }
@ -95,13 +97,15 @@ public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, Rec
/** /**
* 监控上报数据 * 监控上报数据
*
* @param recordData 上报数据 * @param recordData 上报数据
* @return
*/ */
public void processRecordData(RecordData recordData) { public boolean processRecordData(RecordData recordData) {
// 根据 clientId 查询设备信息 // 根据 clientId 查询设备信息
Device device = deviceRepository.findByClientId(recordData.getClientId()); Device device = deviceRepository.findByClientId(recordData.getClientId());
if (device == null) { if (device == null) {
return; // 如果设备不存在直接返回 return false;
} }
// 获取产品下的所有事件 // 获取产品下的所有事件
@ -110,11 +114,24 @@ public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, Rec
throw new JSONException("该设备下事件并未启用!或者该设备下无定义事件!"); throw new JSONException("该设备下事件并未启用!或者该设备下无定义事件!");
} }
boolean processed = false;
// 遍历每个事件 // 遍历每个事件
for (Event event : events) { for (Event event : events) {
event.getOutputs().forEach(param -> processParam(recordData, param, event)); for (CompareParam param : event.getOutputs()) {
boolean isProcessed = processParam(recordData, param, event);
if (isProcessed) {
processed = true;
break; // 找到并处理完第一个参数后跳出内层循环
} }
} }
if (processed) {
break; // 如果已经处理过参数跳出外层循环
}
}
return processed;
}
/** /**
* 处理数据 * 处理数据
@ -123,11 +140,11 @@ public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, Rec
* @param param 属性 * @param param 属性
* @param event 事件 * @param event 事件
*/ */
private void processParam(RecordData recordData, CompareParam param, Event event) { private boolean processParam(RecordData recordData, CompareParam param, Event event) {
String identifier = param.getIdentifier(); String identifier = param.getIdentifier();
Object valueObj = recordData.getContent().get(identifier); Object valueObj = recordData.getContent().get(identifier);
if (valueObj == null) { if (valueObj == null) {
return; throw new JSONException("上报数据中未找到属性:" + identifier);
} }
DataType dataType = param.getDataType(); DataType dataType = param.getDataType();
String defaultValueStr = param.getDefaultValue(); String defaultValueStr = param.getDefaultValue();
@ -139,7 +156,7 @@ public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, Rec
defaultValue = ((Boolean) defaultValue) ? 1 : 0; defaultValue = ((Boolean) defaultValue) ? 1 : 0;
} }
//进行监控 //进行监控
processComparison(recordData, param, event, (Number) defaultValue, (Number) value); return processComparison(recordData, param, event, (Number) defaultValue, (Number) value);
} }
/** /**
@ -158,7 +175,7 @@ public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, Rec
/** /**
* 判断数值进行监控 * 判断数值进行监控
*/ */
private void processComparison(RecordData recordData, CompareParam param, Event event, Number defaultValue, Number value) { private boolean processComparison(RecordData recordData, CompareParam param, Event event, Number defaultValue, Number value) {
CompareParam.CompareType compareType = param.getCompareType(); CompareParam.CompareType compareType = param.getCompareType();
boolean result = switch (compareType) { boolean result = switch (compareType) {
case GT -> value.doubleValue() > defaultValue.doubleValue(); case GT -> value.doubleValue() > defaultValue.doubleValue();
@ -169,7 +186,14 @@ public class RecordDataServiceImpl extends ServiceImpl<RecordDataRepository, Rec
}; };
if (result) { if (result) {
eventLogRepository.insert(new EventLog(null, event.getName(), recordData.getId(), recordData, LocalDateTime.now(), null, null)); eventLogRepository.insert(new EventLog(null, event.getName(), recordData.getId(), recordData, LocalDateTime.now(), null, null));
return true;
} }
return false;
} }
private void updateDeviceState(String clientId, boolean isDeviceState) {
deviceRepository.update(new LambdaUpdateWrapper<Device>()
.eq(Device::getClientId, clientId)
.set(Device::getDeviceState, isDeviceState));
}
} }

View File

@ -79,7 +79,7 @@ public class EventController {
public IPage<EventLog> eventLogPage(Page<EventLog> page, @PathVariable("clientId") String clientId) { public IPage<EventLog> eventLogPage(Page<EventLog> page, @PathVariable("clientId") String clientId) {
return eventLogRepository.selectPage(page, new LambdaQueryWrapper<EventLog>().eq(EventLog::getRecordId, clientId)); return eventLogRepository.selectPage(page, new LambdaQueryWrapper<EventLog>().eq(EventLog::getRecordId, clientId));
} }
//TODO 详情接口
/** /**
* 删除事件 * 删除事件

View File

@ -11,4 +11,5 @@ public interface EventLogRepository extends BaseMapper<EventLog> {
@Select("select * from iot_event_log where client_id=#{clientId}") @Select("select * from iot_event_log where client_id=#{clientId}")
List<EventLog> selectByClientId(@Param("clientId") String clientId); List<EventLog> selectByClientId(@Param("clientId") String clientId);
} }

View File

@ -943,3 +943,8 @@ ALTER TABLE iot_param
ALTER TABLE iot_param ALTER TABLE iot_param
ADD COLUMN default_value DOUBLE PRECISION; ADD COLUMN default_value DOUBLE PRECISION;
ALTER TABLE iot_event
ALTER COLUMN enabled SET DEFAULT true;

View File

@ -23,4 +23,5 @@
iot_record_data ird iot_record_data ird
where iel.record_id = ird.id where iel.record_id = ird.id
</select> </select>
</mapper> </mapper>