Commit 83481083 by 汪志阳

Merge branch 'fix_sleep' into dev

parents 1d7be20b 43732a0c
...@@ -12,6 +12,7 @@ import com.makeit.global.annotation.AuthIgnore; ...@@ -12,6 +12,7 @@ import com.makeit.global.annotation.AuthIgnore;
import com.makeit.global.aspect.tenant.TenantIdIgnore; import com.makeit.global.aspect.tenant.TenantIdIgnore;
import com.makeit.service.platform.device.PlatDeviceService; import com.makeit.service.platform.device.PlatDeviceService;
import com.makeit.service.platform.elder.*; import com.makeit.service.platform.elder.*;
import com.makeit.vo.platform.elder.wakeUpAnalysisVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -90,6 +91,7 @@ public class PlatElderSleepController { ...@@ -90,6 +91,7 @@ public class PlatElderSleepController {
@ApiOperation("测试") @ApiOperation("测试")
@PostMapping("test5") @PostMapping("test5")
@AuthIgnore @AuthIgnore
@TenantIdIgnore
public ApiResponseEntity<Void> coordinateRecordTask() { public ApiResponseEntity<Void> coordinateRecordTask() {
platElderCoordinateRecordService.coordinateRecordTask(); platElderCoordinateRecordService.coordinateRecordTask();
return ApiResponseUtils.success(); return ApiResponseUtils.success();
...@@ -150,5 +152,14 @@ public class PlatElderSleepController { ...@@ -150,5 +152,14 @@ public class PlatElderSleepController {
huiNengService.bodyAlarm("1712384736845950978","219A04X1856F6D8",jsonObject); huiNengService.bodyAlarm("1712384736845950978","219A04X1856F6D8",jsonObject);
return ApiResponseUtils.success(); return ApiResponseUtils.success();
} }
@ApiOperation("起床测试")
@GetMapping("getup")
@AuthIgnore
@TenantIdIgnore
public ApiResponseEntity<List<wakeUpAnalysisVO>> elderGetUpAnalysisTask(@RequestParam Integer month,
@RequestParam Integer day) {
return ApiResponseUtils.success(platElderBreatheAnalysisService.elderGetUpAnalysisTask(month, day));
}
} }
...@@ -2,6 +2,7 @@ package com.makeit.service.platform.elder; ...@@ -2,6 +2,7 @@ package com.makeit.service.platform.elder;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.makeit.entity.platform.elder.PlatElderBreatheAnalysis; import com.makeit.entity.platform.elder.PlatElderBreatheAnalysis;
import com.makeit.vo.platform.elder.wakeUpAnalysisVO;
import java.util.List; import java.util.List;
...@@ -16,4 +17,6 @@ import java.util.List; ...@@ -16,4 +17,6 @@ import java.util.List;
public interface PlatElderBreatheAnalysisService extends IService<PlatElderBreatheAnalysis> { public interface PlatElderBreatheAnalysisService extends IService<PlatElderBreatheAnalysis> {
List<PlatElderBreatheAnalysis> elderHeartRespiratoryAnalysisTask(Integer month, Integer day); List<PlatElderBreatheAnalysis> elderHeartRespiratoryAnalysisTask(Integer month, Integer day);
List<wakeUpAnalysisVO> elderGetUpAnalysisTask(Integer month, Integer day);
} }
...@@ -23,4 +23,6 @@ public interface PlatElderSleepService extends IService<PlatElderSleep> { ...@@ -23,4 +23,6 @@ public interface PlatElderSleepService extends IService<PlatElderSleep> {
String calculateScores(long daySleepTime, long dayRestTime, long deepTime, long soberTime, long lightTime, String calculateScores(long daySleepTime, long dayRestTime, long deepTime, long soberTime, long lightTime,
SaasSleepEvaluateStandardReport evaluateStandardReport); SaasSleepEvaluateStandardReport evaluateStandardReport);
List<PlatElderSleep> mergeWakeUpList(List<PlatElderSleep> elderSleepList, int riseRepeatThreshold);
} }
...@@ -13,6 +13,7 @@ import com.makeit.entity.platform.device.PlatDevice; ...@@ -13,6 +13,7 @@ import com.makeit.entity.platform.device.PlatDevice;
import com.makeit.entity.platform.elder.PlatElder; import com.makeit.entity.platform.elder.PlatElder;
import com.makeit.entity.platform.elder.PlatElderBreatheAnalysis; import com.makeit.entity.platform.elder.PlatElderBreatheAnalysis;
import com.makeit.entity.platform.elder.PlatElderBreatheDayStat; import com.makeit.entity.platform.elder.PlatElderBreatheDayStat;
import com.makeit.entity.platform.elder.PlatElderSleep;
import com.makeit.entity.saas.analysis.SaasDiseaseEvaluateReport; import com.makeit.entity.saas.analysis.SaasDiseaseEvaluateReport;
import com.makeit.entity.saas.analysis.SaasDiseaseModel; import com.makeit.entity.saas.analysis.SaasDiseaseModel;
import com.makeit.entity.saas.analysis.SaasSleepAnalysisModel; import com.makeit.entity.saas.analysis.SaasSleepAnalysisModel;
...@@ -23,10 +24,7 @@ import com.makeit.module.iot.vo.DeviceOperationLogEntity; ...@@ -23,10 +24,7 @@ import com.makeit.module.iot.vo.DeviceOperationLogEntity;
import com.makeit.module.iot.vo.analysis.DiseaseReportVO; import com.makeit.module.iot.vo.analysis.DiseaseReportVO;
import com.makeit.module.iot.vo.analysis.EvaluateReportVO; import com.makeit.module.iot.vo.analysis.EvaluateReportVO;
import com.makeit.module.iot.vo.breathe.DeviceInfoContentBreathe; import com.makeit.module.iot.vo.breathe.DeviceInfoContentBreathe;
import com.makeit.service.platform.elder.PlatElderBreatheAnalysisService; import com.makeit.service.platform.elder.*;
import com.makeit.service.platform.elder.PlatElderBreatheDayStatService;
import com.makeit.service.platform.elder.PlatElderRealTimeService;
import com.makeit.service.platform.elder.PlatElderService;
import com.makeit.service.saas.SaasDiseaseEvaluateReportService; import com.makeit.service.saas.SaasDiseaseEvaluateReportService;
import com.makeit.service.saas.SaasDiseaseModelService; import com.makeit.service.saas.SaasDiseaseModelService;
import com.makeit.service.saas.SaasDiseaseReportService; import com.makeit.service.saas.SaasDiseaseReportService;
...@@ -34,6 +32,7 @@ import com.makeit.service.saas.SaasSleepAnalysisModelService; ...@@ -34,6 +32,7 @@ import com.makeit.service.saas.SaasSleepAnalysisModelService;
import com.makeit.utils.data.convert.JsonUtil; import com.makeit.utils.data.convert.JsonUtil;
import com.makeit.utils.data.convert.StreamUtil; import com.makeit.utils.data.convert.StreamUtil;
import com.makeit.utils.time.LocalDateTimeUtils; import com.makeit.utils.time.LocalDateTimeUtils;
import com.makeit.vo.platform.elder.wakeUpAnalysisVO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -47,9 +46,11 @@ import java.time.format.DateTimeFormatter; ...@@ -47,9 +46,11 @@ import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -84,6 +85,8 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr ...@@ -84,6 +85,8 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
private PlatElderBreatheAnalysisService platElderBreatheAnalysisService; private PlatElderBreatheAnalysisService platElderBreatheAnalysisService;
@Autowired @Autowired
private PlatElderRealTimeService platElderRealTimeService; private PlatElderRealTimeService platElderRealTimeService;
@Autowired
private PlatElderSleepService platElderSleepService;
private static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); private static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
...@@ -183,7 +186,7 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr ...@@ -183,7 +186,7 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
} }
if (firstStopSecond != 0 && (timestamp - firstStopSecond) / 1000 >= breatheDuration) { if (firstStopSecond != 0 && (timestamp - firstStopSecond) / 1000 >= breatheDuration) {
// 避免每10s生成一次统计的方式,切换状态后重新计算 // 避免每10s生成一次统计的方式,切换状态后重新计算
if(!existBrStop.get()) { if (!existBrStop.get()) {
log.info("第一次呼吸暂停持续时间满足:{}:now:{}", breatheDuration, longToTime(timestamp)); log.info("第一次呼吸暂停持续时间满足:{}:now:{}", breatheDuration, longToTime(timestamp));
brStopCount.getAndIncrement(); brStopCount.getAndIncrement();
existBrStop.set(true); existBrStop.set(true);
...@@ -271,12 +274,12 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr ...@@ -271,12 +274,12 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
} }
hrFastSecond.set(0); hrFastSecond.set(0);
existHrFast.set(false); existHrFast.set(false);
}else { } else {
hrSlowSecond.set(0); hrSlowSecond.set(0);
existHrSlow.set(false); existHrSlow.set(false);
hrFastSecond.set(0); hrFastSecond.set(0);
existHrFast.set(false); existHrFast.set(false);
log.info("心率正常:{},min:{},max:{},的时间:{}", hr, heartThresholdMin,heartThresholdMax, longToTime(timestamp)); log.info("心率正常:{},min:{},max:{},的时间:{}", hr, heartThresholdMin, heartThresholdMax, longToTime(timestamp));
} }
}); });
...@@ -394,7 +397,7 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr ...@@ -394,7 +397,7 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public List<PlatElderBreatheAnalysis> elderHeartRespiratoryAnalysisTask(Integer month,Integer day) { public List<PlatElderBreatheAnalysis> elderHeartRespiratoryAnalysisTask(Integer month, Integer day) {
// 12-06,12-18 12-07、 12-12(70分) // 12-06,12-18 12-07、 12-12(70分)
LocalDate nowDate = LocalDate.now(); LocalDate nowDate = LocalDate.now();
if (month != null && day != null) { if (month != null && day != null) {
...@@ -442,14 +445,6 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr ...@@ -442,14 +445,6 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
return result; return result;
} }
public Long getDurationRange(String startTime, String endTime) {
LocalDateTime target = LocalDateTime.parse(startTime, DEFAULT_FORMATTER);
// 获取当前日期,此处为了保证后续结果固定,注掉自动获取当前日期,指定固定日期
// LocalDate today = LocalDate.now();
LocalDateTime source = LocalDateTime.parse(endTime, DEFAULT_FORMATTER);
return Duration.between(target, source).toHours() + 1;
}
public static String formatLongTime(long time) { public static String formatLongTime(long time) {
return DEFAULT_FORMATTER.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault())); return DEFAULT_FORMATTER.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()));
} }
...@@ -466,5 +461,210 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr ...@@ -466,5 +461,210 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
return list; return list;
} }
@Override
public List<wakeUpAnalysisVO> elderGetUpAnalysisTask(Integer month, Integer day) {
LocalDate nowDate = LocalDate.now();
if (month != null && day != null) {
nowDate = LocalDate.of(2023, month, day);
}
LocalDate yesDate = nowDate.minusDays(1);
List<PlatElder> elderList = platElderService.list(new QueryWrapper<PlatElder>().lambda()
.isNotNull(PlatElder::getBedId).eq(PlatElder::getId,"1712648603580764161"));
List<wakeUpAnalysisVO> result = new ArrayList<>();
if (CollectionUtils.isEmpty(elderList)) {
return result;
}
List<String> elderIdList = StreamUtil.map(elderList, BaseEntity::getId);
SaasSleepAnalysisModel analysisModel = saasSleepAnalysisModelService.getOne(new QueryWrapper<SaasSleepAnalysisModel>().lambda()
.orderByDesc(BaseEntity::getCreateBy)
.last("limit 1"));
LocalDateTime yesStart = LocalDateTimeUtils.getDayStart(yesDate);
Map<String, List<PlatElderSleep>> sleepMap = StreamUtil.groupBy(platElderSleepService.list(Wrappers.<PlatElderSleep>lambdaQuery().eq(PlatElderSleep::getHappenDate, String.valueOf(yesDate))
.in(PlatElderSleep::getElderId, elderIdList)), PlatElderSleep::getElderId);
for (PlatElder platElder : elderList) {
PlatDevice platDevice = platElderRealTimeService.getBreathDevice(platElder.getId(), null);
if (platDevice == null) {
continue;
}
List<PlatElderSleep> sleepList = sleepMap.get(platElder.getId());
List<String> dayHourRange = getLastDayHourRange(yesStart);
List<LocalDateTime> leaveOverTime = new ArrayList<>();
List<LocalDateTime> wakeUpList = new ArrayList<>();
boolean isOffBed = false;
for (String hourRange : dayHourRange) {
String[] hourRangeArray = hourRange.split("~");
List<DeviceOperationLogEntity> deviceOperationLogEntities = productDeviceService.getDeviceLogByTimeRange(
platDevice.getOriDeviceId(), "reportProperty", 5000, hourRangeArray[0], hourRangeArray[1]);
if (CollectionUtils.isEmpty(deviceOperationLogEntities)) {
continue;
}
List<DeviceInfoContentBreathe> deviceInfoContentBreatheList = deviceOperationLogEntities.stream()
.filter(deviceOperationLogEntity -> deviceOperationLogEntity.getType().contains("reportProperty"))
.map(deviceOperationLogEntity -> {
DeviceInfoContentBreathe deviceInfoContentBreathe = JsonUtil.toObj((String) deviceOperationLogEntity.getContent(), DeviceInfoContentBreathe.class);
assert deviceInfoContentBreathe != null;
deviceInfoContentBreathe.setReportTime(formatLongTime(deviceInfoContentBreathe.getTimestamp()));
return deviceInfoContentBreathe;
}).collect(Collectors.toList());
Map<String, List<DeviceInfoContentBreathe>> minuteMap = StreamUtil.groupBy(deviceInfoContentBreatheList, DeviceInfoContentBreathe::getReportTime);
deviceOperationLogEntities.clear();
// 人离床大于(0.5)小时
double leaveHourThreshold = Double.parseDouble(analysisModel.getRiseLeaveThreshold());
// 或者每分钟大于30秒体动值 大于(50)
int actionThreshold = Integer.parseInt(analysisModel.getRiseActionThreshold());
// 每分钟大于30秒体动值 大于(50) 持续 (10)min
int actionDurationThreshold = Integer.parseInt(analysisModel.getRiseActionDuration());
// 且在 (2) 小时内无再次入睡
int riseRepeatThreshold = Integer.parseInt(analysisModel.getRiseRepeatThreshold());
Long firstOffBedTime = 0L;
TreeMap<LocalDateTime, Integer> minuteToActionCountMap = new TreeMap<>();
for (Map.Entry<String, List<DeviceInfoContentBreathe>> entry : minuteMap.entrySet()) {
List<DeviceInfoContentBreathe> perMinDeviceInfoList = entry.getValue();
if (CollUtil.isEmpty(perMinDeviceInfoList)) {
continue;
}
int totalActionCount = 0;
int perMinInfoSize = perMinDeviceInfoList.size();
for (int i = 0; i < perMinDeviceInfoList.size(); i++) {
DeviceInfoContentBreathe deviceInfo = perMinDeviceInfoList.get(i);
DeviceInfoContentBreathe.Properties deviceProperties = deviceInfo.getProperties();
// 0无人,1有人
Integer hasPerson = deviceProperties.getPerson();
Long timestamp = deviceInfo.getTimestamp();
if (1 == hasPerson) {
isOffBed = false;
firstOffBedTime = 0L;
// 体动值大于阈值
if (deviceProperties.getBodymove() > actionThreshold) {
totalActionCount++;
}
} else {
if (!isOffBed) {
firstOffBedTime = timestamp;
isOffBed = true;
continue;
}
if (firstOffBedTime != 0L && (timestamp - firstOffBedTime) / 1000 >= (long) leaveHourThreshold * 60 * 60) {
logger.info("离床时间大于:{}小时,第一次离床时间:{},当前时间:{}", leaveHourThreshold, longToTime(firstOffBedTime), longToTime(timestamp));
leaveOverTime.add(longToTime(timestamp));
}
}
if (i == perMinInfoSize - 1 && totalActionCount >= perMinInfoSize / 2) {
LocalDateTime reportTime = parse(deviceInfo.getReportTime());
minuteToActionCountMap.put(reportTime, totalActionCount);
}
}
}
wakeUpList = getWakeUpTimes(minuteToActionCountMap, sleepList, actionDurationThreshold, riseRepeatThreshold);
}
wakeUpAnalysisVO wakeUpAnalysisVO = new wakeUpAnalysisVO();
wakeUpAnalysisVO.setElderId(platElder.getId());
wakeUpAnalysisVO.setName(platElder.getName());
wakeUpAnalysisVO.setWakeUpList(wakeUpList);
wakeUpAnalysisVO.setLeaveOverTimeList(leaveOverTime);
result.add(wakeUpAnalysisVO);
}
return result;
}
private List<LocalDateTime> getActionDurationTime(Map<String, List<DeviceInfoContentBreathe>> map, int actionDurationThreshold,
int actionThreshold, List<PlatElderSleep> sleepList, int riseRepeatThreshold) {
List<LocalDateTime> result = new ArrayList<>();
int totalActionCount = 0;
TreeMap<LocalDateTime, Integer> minuteToActionCountMap = new TreeMap<>();
for (Map.Entry<String, List<DeviceInfoContentBreathe>> entry : map.entrySet()) {
List<DeviceInfoContentBreathe> perMinDeviceInfoList = entry.getValue();
if (CollUtil.isEmpty(perMinDeviceInfoList)) {
continue;
}
int perMinInfoSize = perMinDeviceInfoList.size();
for (int i = 0; i < perMinInfoSize; i++) {
DeviceInfoContentBreathe deviceInfo = perMinDeviceInfoList.get(i);
DeviceInfoContentBreathe.Properties deviceProperties = deviceInfo.getProperties();
// 0无人,1有人
Integer hasPerson = deviceProperties.getPerson();
if (1 == hasPerson) {
// 体动值大于阈值
if (deviceProperties.getBodymove() > actionThreshold) {
totalActionCount++;
}
}
if (i == perMinInfoSize - 1 && totalActionCount >= perMinInfoSize / 2) {
LocalDateTime reportTime = parse(deviceInfo.getReportTime());
minuteToActionCountMap.put(reportTime, totalActionCount);
}
}
}
if (CollUtil.isEmpty(minuteToActionCountMap)) {
return result;
}
result = getWakeUpTimes(minuteToActionCountMap, sleepList, actionDurationThreshold, riseRepeatThreshold);
return result;
}
/**
* 获取满足(每分钟大于30秒体动值大于(50),持续10min且在(2)小时内无再次入睡
* @param minuteToActionCountMap
* @return
*/
private List<LocalDateTime> getWakeUpTimes(TreeMap<LocalDateTime, Integer> minuteToActionCountMap, List<PlatElderSleep> elderSleeps,
int actionDurationThreshold, int riseRepeatThreshold) {
List<LocalDateTime> result = new ArrayList<>();
AtomicReference<LocalDateTime> startTime = new AtomicReference<>(LocalDateTime.MAX);
minuteToActionCountMap.forEach((k, v) -> {
int count = 0;
if (startTime.get().isEqual(LocalDateTime.MAX)) {
startTime.set(k);
}
for (int i = 1; i < actionDurationThreshold + 1; i++) {
if (minuteToActionCountMap.containsKey(k.plusMinutes(i))) {
count++;
}
if (count >= actionDurationThreshold / 2) {
if (k.compareTo(startTime.get()) != 1) {
result.add(k);
} else {
startTime.set(k);
}
}
}
if (!minuteToActionCountMap.containsKey(k.plusMinutes(1))) {
startTime.set(LocalDateTime.MAX);
}
});
if (CollUtil.isEmpty(result) || CollUtil.isEmpty(elderSleeps)) {
return result;
}
List<LocalDateTime> errorTime = new ArrayList<>();
// (2)小时内无再次入睡
for (LocalDateTime wakeUpTime : result) {
elderSleeps.stream().filter(f -> Duration.between(wakeUpTime, f.getStartSleep()).toHours() < riseRepeatThreshold)
.findFirst().ifPresent(platElderSleep -> errorTime.add(parse(platElderSleep.getStartSleep().toString())));
}
if (CollUtil.isNotEmpty(errorTime)) {
log.info("清醒时间和再次入睡:{}相隔太短{}", riseRepeatThreshold, errorTime);
result.removeAll(errorTime);
}
return result;
}
private LocalDateTime parse(String time) {
return LocalDateTime.parse(time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
}
} }
package com.makeit.service.platform.elder.impl; package com.makeit.service.platform.elder.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
...@@ -89,11 +90,6 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper, ...@@ -89,11 +90,6 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
public List<PlatElderSleepAnalysis> elderSleepSleepAnalysisTask(Integer month,Integer day) { public List<PlatElderSleepAnalysis> elderSleepSleepAnalysisTask(Integer month,Integer day) {
List<String> dayHourRangeList = getLastDayHourRange(month,day); List<String> dayHourRangeList = getLastDayHourRange(month,day);
// Calendar calendar = Calendar.getInstance();
// calendar.setTime(new Date());
// calendar.add(Calendar.DAY_OF_MONTH, -1);
// Date previousDate = calendar.getTime();
// String currentDate = DateUtil.format(previousDate, DatePattern.NORM_DATE_PATTERN);
String currentDate = LocalDate.now().minusDays(1).toString(); String currentDate = LocalDate.now().minusDays(1).toString();
if(month != null && day != null){ if(month != null && day != null){
currentDate = LocalDate.of(2023, month, day).minusDays(1).toString(); currentDate = LocalDate.of(2023, month, day).minusDays(1).toString();
...@@ -155,6 +151,7 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper, ...@@ -155,6 +151,7 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
.filter(deviceOperationLogEntity -> deviceOperationLogEntity.getType().contains("reportProperty")) .filter(deviceOperationLogEntity -> deviceOperationLogEntity.getType().contains("reportProperty"))
.map(deviceOperationLogEntity -> { .map(deviceOperationLogEntity -> {
DeviceInfoContentBreathe deviceInfoContentBreathe = JsonUtil.toObj((String) deviceOperationLogEntity.getContent(), DeviceInfoContentBreathe.class); DeviceInfoContentBreathe deviceInfoContentBreathe = JsonUtil.toObj((String) deviceOperationLogEntity.getContent(), DeviceInfoContentBreathe.class);
assert deviceInfoContentBreathe != null;
deviceInfoContentBreathe.setReportTime(formatLongTime(deviceInfoContentBreathe.getTimestamp())); deviceInfoContentBreathe.setReportTime(formatLongTime(deviceInfoContentBreathe.getTimestamp()));
return deviceInfoContentBreathe; return deviceInfoContentBreathe;
}) })
...@@ -187,8 +184,8 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper, ...@@ -187,8 +184,8 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
boolean isAction = false; // 每分钟是否动过 boolean isAction = false; // 每分钟是否动过
AnalysisVO analysisVO = new AnalysisVO(); AnalysisVO analysisVO = new AnalysisVO();
int getUpBodymoveCount = 0; int getUpBodymoveCount = 0;
boolean isMoveBed = true; boolean isMoveBed = false;
boolean awakeMinuteActionFlag = true; // 清醒每分钟体动是否满足要求 boolean awakeMinuteActionFlag = false; // 清醒每分钟体动是否满足要求
int noPersonCount = 0; // 无人跳过计数 int noPersonCount = 0; // 无人跳过计数
int sleepDeepMinuteCount = 0; // 深睡每分钟体动和翻身次数 int sleepDeepMinuteCount = 0; // 深睡每分钟体动和翻身次数
...@@ -201,8 +198,9 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper, ...@@ -201,8 +198,9 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
int hr = breatheProperties.getHr(); int hr = breatheProperties.getHr();
Integer hasPerson = breatheProperties.getPerson(); // 0无人,1有人 Integer hasPerson = breatheProperties.getPerson(); // 0无人,1有人
if (breatheProperties.getPerson() == 0) { if (hasPerson == 0) {
noPersonCount++; noPersonCount++;
isMoveBed = true;
continue; continue;
} }
// 0和255直接跳过 // 0和255直接跳过
...@@ -222,7 +220,7 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper, ...@@ -222,7 +220,7 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
turnoverCount++; turnoverCount++;
} }
// 判断入睡时间的体动阈值 // 判断入睡时间的体动阈值
if (bodymove > sleepTimeActionThreshold) { if (bodymove >= sleepTimeActionThreshold) {
isAction = true; isAction = true;
} }
// 起床每分钟体动次数 // 起床每分钟体动次数
...@@ -230,15 +228,10 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper, ...@@ -230,15 +228,10 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
getUpBodymoveCount++; getUpBodymoveCount++;
} }
// 清醒 // 清醒
if (bodymove < awakeThreshold || hasPerson == 1) { if (bodymove > awakeThreshold) {
awakeMinuteActionFlag = false; awakeMinuteActionFlag = true;
}
// 判断有没有离开床
if (hasPerson == 1) {
isMoveBed = false;
} }
if (br > maxBr) { if (br > maxBr) {
maxBr = br; maxBr = br;
} }
...@@ -252,7 +245,7 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper, ...@@ -252,7 +245,7 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
if (hr < minHr) { if (hr < minHr) {
minHr = hr; minHr = hr;
} }
if (breatheProperties.getPerson() == 1) { if (hasPerson == 1) {
totalBr += br; totalBr += br;
totalHr += hr; totalHr += hr;
hrBrCount++; hrBrCount++;
...@@ -705,7 +698,9 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper, ...@@ -705,7 +698,9 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
dayRestTime += elderSleep.getInterval(); dayRestTime += elderSleep.getInterval();
} }
} }
platElderSleepService.saveBatch(elderSleepList); int riseRepeatThreshold = Integer.parseInt(analysisModel.getRiseRepeatThreshold());
List<PlatElderSleep> mergeElderSleepList = mergeWakeUpList(elderSleepList, riseRepeatThreshold);
platElderSleepService.saveBatch(mergeElderSleepList);
String score = calculateScores(daySleepTime, dayRestTime, deepTime, soberTime, lightTime, evaluateStandardReport); String score = calculateScores(daySleepTime, dayRestTime, deepTime, soberTime, lightTime, evaluateStandardReport);
EvaluateReportVO sleepReport = saasSleepEvaluateReportService.getByScore(Long.parseLong(score)); EvaluateReportVO sleepReport = saasSleepEvaluateReportService.getByScore(Long.parseLong(score));
...@@ -728,6 +723,52 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper, ...@@ -728,6 +723,52 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
return result; return result;
} }
/**
* @param elderSleepList
* @param riseRepeatThreshold 且在 (2) 小时内无再次入睡
* @return
*/
@Override
public List<PlatElderSleep> mergeWakeUpList(List<PlatElderSleep> elderSleepList, int riseRepeatThreshold) {
List<PlatElderSleep> result = new ArrayList<>();
if (CollUtil.isEmpty(elderSleepList)) {
return elderSleepList;
}
elderSleepList = elderSleepList.stream().sorted(Comparator.comparing(PlatElderSleep::getStartSleep))
.collect(Collectors.toList());
List<PlatElderSleep> finalElderSleepList = elderSleepList;
List<PlatElderSleep> mergeSleepList = new ArrayList<>();
finalElderSleepList.forEach(e -> {
if (mergeSleepList.contains(e)) {
return;
}
// 2小时内再次入睡的数据,合并
List<PlatElderSleep> riseSleepList = finalElderSleepList.stream().filter(f -> Duration.between(e.getEndSleep(),
f.getStartSleep()).toHours() < riseRepeatThreshold).collect(Collectors.toList());
if (CollUtil.isEmpty(riseSleepList)) {
result.add(e);
return;
}
mergeSleepList.addAll(riseSleepList);
PlatElderSleep maxSleepTime = finalElderSleepList.stream().max(Comparator.comparing(f -> Duration.between(f.getStartSleep(),
f.getEndSleep()).toMinutes() > Duration.between(e.getStartSleep(),
e.getEndSleep()).toMinutes())).orElse(e);
PlatElderSleep last = riseSleepList.get(riseSleepList.size() - 1);
e.setElderSleepType(maxSleepTime.getElderSleepType());
e.setEndSleep(last.getEndSleep());
List<PlatSleepRangeVO> sleepRecord = e.getSleepRecord();
Set<PlatSleepRangeVO> platSleepRangeVOS = new LinkedHashSet<>(sleepRecord);
riseSleepList.forEach(r -> platSleepRangeVOS.addAll(r.getSleepRecord()));
e.setSleepRecord(new ArrayList<>(platSleepRangeVOS));
result.add(e);
});
return result;
}
@Override @Override
public String calculateScores(long daySleepTime, long dayRestTime, long deepTime, long soberTime, long lightTime, public String calculateScores(long daySleepTime, long dayRestTime, long deepTime, long soberTime, long lightTime,
SaasSleepEvaluateStandardReport evaluateStandardReport) { SaasSleepEvaluateStandardReport evaluateStandardReport) {
......
package com.makeit.vo.platform.elder;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author wangzy
* @description
* @createDate 2023-12-29-14:48
*/
@Data
public class wakeUpAnalysisVO {
private List<LocalDateTime> wakeUpList;
private List<LocalDateTime> leaveOverTimeList;
private String elderId;
private String name;
}
package com.makeit.iotapi; package com.makeit.iotapi;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.makeit.dto.platform.alarm.PlatAlarmCheckDTO; import com.makeit.dto.platform.alarm.PlatAlarmCheckDTO;
import com.makeit.entity.platform.device.PlatDevice; import com.makeit.entity.platform.device.PlatDevice;
import com.makeit.entity.platform.elder.PlatElderSleep;
import com.makeit.global.annotation.AuthIgnore;
import com.makeit.global.aspect.tenant.TenantIdIgnore;
import com.makeit.module.admin.vo.plat.PlatTenantVO; import com.makeit.module.admin.vo.plat.PlatTenantVO;
import com.makeit.module.iot.service.IotOrgService; import com.makeit.module.iot.service.IotOrgService;
import com.makeit.module.iot.service.IotProductDeviceService; import com.makeit.module.iot.service.IotProductDeviceService;
import com.makeit.module.iot.service.IotTokenService; import com.makeit.module.iot.service.IotTokenService;
import com.makeit.service.platform.alarm.alarmStrategy.OffBedAlarm; import com.makeit.service.platform.alarm.alarmStrategy.OffBedAlarm;
import com.makeit.service.platform.elder.PlatElderSleepService;
import com.makeit.utils.redis.RedisUtil; import com.makeit.utils.redis.RedisUtil;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
...@@ -27,6 +35,11 @@ public class IotDeviceInfoContentFall { ...@@ -27,6 +35,11 @@ public class IotDeviceInfoContentFall {
private IotProductDeviceService iotProductDeviceService; private IotProductDeviceService iotProductDeviceService;
@Autowired @Autowired
private OffBedAlarm offBedAlarm; private OffBedAlarm offBedAlarm;
@Autowired
private PlatElderSleepService platElderSleepService;
private static final Logger logger = LoggerFactory.getLogger(IotDeviceInfoContentFall.class);
@Test @Test
...@@ -114,4 +127,27 @@ public class IotDeviceInfoContentFall { ...@@ -114,4 +127,27 @@ public class IotDeviceInfoContentFall {
System.out.println(list); System.out.println(list);
} }
@Test
@TenantIdIgnore
@AuthIgnore
void mergeElderSleepList() {
List<PlatElderSleep> sleepList = platElderSleepService.list(Wrappers.<PlatElderSleep>lambdaQuery()
.eq(PlatElderSleep::getHappenDate, "2024-01-01").eq(PlatElderSleep::getElderId, "1712648603580764161"));
logger.info("ori sleep data :{}", JSONUtil.toJsonStr(sleepList));
List<PlatElderSleep> platElderSleeps = recursion(sleepList, sleepList.size() / 2, 3);
logger.info("end sleep data :{}", JSONUtil.toJsonStr(platElderSleeps));
List<PlatElderSleep> list = platElderSleepService.mergeWakeUpList(sleepList, 3);
System.out.println(list);
}
private List<PlatElderSleep> recursion(List<PlatElderSleep> elderSleepList, int count, int riseRepeatThreshold) {
List<PlatElderSleep> platElderSleeps = platElderSleepService.mergeWakeUpList(elderSleepList, riseRepeatThreshold);
if (count == 0) {
return platElderSleeps;
} else {
count--;
return recursion(platElderSleeps, count, riseRepeatThreshold);
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment