fd272:hrv界面添加数据显示 2792/1 2792/head 2794/target/1
authorluozheng <1732036298@qq.com>
Sat, 22 Nov 2025 09:27:15 +0000 (17:27 +0800)
committerluozheng <1732036298@qq.com>
Sat, 22 Nov 2025 09:27:15 +0000 (17:27 +0800)
code/sdk/application/wearable/fd272/nativeapp/nativeui/hrv/src/HrvView.cpp
code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/include/stressTestModel.h
code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/src/stressTestModel.cpp

index 2c646c7..f34da61 100644 (file)
@@ -11,6 +11,7 @@
 #include "common/key_code.h"
 #include "custom_utils.h"
 #include "ui_resource_string.h"
+#include "stress/include/stressTestModel.h"
 namespace OHOS
 {
 
@@ -47,6 +48,7 @@ void HrvView::OnStart()
         group->SetPosition(0, 0, 466, 466);
         group->SetStyle(STYLE_BACKGROUND_COLOR, 0xff000000);
         group->SetStyle(STYLE_BACKGROUND_OPA, 0xD0);
+        group->SetOnDragListener((UIView::OnDragListener *)OHOS::HrvPresenter::GetInstance());
         RootView::GetInstance()->Add(group);
         
         Label_init();
@@ -75,7 +77,15 @@ bool HrvView::Label_init()
     {
         hrv_average_value_label = new UILabel();
         hrv_average_value_label->SetPosition(149, 115, 96, 97);
-        hrv_average_value_label->SetText("--");
+        int16_t avg = StressTestModel::GetInstance().GetLastSevenDaysHrvAverage();
+        if (avg != -1)
+        {
+            hrv_average_value_label->SetText(std::to_string(avg).c_str());
+        }
+        else
+        {
+            hrv_average_value_label->SetText("--");
+        }
         hrv_average_value_label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 80);
         hrv_average_value_label->SetStyle(STYLE_TEXT_COLOR, 0xFFFFFFFF);
         hrv_average_value_label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
@@ -135,7 +145,14 @@ bool HrvView::Label_init()
     {
         last_average_value_label = new UILabelExt();
         last_average_value_label->SetPosition(83, 391, 300, 35);
-        last_average_value_label->SetText("-- ms");
+        std::string last_average_value = "-- ms";
+        //获取昨日平均值
+        int16_t avg = StressTestModel::GetInstance().GetYesterdayHrvAverage();
+        if (avg != -1)
+        {
+            last_average_value = std::to_string(avg) + " ms";
+        }
+        last_average_value_label->SetText(last_average_value.c_str());
         last_average_value_label->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
         last_average_value_label->SetStyle(STYLE_TEXT_COLOR, 0xFFFFFFFF);
         last_average_value_label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
index e0def7e..f0b6db5 100644 (file)
@@ -43,16 +43,19 @@ namespace OHOS
         uint32_t GetLastTestTimestamp(void);
         void SetLastTestTimestamp(uint32_t timestamp);
         
-        // 获取当前日期字符串(格式:YYYY_MM_DD)
-        std::string GetCurrentDateString(void);
+        // 获取指定天数前的日期字符串(格式:YYYY_MM_DD)
+        std::string GetDaysAgoDateString(int daysAgo = 0);
         // 创建目录(如果不存在)
         bool CreateDirectoryIfNotExists(const char* dirPath);
         
         // 保存历史记录到日期文件
         void SaveHistoryRecord(uint32_t timestamp, uint16_t value);
-        
         // 获取指定日期的平均值(用于HRV slice显示)
         int16_t GetDateAverage(const char* dateStr);
+        // 获取昨日hrv平均值
+        int16_t GetYesterdayHrvAverage(void);
+        //获取七天hrv平均值
+        int16_t GetLastSevenDaysHrvAverage(void);
 
         // 定时器相关
         void StressTest_StartTimer(uint32_t interval = 1 * 1000, int type = 0);
index e3f56ee..5488fc4 100644 (file)
@@ -17,6 +17,7 @@
 #include <string>
 #include "errcode.h"
 #include "custom_runtime.h"
+#include <unistd.h>
 
 #ifdef SUPPORT_PPG_SERVICE
 #include "ppg_service.h"
@@ -25,7 +26,7 @@
 
 namespace OHOS
 {
-    StressTestModel::StressTestModel() 
+    StressTestModel::StressTestModel()
     {
         CreateDirectoryIfNotExists("/user/userdata/hrv/");
         // 构造函数中加载最近一次测试结果
@@ -37,27 +38,33 @@ namespace OHOS
         return instance;
     }
 
-    // 获取当前日期字符串(格式:YYYY_MM_DD)
-    std::string StressTestModel::GetCurrentDateString(void)
+    std::string StressTestModel::GetDaysAgoDateString(int daysAgo)
     {
         char dateStr[32];
         time_t now = time(nullptr);
-        struct tm *tm_info = localtime(&now);
-        snprintf(dateStr, sizeof(dateStr), "%04d_%02d_%02d", 
-                 tm_info->tm_year + 1900, tm_info->tm_mon + 1, tm_info->tm_mday);
+        struct tm tm_info;
+        tm_info = *localtime_r(&now, &tm_info); // 线程安全版本
+        tm_info.tm_mday -= daysAgo;
+        mktime(&tm_info); // 自动处理月份/年份变更
+        snprintf(dateStr, sizeof(dateStr), "%04d_%02d_%02d",
+                 tm_info.tm_year + 1900, tm_info.tm_mon + 1, tm_info.tm_mday);
         return std::string(dateStr);
     }
 
     // 创建目录(如果不存在)
-    bool StressTestModel::CreateDirectoryIfNotExists(const char* dirPath)
+    bool StressTestModel::CreateDirectoryIfNotExists(const char *dirPath)
     {
-        if (access(dirPath, F_OK) == -1) {  // 如果路径不存在
+        if (access(dirPath, F_OK) == -1)
+        { // 如果路径不存在
             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Directory %s not exist, creating directory\n", dirPath);
-            if (mkdir(dirPath, 0777)!= 0) {  // 尝试创建目录,如果创建失败
+            if (mkdir(dirPath, 0777) != 0)
+            { // 尝试创建目录,如果创建失败
                 WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Create directory %s failed\n", dirPath);
                 return false;
             }
-        } else {  // 如果路径存在
+        }
+        else
+        { // 如果路径存在
             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Directory %s already exists\n", dirPath);
         }
         return true;
@@ -66,7 +73,7 @@ namespace OHOS
     void StressTestModel::SaveResultToFile(void)
     {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::SaveResultToFile: 保存压力测试结果");
-        
+
         // 获取当前时间戳
         uint32_t timestamp = 0;
         if (uapi_get_timestampe_ss(&timestamp) != ERRCODE_SUCC)
@@ -75,16 +82,16 @@ namespace OHOS
             return;
         }
         lastTestTimestamp = timestamp;
-        
+
         // 1. 保存最近一次测试结果(覆盖存储)
         // 确保目录存在
-        const char* lastResultDir = "/user/userdata/hrv/last_hrv_test/";
+        const char *lastResultDir = "/user/userdata/hrv/last_hrv_test/";
         if (!CreateDirectoryIfNotExists(lastResultDir))
         {
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "创建最近结果目录失败");
             return;
         }
-        
+
         FILE *fp = fopen(STRESS_TEST_LAST_RESULT_FILE_PATH, "w+");
         if (fp == nullptr)
         {
@@ -95,7 +102,7 @@ namespace OHOS
         fprintf(fp, "%u %u\n", timestamp, static_cast<unsigned>(currentResultValue));
         fclose(fp);
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "保存最近一次结果: timestamp=%u, value=%u", timestamp, currentResultValue);
-        
+
         // 2. 保存历史记录到日期文件(追加模式)
         SaveHistoryRecord(timestamp, currentResultValue);
     }
@@ -113,7 +120,7 @@ namespace OHOS
             lastTestTimestamp = 0;
             return;
         }
-        
+
         // 读取格式:时间戳(秒) + 结果值
         unsigned timestamp = 0;
         unsigned value = 35;
@@ -129,29 +136,29 @@ namespace OHOS
             }
         }
         fclose(fp);
-        
+
         if (value > 1000) // 简单有效性约束,防止脏数据
         {
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "值大于1000,使用默认值");
             value = 35;
             timestamp = 0;
         }
