From 5fa86ef2abea0a68237b8945ac6d2ee159b6569a Mon Sep 17 00:00:00 2001 From: luozheng <1732036298@qq.com> Date: Mon, 17 Nov 2025 10:52:33 +0800 Subject: [PATCH] =?utf8?q?272:=E5=AF=B9=E6=8E=A5=E5=8E=8B=E5=8A=9B?= =?utf8?q?=E6=B5=8B=E8=AF=95=E6=8E=A5=E5=8F=A3=E6=B7=BB=E5=8A=A0=E6=B5=8B?= =?utf8?q?=E8=AF=95=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../nativeui/stress/include/stressTestModel.h | 6 + .../nativeui/stress/src/stressTestModel.cpp | 200 ++++++++++++------ .../nativeui/stress/src/stressTestingView.cpp | 2 +- 3 files changed, 147 insertions(+), 61 deletions(-) diff --git a/code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/include/stressTestModel.h b/code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/include/stressTestModel.h index eb41966fc..ac018e76c 100644 --- a/code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/include/stressTestModel.h +++ b/code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/include/stressTestModel.h @@ -42,6 +42,12 @@ namespace OHOS // 定时器相关 void StressTest_StartTimer(uint32_t interval = 1 * 1000, int type = 0); void StressTest_StopTimer(void); + + // 压力数据处理(参考UpHeartdata) + void UpStressData(uint8_t stress); + + // 设置佩戴状态(参考SetWearStatus) + void SetWearStatus(void); private: StressTestModel(); diff --git a/code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/src/stressTestModel.cpp b/code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/src/stressTestModel.cpp index 5bd70207d..9cbb1b771 100644 --- a/code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/src/stressTestModel.cpp +++ b/code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/src/stressTestModel.cpp @@ -8,8 +8,13 @@ #include "custom_utils.h" #include #include -#include // 包含 rand()、srand() 函数 -#include // 包含 time() 函数,用于生成随机种子 +#include +#include + +#ifdef SUPPORT_PPG_SERVICE +#include "ppg_service.h" +#include "ppg_hal.h" +#endif namespace OHOS { @@ -159,111 +164,180 @@ namespace OHOS WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::HandleResultValue: %dms", currentResultValue); } - static uint16_t StressAlgo_FetchOneSecondData(void) - { - // 初始化随机种子(仅需初始化一次,放在函数外更高效) - static int initialized = 0; - if (!initialized) - { - srand((unsigned int)time(NULL)); // 以当前时间作为种子,确保每次运行结果不同 - initialized = 1; - } +// 压力测量相关常量定义(参考心率测量的定义) +#define MAX_VALID_STRESS_COUNT 40 // 最大有效数据个数(60秒内至少需要40个有效数据) +#define MAX_DISVALID_STRESS_COUNT 15 // 最大无效数据个数(连续15次无效则停止) +#define MAX_UNWEAR_COUNT 2 // 最大未佩戴次数 +#define STRESS_TEST_DURATION_SEC 120 // 压力测试持续时间(秒) - // rand() 生成 [0, RAND_MAX] 的随机整数,取模 101 后得到 [0, 100] - return (uint16_t)(rand() % 101); - } + // 压力测量状态变量 + static uint16_t valid_counter_ = 0; // 有效数据计数器 + static uint16_t disvalid_counter_ = 0; // 无效数据计数器 + static uint16_t unwear_counter_ = 0; // 未佩戴计数器 + static uint16_t test_duration_sec_ = 0; // 测试持续时间(秒) + static uint16_t stress_value_ = 0; // 当前压力值 + static uint16_t ringBuffer[60]{0}; // 压力测试结果环形缓冲区 + static uint16_t ringBufferIndex = 0; // 环形缓冲区索引 GraphicTimer *g_stressTestTimer = nullptr; - static int g_stressTestTimerCount = 0; // 压力测试定时器计数 - static int g_invalidConsecutiveSec = 0; // 无效连续次数计数 - static uint8_t validCount{0}; // 有效数据个数 - static uint16_t ringBuffer[60]{0}; // 压力测试结果环形缓冲区 - static void resetStressTestTimerData(void) + // 重置压力测试数据 + static void resetStressTestData(void) { - g_stressTestTimerCount = 0; - g_invalidConsecutiveSec = 0; - validCount = 0; + valid_counter_ = 0; + disvalid_counter_ = 0; + unwear_counter_ = 0; + test_duration_sec_ = 0; + stress_value_ = 0; + ringBufferIndex = 0; for (int i = 0; i < 60; i++) { ringBuffer[i] = 0; } } - static void StressTestTimerCallbackProc(void *data) + // 处理压力数据(参考UpHeartdata函数) + void StressTestModel::UpStressData(uint8_t stress) { - (void)data; - //秒 - g_stressTestTimerCount++; - // 模拟出压力测试值 - uint16_t rawValueMs = StressAlgo_FetchOneSecondData(); - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "当前秒数: %d, 压力测试值: %dms", g_stressTestTimerCount, rawValueMs); - - bool isValueRange = (rawValueMs >= 0 && rawValueMs <= 100); - if (!isValueRange) + stress_value_ = stress; + test_duration_sec_++; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "测试时长:%d", test_duration_sec_); + if(test_duration_sec_ < 40) { - g_invalidConsecutiveSec++; + return;//至少要30s后才能出值 + } + + // 更新压力值和计数器 + if (stress_value_ > 0 && stress_value_ <= 100) + { + // 有效数据:存储到环形缓冲区 + ringBuffer[ringBufferIndex % 60] = stress_value_; + ringBufferIndex++; + valid_counter_++; // 增加有效计数器 + disvalid_counter_ = 0; // 清空无效计数器 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试有效数据: %d, 有效计数: %d, 测试时长: %d秒", + stress_value_, valid_counter_, test_duration_sec_); } else { - g_invalidConsecutiveSec = 0; - ringBuffer[validCount % 60] = rawValueMs; - validCount++; + // 无效数据 + disvalid_counter_++; // 增加无效计数器 + valid_counter_ = 0; // 清零有效计数器(连续有效才计数) + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试无效数据: %d, 无效计数: %d, 测试时长: %d秒", + stress_value_, disvalid_counter_, test_duration_sec_); } - /* 无效连续次数超过10次,停止压力测试 */ - if (g_invalidConsecutiveSec >= 10) + // 检查无效计数器是否达标 + if (disvalid_counter_ >= MAX_DISVALID_STRESS_COUNT) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::StressTestTimerCallbackProc: 无效连续次数超过10次,停止压力测试"); - StressTestModel::GetInstance().StressTest_StopTimer(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试: 无效数据过多 disvalid_counter:%d", disvalid_counter_); + StressTestModel::GetInstance().SetCurrentFailType(StressTestModel::FAIL_TYPE_INVALID_DATA); + StressTest_StopTimer(); // 震动提醒 custom_VibratorFunc_int(0); + // 切换到失败页面 if (StressTestPresenter::GetInstance()) { - StressTestPresenter::GetInstance()->ChangeViewOperation(StressTestModel::GetInstance().GetCurrentView(), STRESSTESTFAILVIEW); + StressTestPresenter::GetInstance()->ChangeViewOperation( + StressTestModel::GetInstance().GetCurrentView(), STRESSTESTFAILVIEW); } return; } - // 完成判定 - if (g_stressTestTimerCount >= 60 && validCount >= 40) + + if (ringBufferIndex >= MAX_VALID_STRESS_COUNT) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::StressTestTimerCallbackProc: 完成判定,计算最终结果"); // 计算最终结果,有效值的均值 uint16_t sum = 0; - for (int i = 0; i < validCount; i++) + uint16_t count = (ringBufferIndex < 60) ? ringBufferIndex : 60; + for (int i = 0; i < count; i++) { sum += ringBuffer[i]; } - uint16_t finalMs = sum / validCount; + uint16_t finalMs = sum / count; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试完成: 最终结果 %dms, 有效数据个数: %d", finalMs, count); + // 停止压力测试 + StressTest_StopTimer(); + StressTestModel &m = StressTestModel::GetInstance(); m.HandleResultValue(finalMs); // 分档上报 - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::StressTestTimerCallbackProc: 最终结果: %dms", finalMs); + // 切换到结果页面 if (StressTestPresenter::GetInstance()) { - StressTestPresenter::GetInstance()->ChangeViewOperation(StressTestModel::GetInstance().GetCurrentView(), STRESSTESTRESULTVIEW); + StressTestPresenter::GetInstance()->ChangeViewOperation( + StressTestModel::GetInstance().GetCurrentView(), STRESSTESTRESULTVIEW); } - //停止压力测试定时器 - StressTestModel::GetInstance().StressTest_StopTimer(); } - else if (g_stressTestTimerCount >= 60 && validCount < 40) + // 检查是否达到测试时长且有效数据足够 + if ((test_duration_sec_ >= STRESS_TEST_DURATION_SEC) && ringBufferIndex < MAX_VALID_STRESS_COUNT) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::StressTestTimerCallbackProc: 完成判定,计算最终结果"); - //停止压力测试定时器 - StressTestModel::GetInstance().StressTest_StopTimer(); + // 有效数据不足 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试: 有效数据不足 ringBufferIndex:%d", ringBufferIndex); + StressTestModel::GetInstance().SetCurrentFailType(StressTestModel::FAIL_TYPE_INVALID_DATA); // 震动提醒 custom_VibratorFunc_int(0); - // 切换到结果页面 + // 停止压力测试 + StressTest_StopTimer(); + // 切换到失败页面 if (StressTestPresenter::GetInstance()) { - StressTestPresenter::GetInstance()->ChangeViewOperation(StressTestModel::GetInstance().GetCurrentView(), STRESSTESTFAILVIEW); + StressTestPresenter::GetInstance()->ChangeViewOperation( + StressTestModel::GetInstance().GetCurrentView(), STRESSTESTFAILVIEW); } + return; } } - static void StressTestTimerCallback(void *data) + // 设置佩戴状态(参考SetWearStatus函数) + void StressTestModel::SetWearStatus(void) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试: 未佩戴状态 unwear_counter_:%d", unwear_counter_); + unwear_counter_++; + + if (unwear_counter_ > MAX_UNWEAR_COUNT) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试: 未佩戴次数过多,停止测试"); + StressTestModel::GetInstance().SetCurrentFailType(StressTestModel::FAIL_TYPE_NOT_WORN); + StressTest_StopTimer(); + // 震动提醒 + custom_VibratorFunc_int(0); + // 切换到失败页面 + if (StressTestPresenter::GetInstance()) + { + StressTestPresenter::GetInstance()->ChangeViewOperation( + StressTestModel::GetInstance().GetCurrentView(), STRESSTESTFAILVIEW); + } + } + } + + // 压力数据回调处理函数(参考heart_data_callbackProc) + static void stress_data_callbackProc(void *data) + { + // 更新佩戴状态 + uint8_t wear = 1; +#ifdef SUPPORT_PPG_SERVICE + wear = ppg_get_wear_status(); +#endif + if (wear == 0) + { + OHOS::StressTestModel::GetInstance().SetWearStatus(); + } + + // 更新压力值 + uint8_t hrv = 0; +#ifdef SUPPORT_PPG_SERVICE + hrv = ppg_get_hrv(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "stress_data_callbackProc: hrv = %d, wear = %d", hrv, wear); +#endif + + OHOS::StressTestModel::GetInstance().UpStressData(hrv); + } + + // 定时器回调函数(切换到图形线程) + static void stress_data_timer_callback(void *data) { - GraphicService::GetInstance()->PostGraphicEvent(std::bind(StressTestTimerCallbackProc, data)); + GraphicService::GetInstance()->PostGraphicEvent( + std::bind(stress_data_callbackProc, data)); } // 开启压力测试定时器 @@ -272,7 +346,7 @@ namespace OHOS uint32_t tick = GetOSTick(interval); if (g_stressTestTimer == nullptr) { - g_stressTestTimer = new GraphicTimer(tick, StressTestTimerCallback, nullptr, true); + g_stressTestTimer = new GraphicTimer(tick, stress_data_timer_callback, nullptr, true); if (g_stressTestTimer == nullptr) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::StressTest_StartTimer new GraphicTime failed!!"); @@ -297,6 +371,9 @@ namespace OHOS WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::StressTest_StartTimer: 压力测试定时器启动成功"); // 常亮屏幕 ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON); + #ifdef SUPPORT_PPG_SERVICE + ppg_hrv_start(); + #endif } } @@ -312,7 +389,10 @@ namespace OHOS // 取消常亮屏 ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON); // 重置压力测试定时器数据 - resetStressTestTimerData(); + resetStressTestData(); + #ifdef SUPPORT_PPG_SERVICE + ppg_hrv_stop(); + #endif } } } diff --git a/code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/src/stressTestingView.cpp b/code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/src/stressTestingView.cpp index 884ea64b5..d7ae977d6 100644 --- a/code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/src/stressTestingView.cpp +++ b/code/sdk/application/wearable/fd272/nativeapp/nativeui/stress/src/stressTestingView.cpp @@ -7,7 +7,7 @@ namespace OHOS static constexpr int STRESS_TESTING_IMAGE_ANIMATOR_VIEW_Y = 60; static constexpr int STRESS_TESTING_IMAGE_ANIMATOR_VIEW_W = 260; static constexpr int STRESS_TESTING_IMAGE_ANIMATOR_VIEW_H = 260; - static constexpr int STRESS_TESTING_IMAGE_ANIMATOR_DELAY = 75; // 图片更新间隔 + static constexpr int STRESS_TESTING_IMAGE_ANIMATOR_DELAY = 100; // 图片更新间隔 const char *stress_testing_image_path_array[] = { "/user/res/stress/stress_gif/bg1_CS6.bin", -- 2.17.1