#include <time.h>
#include <string.h>
#include <math.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <string>
+#include "errcode.h"
+#include "custom_runtime.h"
#ifdef SUPPORT_PPG_SERVICE
#include "ppg_service.h"
namespace OHOS
{
- StressTestModel::StressTestModel() {}
+ StressTestModel::StressTestModel()
+ {
+ CreateDirectoryIfNotExists("/user/userdata/hrv/");
+ // 构造函数中加载最近一次测试结果
+ }
StressTestModel::~StressTestModel() {}
StressTestModel &StressTestModel::GetInstance()
{
return instance;
}
+ // 获取当前日期字符串(格式:YYYY_MM_DD)
+ std::string StressTestModel::GetCurrentDateString(void)
+ {
+ 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);
+ return std::string(dateStr);
+ }
+
+ // 创建目录(如果不存在)
+ bool StressTestModel::CreateDirectoryIfNotExists(const char* dirPath)
+ {
+ 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) { // 尝试创建目录,如果创建失败
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Create directory %s failed\n", dirPath);
+ return false;
+ }
+ } else { // 如果路径存在
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Directory %s already exists\n", dirPath);
+ }
+ return true;
+ }
+
void StressTestModel::SaveResultToFile(void)
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::SaveResultToFile: 保存压力测试结果到文件");
- FILE *fp = fopen(STRESS_TEST_RESULT_FILE_PATH, "w+");
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::SaveResultToFile: 保存压力测试结果");
+
+ // 获取当前时间戳
+ uint32_t timestamp = 0;
+ if (uapi_get_timestampe_ss(×tamp) != ERRCODE_SUCC)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "获取时间戳失败");
+ return;
+ }
+ lastTestTimestamp = timestamp;
+
+ // 1. 保存最近一次测试结果(覆盖存储)
+ // 确保目录存在
+ 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)
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveResultToFile open fail: %s", STRESS_TEST_RESULT_FILE_PATH);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveResultToFile open fail: %s", STRESS_TEST_LAST_RESULT_FILE_PATH);
return;
}
- // 以纯æ\96\87æ\9c¬å\86\99å\85¥ä¸\80个æ\95´æ\95°å\80¼ï¼\8c便äº\8eæ\8e\92æ\9f¥
- fprintf(fp, "%u\n", static_cast<unsigned>(currentResultValue));
+ // ä¿\9då\98æ ¼å¼\8fï¼\9aæ\97¶é\97´æ\88³(ç§\92) + ç»\93æ\9e\9cå\80¼
+ 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);
}
void StressTestModel::LoadResultFromFile(void)
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::LoadResultFromFile: 加载压力测试结果到文件");
- FILE *fp = fopen(STRESS_TEST_RESULT_FILE_PATH, "r");
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::LoadResultFromFile: 加载最近一次压力测试结果");
+ FILE *fp = fopen(STRESS_TEST_LAST_RESULT_FILE_PATH, "r");
if (fp == nullptr)
{
- // 文件不存在则写入默认值并返回
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::LoadResultFromFile: 压力测试结果文件不存在,写入默认值");
+ // 文件不存在,使用默认值
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "压力测试结果文件不存在,使用默认值");
SetCurrentResultValue(35);
SetCurrentResultType(RESULT_TYPE_NORMAL);
- SaveResultToFile();
+ lastTestTimestamp = 0;
return;
}
+
+ // 读取格式:时间戳(秒) + 结果值
+ unsigned timestamp = 0;
unsigned value = 35;
- if (fscanf(fp, "%u", &value) != 1)
+ if (fscanf(fp, "%u %u", ×tamp, &value) != 2)
{
- // 读失败/格式不对,回退默认
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::LoadResultFromFile: 读取压力测试结果失败,回退默认值");
- value = 35;
+ // 旧格式兼容:只有值
+ fseek(fp, 0, SEEK_SET);
+ if (fscanf(fp, "%u", &value) != 1)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "读取压力测试结果失败,使用默认值");
+ value = 35;
+ timestamp = 0;
+ }
}
fclose(fp);
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::LoadResultFromFile: 读取压力测试结果成功,值为: %u", value);
+
if (value > 1000) // 简单有效性约束,防止脏数据
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::LoadResultFromFile: 值大于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)
+ {
+ // 确保历史数据目录存在
+ if (!CreateDirectoryIfNotExists(STRESS_TEST_HISTORY_DIR))
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "创建历史数据目录失败");
+ return;
+ }
+
+ // 获取日期字符串(格式:YYYY_MM_DD)
+ std::string dateStr = GetCurrentDateString();
+
+ // 构建文件路径
+ 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)
+ {
+ 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);
+ }
+
+ // 获取指定日期的平均值(用于HRV slice显示)
+ 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);
+
+ FILE *fp = fopen(filePath, "r");
+ if (fp == nullptr)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "日期文件不存在: %s", filePath);
+ return -1;
+ }
+
+ uint32_t sum = 0;
+ uint16_t count = 0;
+ uint32_t timestamp = 0;
+ uint16_t value = 0;
+
+ // 读取所有记录并计算平均值
+ while (fscanf(fp, "%u %u", ×tamp, &value) == 2)
+ {
+ if (value > 0 && value <= 100) // 有效性检查
+ {
+ sum += value;
+ count++;
+ }
+ }
+ fclose(fp);
+
+ if (count == 0)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "日期 %s 无有效数据", dateStr);
+ return -1;
+ }
+
+ uint16_t average = sum / count;
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "日期 %s 平均值: %u (共%d条记录)", dateStr, average, count);
+ return average;
}
uint8_t StressTestModel::GetCurrentView(void)
{
currentResultType = RESULT_TYPE_OVERLOAD; // <20
}
- SaveResultToFile();
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::HandleResultValue: %d", currentResultType);
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "StressTestModel::HandleResultValue: %dms", currentResultValue);
+ SaveResultToFile();
}
// 压力测量相关常量定义(参考心率测量的定义)