-        
+
         lastTestTimestamp = timestamp;
         HandleResultValue(static_cast<uint16_t>(value));
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "加载成功: timestamp=%u, value=%u", timestamp, value);
     }
-    
+
     uint32_t StressTestModel::GetLastTestTimestamp(void)
     {
         return lastTestTimestamp;
     }
-    
+
     void StressTestModel::SetLastTestTimestamp(uint32_t timestamp)
     {
         lastTestTimestamp = timestamp;
     }
-    
+
     // 保存历史记录到日期文件
     void StressTestModel::SaveHistoryRecord(uint32_t timestamp, uint16_t value)
     {
@@ -161,14 +168,14 @@ namespace OHOS
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "创建历史数据目录失败");
             return;
         }
-        
+
         // 获取日期字符串(格式:YYYY_MM_DD)
-        std::string dateStr = GetCurrentDateString();
-        
+        std::string dateStr = GetDaysAgoDateString();
+
         // 构建文件路径
-        char filePath[256]={0};
+        char filePath[256] = {0};
         snprintf(filePath, sizeof(filePath), "%s%s.txt", STRESS_TEST_HISTORY_DIR, dateStr.c_str());
-        
+
         // 追加模式打开文件
         FILE *fp = fopen(filePath, "a+");
         if (fp == nullptr)
