From a4db783b2b9028aa68c9e645ac4d8209ebd87191 Mon Sep 17 00:00:00 2001 From: xue <2144439972@qq.com> Date: Mon, 7 Jul 2025 12:16:46 +0800 Subject: [PATCH] =?utf8?q?=E5=A2=9E=E5=8A=A0=E6=95=B0=E6=8D=AE=E5=AD=98?= =?utf8?q?=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../nativeui/bloodpressure/include/BPModel.h | 9 +- .../nativeui/bloodpressure/src/BPModel.cpp | 256 +++++++++++++----- 2 files changed, 198 insertions(+), 67 deletions(-) diff --git a/code/sdk/application/wearable/fd230app/nativeui/bloodpressure/include/BPModel.h b/code/sdk/application/wearable/fd230app/nativeui/bloodpressure/include/BPModel.h index f7f880f09..a25e57fc8 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/bloodpressure/include/BPModel.h +++ b/code/sdk/application/wearable/fd230app/nativeui/bloodpressure/include/BPModel.h @@ -68,10 +68,9 @@ enum class BP_VALUE_TYPE { }; struct LAST_CHECK_DATA { - uint64_t timestamp; // 时间戳 单位s uint8_t last_check_sbp_value; // 上次检测收缩压值 uint8_t last_check_dbp_value; // 上次检测舒张压值 - + uint32_t timestamp; // 时间戳 单位s }; #define BP_CHECK_TIME_MAX_TEST 90 //测量所需时间 @@ -89,6 +88,7 @@ public: // 获取当前时间年月日时分字符串 std::string GetCurrentTimeStr(); std::string GetCurrentTimeStr(uint64_t timeStamp); + std::string GetCurrentTimePath(); //获取当前时间戳 uint32_t GetCurrentTime(); std::string GetLastCalibrationTime(); @@ -119,10 +119,7 @@ public: /* --------------------------------- 最近检测数据 --------------------------------- */ - #define BP_LAST_CHECK_FILE_PATH "/user/userdata/bp/bp_last_check.txt" static constexpr const char *BP_JSON_PATH = "/user/userdata/bp/"; - bool save_last_check_bp_data(LAST_CHECK_DATA data); - bool load_last_check_bp_data(void); bool get_last_check_bp_data(LAST_CHECK_DATA &data); int get_last_check_data_num(void); const uint8_t max_checkout_num = 30; @@ -131,6 +128,8 @@ public: // 存储bin文件 bool save_bin_BP(const LAST_CHECK_DATA &data); bool UpdateHealthData(const LAST_CHECK_DATA &data); + bool IsTimestampToday(uint32_t timestamp); + bool LoadBP(); /* -------------------------------------------------------------------------- */ diff --git a/code/sdk/application/wearable/fd230app/nativeui/bloodpressure/src/BPModel.cpp b/code/sdk/application/wearable/fd230app/nativeui/bloodpressure/src/BPModel.cpp index c5a5e317b..1b7a14298 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/bloodpressure/src/BPModel.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/bloodpressure/src/BPModel.cpp @@ -101,6 +101,33 @@ namespace OHOS return std::string(buffer); } + // 获取当前时间+路经字符串 // 格式: 文件路径+YYYY_MM_DD+文件名 + std::string BPModel::GetCurrentTimePath() + { + uint32_t timeStamp = 0; + + if (uapi_get_timestampe_ss(&timeStamp) != ERRCODE_SUCC) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get timestamp"); + return "----/--/--"; + } + + // 将时间戳转换为 time_t 类型 + time_t rawtime = static_cast(timeStamp); + struct tm *timeinfo = localtime(&rawtime); + + if (timeinfo == NULL) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to convert time"); + return "----/--/--"; + } + + // 格式化时间为字符串 + char buffer[20]; // 格式: YYYY-MM-DD HH:MM + std::strftime(buffer, sizeof(buffer), "%Y_%m_%d", timeinfo); + + return std::string(BP_JSON_PATH) + std::string(buffer) + "BP.bin"; + } std::string BPModel::GetCurrentTimeStr(uint64_t timeStamp) { @@ -192,7 +219,6 @@ namespace OHOS bp_check_cnt = 0; // 重置计数 if (Time != BP_CHECK_TIME_MAX_TEST) Time = BP_CHECK_TIME_MAX_TEST; // 重置时间120秒 - load_last_check_bp_data(); BP_StartTimer(); ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON); // 后期 周期被动状态 需要做区别 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, @@ -312,6 +338,8 @@ namespace OHOS auto *emoView = EmoView::GetInstance(); auto *ecgView = EcgView::GetInstance(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "current_state:%d", current_state); // 处理血压校准相关状态 if (current_state == BPState::BP_CALIBRATING_FIRSTTIME || current_state == BPState::BP_CALIBRATING_SECONDTIME) @@ -324,7 +352,6 @@ namespace OHOS BPCALIBRATIONMINDVIEW); } LastCalibrationTime = BPModel::GetCurrentTimeStr(); // 获取校准完成时的时间 - BP_STOP(); BP_SetState(BPState::BP_NORMAL); CalibrationFlag++; return; @@ -350,6 +377,12 @@ namespace OHOS { bpDetectionView->ChangeView(CALIBRATION_BPVIEW, RESULT_BPVIEW); } + BP_STOP(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "LoadBP1111"); + LoadBP(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "LoadBP2222"); BP_SetState(BPState::BP_NORMAL); return; } @@ -505,9 +538,26 @@ namespace OHOS newData.last_check_sbp_value = custom_sbp; // 测试数据 newData.last_check_dbp_value = custom_dbp; newData.timestamp = BPModel::GetCurrentTime(); - save_last_check_bp_data(newData); // 保存数据 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SBP: %d, DBP: %d", custom_sbp, custom_dbp); } +#if 1 + if (Time == 5) + { + LAST_CHECK_DATA newData; + newData.timestamp = BPModel::GetCurrentTime(); + newData.last_check_sbp_value = 128; // 测试数据 + newData.last_check_dbp_value = 80; + UpdateHealthData(newData); + } + if (Time == 20) + { + LAST_CHECK_DATA newData; + newData.timestamp = BPModel::GetCurrentTime(); + newData.last_check_sbp_value = 199; // 测试数据 + newData.last_check_dbp_value = 30; + UpdateHealthData(newData); + } +#endif } break; } @@ -540,7 +590,6 @@ namespace OHOS newData.last_check_sbp_value = custom_sbp; // 测试数据 newData.last_check_dbp_value = custom_dbp; newData.timestamp = BPModel::GetCurrentTime(); - save_last_check_bp_data(newData); // 保存数据 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SBP: %d, DBP: %d", custom_sbp, custom_dbp); } } @@ -575,7 +624,6 @@ namespace OHOS newData.last_check_sbp_value = custom_sbp; // 测试数据 newData.last_check_dbp_value = custom_dbp; newData.timestamp = BPModel::GetCurrentTime(); - save_last_check_bp_data(newData); // 保存数据 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SBP: %d, DBP: %d", custom_sbp, custom_dbp); } } @@ -757,67 +805,13 @@ namespace OHOS bp_check_value_vector.push_back(mappedValue); } - /* - 1.存储到BP.bin,存储前先判断文件夹是否存在 + 1.存储到BP.bin 2.每次测量成功存储一次data,追加ab+ 3.开机初始化读取文件,赋值到DBP,SBP 4.每次更新,更新数组 5.更新完毕,存储到文件 - */ - // 保存上次检测数据 - bool BPModel::save_last_check_bp_data(LAST_CHECK_DATA data) - { - // 检查容量,最多存储30条日志 - if (lastCheckData.size() >= max_checkout_num) - { - lastCheckData.pop_front(); // 超出限制,删除最旧的日志 - } - - // 保存新日志,将传入的完整检测数据添加到队列 - lastCheckData.push_back(data); - - // 将lastCheckData写入文件,覆盖写 - std::ofstream outFile(BP_LAST_CHECK_FILE_PATH, std::ios::trunc); - if (!outFile) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, - "Open file failed! Path: %s, Error: %s", - BP_LAST_CHECK_FILE_PATH, - strerror(errno)); - return false; // 文件打开失败 - } - - // 遍历队列,将每条检测数据(包括收缩压、舒张压和时间戳)写入文件 - for (const auto &Data : lastCheckData) - { - outFile << Data.last_check_sbp_value << " "; - outFile << Data.last_check_dbp_value << " "; - outFile << Data.timestamp << std::endl; - } - outFile.close(); - - return true; - } - - // 加载上次检测数据 - bool BPModel::load_last_check_bp_data(void) - { - std::ifstream inFile(BP_LAST_CHECK_FILE_PATH); - if (!inFile) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "BPModel::load_last_check_bp_data"); - return false; // 文件打开失败 - } - // 读取文件内容,解析检测数据 - LAST_CHECK_DATA data; - while (inFile >> data.last_check_sbp_value >> data.last_check_dbp_value >> data.timestamp) - { - lastCheckData.push_back(data); - } - return true; - } bool BPModel::get_last_check_bp_data(LAST_CHECK_DATA &data) { @@ -839,20 +833,158 @@ namespace OHOS bool BPModel::UpdateHealthData(const LAST_CHECK_DATA &data) { - + + // 判断文件夹是否存在 + if (!CreateBPFolder()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateBPFolder file"); + return false; + } + if (!save_bin_BP(data)) + { // 存储bin文件[协议使用] + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveBP failed"); + return false; + } return true; } // 存储bin文件 bool BPModel::save_bin_BP(const LAST_CHECK_DATA &data) { + /* 存储 bin 文件 [协议使用] */ + std::string binFilePath = GetCurrentTimePath(); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "save_bin_heart binFilePath %s", + binFilePath.c_str()); + FILE *fp = fopen(binFilePath.c_str(), "ab+"); + if (fp == NULL) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "Failed to open binary file for writing"); + return false; + } + + // 写入数据 + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sizeof(HeartRateData) %d", sizeof(HeartRateData)); + if ((fwrite(&data.timestamp, sizeof(data.timestamp), 1, fp) != 1) || + (fwrite(&data.last_check_sbp_value, sizeof(data.last_check_sbp_value), 1, fp) != 1) || + (fwrite(&data.last_check_dbp_value, sizeof(data.last_check_dbp_value), 1, fp) != 1)) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "Failed to write data to binary file"); + fclose(fp); + return false; + } + + fclose(fp); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "Saved BP data: timestamp = %d, SBP = %d, DBP = %d", data.timestamp, + data.last_check_sbp_value, + data.last_check_dbp_value); return true; } /*创建文件夹*/ bool BPModel::CreateBPFolder() { + struct stat info; + if (stat(BP_JSON_PATH, &info) != 0) + { + if (mkdir(BP_JSON_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "mkdir BP_JSON_PATH is error"); + return false; + } + } + return true; } + bool BPModel::IsTimestampToday(uint32_t timestamp) + { + // 获取当前时间 + struct tm currentTm; + time_t seconds; + time(&seconds); + localtime_r(&seconds, ¤tTm); + // 将给定时间戳转换为 tm 结构 + struct tm *timestampTm = + localtime(reinterpret_cast(×tamp)); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "当前年月日:%d-%d-%d", + currentTm.tm_year + 1900, currentTm.tm_mon + 1, + currentTm.tm_mday); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "给定时间戳:%d-%d-%d", + timestampTm->tm_year + 1900, timestampTm->tm_mon + 1, + timestampTm->tm_mday); + // 比较年、月和日 + if ((currentTm.tm_year == timestampTm->tm_year && + currentTm.tm_mon == timestampTm->tm_mon && + currentTm.tm_mday == timestampTm->tm_mday)) + { + return true; + } + else + { + return false; + } + } + /*加载文件中数据*/ + bool BPModel::LoadBP() + { + // 清空存储数组 + + std::string binFilePath = GetCurrentTimePath(); // 文件夹+时间+文件名 + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "binFilePath %s", binFilePath.c_str()); //打开失败,今天没有测量记录则没有这个文件 + + std::ifstream ifs(binFilePath, std::ios::binary); + if (!ifs.is_open()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "Failed to open binary file for reading"); + return false; + } + + LAST_CHECK_DATA data; + // 选取数据 + while (true) + { + // 先读取时间戳 + if (!ifs.read(reinterpret_cast(&data.timestamp), sizeof(data.timestamp))) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "Failed to read heart rate value"); + break; // 如果读取失败,退出循环 + } + + // 再读取SBP值 + if (!ifs.read(reinterpret_cast(&data.last_check_sbp_value), sizeof(data.last_check_sbp_value))) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "Failed to read heart rate value"); + break; // 如果读取失败,退出循环 + } + // 再读取DBP值 + if (!ifs.read(reinterpret_cast(&data.last_check_dbp_value), sizeof(data.last_check_dbp_value))) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "Failed to read heart rate value"); + break; // 如果读取失败,退出循环 + } + //如果时间为当天 + if (IsTimestampToday(data.timestamp)) + { + + lastCheckData.push_back(data); // 存入数组中 +#if 1 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "timestamp:%d", data.timestamp); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "last_check_sbp_value:%d", data.last_check_sbp_value); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, + "last_check_dbp_value:%d", data.last_check_dbp_value); +#endif + } + } + + return true; + } - } // namespace OHOS -- 2.17.1