diff --git a/sec-beidou/src/main/java/com/imdroid/beidou/controller/GnssMsgStatusController.java b/sec-beidou/src/main/java/com/imdroid/beidou/controller/GnssMsgStatusController.java index 881ee762..c7039d10 100644 --- a/sec-beidou/src/main/java/com/imdroid/beidou/controller/GnssMsgStatusController.java +++ b/sec-beidou/src/main/java/com/imdroid/beidou/controller/GnssMsgStatusController.java @@ -1,6 +1,7 @@ package com.imdroid.beidou.controller; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.imdroid.beidou.service.CommonExcelService; import com.imdroid.secapi.dto.GnssStatusMsg; @@ -11,12 +12,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import java.util.List; +import java.util.*; /** * 状态消息 控制器 @@ -32,6 +34,10 @@ public class GnssMsgStatusController extends BasicController implements CommonEx GnssStatusMsgMapper statusMsgMapper; @Autowired OpLogManager opLogManager; + + // 滑动窗口大小 + private static final int WINDOW_SIZE = 5; + @RequestMapping("/page/gnss_msg_status") public String gnssStatusMsg(Model m, HttpSession session) { initModel(m, session); @@ -53,6 +59,118 @@ public class GnssMsgStatusController extends BasicController implements CommonEx } return obj; } + + /** + * 获取特定设备的数据,并应用滑动平均 + * + * @param deviceId 设备ID + * @param limit 获取条数,默认150条 + * @return 处理后的数据 + */ + @RequestMapping("/gnss/msg/status/device_data") + @ResponseBody + public JSONObject getDeviceData(@RequestParam String deviceId, + @RequestParam(required = false, defaultValue = "150") Integer limit) { + // 查询指定设备的最近数据 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("deviceid", deviceId) + .orderByDesc("createtime") + .last("limit " + limit); + + List dataList = statusMsgMapper.selectList(queryWrapper); + // 反转列表,使其按时间升序排列 + Collections.reverse(dataList); + + // 应用滑动平均 + List smoothedData = applyMovingAverage(dataList, WINDOW_SIZE); + + JSONObject result = new JSONObject(); + result.put("code", 0); + result.put("msg", ""); + result.put("count", smoothedData.size()); + result.put("data", smoothedData); + result.put("originalData", dataList); + return result; + } + + /** + * 应用滑动平均算法 + * + * @param dataList 原始数据列表 + * @param windowSize 窗口大小 + * @return 处理后的数据列表 + */ + private List applyMovingAverage(List dataList, int windowSize) { + if (dataList.size() <= 1) { + return new ArrayList<>(dataList); + } + + List result = new ArrayList<>(dataList.size()); + + // 初始窗口 + Deque rollWindow = new LinkedList<>(); + Deque pitchWindow = new LinkedList<>(); + Deque yawWindow = new LinkedList<>(); + + for (int i = 0; i < dataList.size(); i++) { + GnssStatusMsg currentMsg = dataList.get(i); + GnssStatusMsg smoothedMsg = new GnssStatusMsg(); + + // 复制基本属性 + smoothedMsg.setId(currentMsg.getId()); + smoothedMsg.setDeviceid(currentMsg.getDeviceid()); + smoothedMsg.setCreatetime(currentMsg.getCreatetime()); + smoothedMsg.setDevicetime(currentMsg.getDevicetime()); + smoothedMsg.setTenantid(currentMsg.getTenantid()); + smoothedMsg.setDtustate(currentMsg.getDtustate()); + smoothedMsg.setRssi(currentMsg.getRssi()); + smoothedMsg.setVoltage(currentMsg.getVoltage()); + smoothedMsg.setSolarvoltage(currentMsg.getSolarvoltage()); + smoothedMsg.setChargecurrency(currentMsg.getChargecurrency()); + smoothedMsg.setChargewatt(currentMsg.getChargewatt()); + smoothedMsg.setTemperature(currentMsg.getTemperature()); + smoothedMsg.setHumidity(currentMsg.getHumidity()); + + // 添加当前值到窗口 + if (currentMsg.getRoll() != null) rollWindow.addLast(currentMsg.getRoll()); + if (currentMsg.getPitch() != null) pitchWindow.addLast(currentMsg.getPitch()); + if (currentMsg.getYaw() != null) yawWindow.addLast(currentMsg.getYaw()); + + // 保持窗口大小 + if (rollWindow.size() > windowSize) rollWindow.removeFirst(); + if (pitchWindow.size() > windowSize) pitchWindow.removeFirst(); + if (yawWindow.size() > windowSize) yawWindow.removeFirst(); + + // 计算平均值 + if (!rollWindow.isEmpty()) { + float rollSum = 0; + for (Float val : rollWindow) rollSum += val; + smoothedMsg.setRoll(rollSum / rollWindow.size()); + } else { + smoothedMsg.setRoll(currentMsg.getRoll()); + } + + if (!pitchWindow.isEmpty()) { + float pitchSum = 0; + for (Float val : pitchWindow) pitchSum += val; + smoothedMsg.setPitch(pitchSum / pitchWindow.size()); + } else { + smoothedMsg.setPitch(currentMsg.getPitch()); + } + + if (!yawWindow.isEmpty()) { + float yawSum = 0; + for (Float val : yawWindow) yawSum += val; + smoothedMsg.setYaw(yawSum / yawWindow.size()); + } else { + smoothedMsg.setYaw(currentMsg.getYaw()); + } + + result.add(smoothedMsg); + } + + return result; + } /** * 导出excel diff --git a/sec-beidou/src/main/resources/templates/page/gnss_msg_status.html b/sec-beidou/src/main/resources/templates/page/gnss_msg_status.html index 204cf32e..91c1c2f4 100644 --- a/sec-beidou/src/main/resources/templates/page/gnss_msg_status.html +++ b/sec-beidou/src/main/resources/templates/page/gnss_msg_status.html @@ -21,7 +21,7 @@
- +
@@ -44,7 +44,7 @@
- +
@@ -52,17 +52,36 @@ -
+
+
    +
  • 数据表格
  • +
  • 姿态曲线
  • +
+
+
+
+
+
+
+
+
+
+ +