@@ -176,39 +183,45 @@ namespace OHOS
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "打开历史记录文件失败: %s", filePath);
             return;
         }
-        
+
         // 写入格式:时间戳(秒) + 结果值,每行一条记录
         fprintf(fp, "%u %u\n", timestamp, value);
         fclose(fp);
-        
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "保存历史记录: date=%s, timestamp=%u, value=%u", 
-                     dateStr.c_str(), timestamp, value);
+
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "保存历史记录: date=%s, timestamp=%u, value=%u",
+                      dateStr.c_str(), timestamp, value);
     }
-    
+
     // 获取指定日期的平均值(用于HRV slice显示)
-    int16_t StressTestModel::GetDateAverage(const char* dateStr)
+    int16_t StressTestModel::GetDateAverage(const char *dateStr)
     {
         if (dateStr == nullptr)
         {
             return -1;
         }
-        
+
         // 构建文件路径
         char filePath[256];
         snprintf(filePath, sizeof(filePath), "%s%s.txt", STRESS_TEST_HISTORY_DIR, dateStr);
-        
+
+        // 先检查文件是否存在
+        if (access(filePath, F_OK) == -1) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "日期文件不存在: %s", filePath);
+            return -1;
+        }
+
         FILE *fp = fopen(filePath, "r");
         if (fp == nullptr)
         {
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "日期文件不存在: %s", filePath);
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "打开日期文件失败: %s, 错误: %s", filePath, strerror(errno));
             return -1;
         }
-        
+
         uint32_t sum = 0;
         uint16_t count = 0;
         uint32_t timestamp = 0;
         uint16_t value = 0;
-        
+
         // 读取所有记录并计算平均值
         while (fscanf(fp, "%u %u", &timestamp, &value) == 2)
         {
@@ -219,18 +232,44 @@ namespace OHOS
             }
         }
         fclose(fp);
-        
+
         if (count == 0)
         {
             WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "日期 %s 无有效数据", dateStr);
             return -1;
         }
-        
+
         uint16_t average = sum / count;
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "日期 %s 平均值: %u (共%d条记录)", dateStr, average, count);
         return average;
     }
 
+    // 获取昨日hrv平均值
+    int16_t StressTestModel::GetYesterdayHrvAverage(void)
+    {
+        std::string yesterday_date = GetDaysAgoDateString(1);
+        return GetDateAverage(yesterday_date.c_str());
+    }
+
+    // 获取七天hrv平均值:当天的和过去六天的hrv平均值
+    int16_t StressTestModel::GetLastSevenDaysHrvAverage(void)
+    {
+        int16_t avg = 0;
+        int count = 0;
+        for (int i = 0; i < 7; i++) // i=0:昨天, i=6:6天前
+        {
+            std::string date = GetDaysAgoDateString(i);
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "获取日期 %s 的平均值", date.c_str());
+            int16_t day_avg = GetDateAverage(date.c_str());
+            if (day_avg != -1)
+            {
+                avg += day_avg;
+                count++;
+            }
+        }
+        return (count > 0) ? (avg / count) : -1; // 无有效数据时返回-1更合理
+    }
+
     uint8_t StressTestModel::GetCurrentView(void)
     {
         return currentView;
@@ -493,7 +532,7 @@ namespace OHOS
 
         if ((test_duration_sec_ >= STRESS_TEST_DURATION_SEC) && ringBufferIndex >= MAX_VALID_STRESS_COUNT)
         {
-            #if 1
+#if 1
             // 计算最终结果,有效值的均值
             uint16_t sum = 0;
             uint16_t count = (ringBufferIndex < 60) ? ringBufferIndex : 60;
@@ -513,7 +552,7 @@ namespace OHOS
                 StressTestPresenter::GetInstance()->ChangeViewOperation(
                     StressTestModel::GetInstance().GetCurrentView(), STRESSTESTRESULTVIEW);
             }
-            #else
+#else
             uint16_t finalMs = CalculateReasonableStress();
             if (finalMs == -1)
             {
@@ -536,7 +575,7 @@ namespace OHOS
                         StressTestModel::GetInstance().GetCurrentView(), STRESSTESTRESULTVIEW);
                 }
             }
-            #endif
+#endif
             // 停止压力测试
             StressTest_StopTimer();
             // 震动