#include "custom_utils.h"
#include <vibrator_service.h>
#include <stdio.h>
-#include <stdlib.h> // 包含 rand()、srand() 函数
-#include <time.h> // 包含 time() 函数,用于生成随机种子
+#include <stdlib.h>
+#include <time.h>
+
+#ifdef SUPPORT_PPG_SERVICE
+#include "ppg_service.h"
+#include "ppg_hal.h"
+#endif
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));
}
// 开启压力测试定时器
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!!");
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::StressTest_StartTimer: 压力测试定时器启动成功");
// 常亮屏幕
ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON);
+ #ifdef SUPPORT_PPG_SERVICE
+ ppg_hrv_start();
+ #endif
}
}
// 取消常亮屏
ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON);
// 重置压力测试定时器数据
- resetStressTestTimerData();
+ resetStressTestData();
+ #ifdef SUPPORT_PPG_SERVICE
+ ppg_hrv_stop();
+ #endif
}
}
}