From e8ebecccfce261647d1a537d005410a96d9cdad8 Mon Sep 17 00:00:00 2001 From: SnickerSun Date: Fri, 20 Sep 2024 12:04:53 +0800 Subject: [PATCH] =?utf8?q?Revert=20"=E4=BF=AE=E6=94=B9=E5=BF=83=E7=8E=87?= =?utf8?q?=E7=9A=84=E6=98=BE=E7=A4=BA=E6=9C=80=E5=A4=A7=E6=9C=80=E5=B0=8F?= =?utf8?q?=E5=80=BC=E4=B8=BA=E5=AE=9E=E9=99=85=E5=80=BC"?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This reverts commit 9df02a668cc4579c5af24c5bf9be75cabab01b00. --- .../health_service/health_service.cpp | 951 +++++++++--------- .../nativeui/heartrate/include/HeartModel.h | 7 +- .../nativeui/heartrate/src/HeartChartView.cpp | 4 +- .../nativeui/heartrate/src/HeartModel.cpp | 32 +- 4 files changed, 501 insertions(+), 493 deletions(-) diff --git a/code/sdk/application/wearable/fd230app/nativeui/heart_blood/health_service/health_service.cpp b/code/sdk/application/wearable/fd230app/nativeui/heart_blood/health_service/health_service.cpp index a8491bd4e..6d9550e4f 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heart_blood/health_service/health_service.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/heart_blood/health_service/health_service.cpp @@ -1,32 +1,36 @@ #include "health_service.h" -#include "bloodoxygen/include/BloodOxygenModel.h" -#include "cJSON.h" -#include "custom_utils.h" -#include "heartrate/include/HeartModel.h" -#include "kv_store.h" +#include #include "wearable_log.h" -#include +#include "cJSON.h" +#include #include +#include "kv_store.h" +#include "custom_utils.h" #include -#include #include #include -#include -namespace OHOS { -extern "C" { -void save_heart_data() { - printf("save_heart_data\r\n"); - OHOS::HealthService::GetInstance()->SaveDailyHeartRate(); - return; -} -} +#include +#include "heartrate/include/HeartModel.h" +#include "bloodoxygen/include/BloodOxygenModel.h" +namespace OHOS +{ + extern "C" + { + void save_heart_data() + { + printf("save_heart_data\r\n"); + OHOS::HealthService::GetInstance()->SaveDailyHeartRate(); + return; + } + } -static HealthService *g_pHealthService = nullptr; -/*获取日期*/ -std::string GetCurrentDate() { - char date[9]; - uapi_get_YYMMDD_Time(date, '\0'); - return std::string(date); + static HealthService *g_pHealthService = nullptr; + /*获取日期*/ + std::string GetCurrentDate() + { + char date[9]; + uapi_get_YYMMDD_Time(date, '\0'); + return std::string(date); #if 0 time_t now = time(0); tm *ltm = localtime(&now); @@ -34,471 +38,478 @@ std::string GetCurrentDate() { strftime(date, sizeof(date), "%m%d%Y", ltm); // Use "%m%d%Y" for MMDDYYYY format return std::string(date); #endif -} -// static char *JSON_F_buf=NULL; + } + // static char *JSON_F_buf=NULL; -HealthService::HealthService() { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HealthService::HealthService"); - g_pHealthService = this; -} -HealthService::~HealthService() { g_pHealthService = nullptr; } -HealthService *HealthService::GetInstance() { - static HealthService instance; - return &instance; -} + HealthService::HealthService() + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HealthService::HealthService"); + g_pHealthService = this; + } + HealthService::~HealthService() + { + g_pHealthService = nullptr; + } + HealthService *HealthService::GetInstance() + { + static HealthService instance; + return &instance; + } -static constexpr const char *HEALTH_JSON_PATH = "/user/userdata/health/"; -static constexpr const char *HEALTH_JSON_PATH_HEART = - "/user/userdata/health/heart/"; -static constexpr const char *HEALTH_JSON_PATH_OXYGEN = - "/user/userdata/health/oxygen/"; -const char *GET_HEALTH_JSON_PATH_C_STR_HEART() { - return HEALTH_JSON_PATH_HEART; -} -const char *GET_HEALTH_JSON_PATH_C_STR_OXYGEN() { - return HEALTH_JSON_PATH_OXYGEN; -} -/* --------------------------------- 文件IO操作 - * --------------------------------- */ -/*创建文件夹*/ -bool HealthService::CreateHealthFolder() { - struct stat info; - if (stat(HEALTH_JSON_PATH, &info) != 0) { - if (mkdir(HEALTH_JSON_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "mkdir HEALTH_JSON_PATH is error"); - return false; + static constexpr const char *HEALTH_JSON_PATH = "/user/userdata/health/"; + static constexpr const char *HEALTH_JSON_PATH_HEART = "/user/userdata/health/heart/"; + static constexpr const char *HEALTH_JSON_PATH_OXYGEN = "/user/userdata/health/oxygen/"; + const char *GET_HEALTH_JSON_PATH_C_STR_HEART() + { + return HEALTH_JSON_PATH_HEART; } - } - if (stat(HEALTH_JSON_PATH_HEART, &info) != 0) { - if (mkdir(HEALTH_JSON_PATH_HEART, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != - 0) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, - "mkdir HEALTH_JSON_PATH_HEART is error"); - return false; + const char *GET_HEALTH_JSON_PATH_C_STR_OXYGEN() + { + return HEALTH_JSON_PATH_OXYGEN; } - } - if (stat(HEALTH_JSON_PATH_OXYGEN, &info) != 0) { - if (mkdir(HEALTH_JSON_PATH_OXYGEN, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != - 0) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, - "mkdir HEALTH_JSON_PATH_OXYGEN is error"); - return false; + /* --------------------------------- 文件IO操作 --------------------------------- */ + /*创建文件夹*/ + bool HealthService::CreateHealthFolder() + { + struct stat info; + if (stat(HEALTH_JSON_PATH, &info) != 0) + { + if (mkdir(HEALTH_JSON_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "mkdir HEALTH_JSON_PATH is error"); + return false; + } + } + if (stat(HEALTH_JSON_PATH_HEART, &info) != 0) + { + if (mkdir(HEALTH_JSON_PATH_HEART, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "mkdir HEALTH_JSON_PATH_HEART is error"); + return false; + } + } + if (stat(HEALTH_JSON_PATH_OXYGEN, &info) != 0) + { + if (mkdir(HEALTH_JSON_PATH_OXYGEN, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "mkdir HEALTH_JSON_PATH_OXYGEN is error"); + return false; + } + } + + return true; } - } - return true; -} + /*生成bin*/ + std::string GetBinFilePath(uint8_t type) + { + std::string currentDate = GetCurrentDate(); + const char *healthTypePath = (type == HEALTH_TYPE_HEART) ? HEALTH_JSON_PATH_HEART : HEALTH_JSON_PATH_OXYGEN; -/*生成bin*/ -std::string GetBinFilePath(uint8_t type) { - std::string currentDate = GetCurrentDate(); - const char *healthTypePath = (type == HEALTH_TYPE_HEART) - ? HEALTH_JSON_PATH_HEART - : HEALTH_JSON_PATH_OXYGEN; + return healthTypePath + currentDate + ".bin"; + } - return healthTypePath + currentDate + ".bin"; -} + /* --------------------------------- json操作 --------------------------------- */ + static constexpr const char *HEART_JSON_PATH = "/user/userdata/health/heart.json"; + static constexpr const char *BLOOD_JSON_PATH = "/user/userdata/health/blood.json"; -/* --------------------------------- json操作 --------------------------------- - */ -static constexpr const char *HEART_JSON_PATH = - "/user/userdata/health/heart.json"; -static constexpr const char *BLOOD_JSON_PATH = - "/user/userdata/health/blood.json"; - -// 读取血氧数据 -BloodOxygenData *HealthService::ReadBloodOxygenData() { - // 判断文件夹是否存在 - if (!CreateHealthFolder()) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file"); - return nullptr; - } - - // 读取文件 - std::ifstream inFile(BLOOD_JSON_PATH); - if (!inFile.is_open()) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open JSON file"); - return nullptr; - } - - // 读取文件内容到字符串 - std::stringstream buffer; - buffer << inFile.rdbuf(); - std::string jsonDataString = buffer.str(); - const char *jsonData = jsonDataString.c_str(); - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonData: %s", jsonData); - - // 关闭文件 - inFile.close(); - - if (jsonDataString.empty()) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonDataString is empty"); - return nullptr; - } - - cJSON *oxygen_root = cJSON_Parse(jsonData); - if (oxygen_root == NULL) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "oxygen_root is empty"); - return nullptr; - } - - BloodOxygenData *data = new BloodOxygenData(); - - cJSON *value_item = cJSON_GetObjectItem(oxygen_root, "value"); - cJSON *timestamp_item = cJSON_GetObjectItem(oxygen_root, "timestamp"); - - if (value_item && timestamp_item) { - data->SPO2 = value_item->valueint; - data->timestamp = timestamp_item->valuedouble; - } else { - // 读取的数据异常 - cJSON_Delete(oxygen_root); - delete data; - return nullptr; - } - cJSON_Delete(oxygen_root); - return data; -} -// 读取心率数据 -HeartRateData *HealthService::ReadHeartRateData() { - // 判断文件夹是否存在 - if (!CreateHealthFolder()) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file"); - return nullptr; - } - - // 读取文件 - std::ifstream inFile(HEART_JSON_PATH); - if (!inFile.is_open()) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open JSON file"); - // 创建一个默认值为 0的数据 存储到json里面 ? - return nullptr; - } - - // 读取文件内容到字符串 - std::stringstream buffer; - buffer << inFile.rdbuf(); - std::string jsonDataString = buffer.str(); - const char *jsonData = jsonDataString.c_str(); - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonData: %s", jsonData); - - // 关闭文件 - inFile.close(); - - if (jsonDataString.empty()) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonDataString is empty"); - return nullptr; - } - - cJSON *heart_root = cJSON_Parse(jsonData); - if (heart_root == NULL) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "heart_root is empty"); - return nullptr; - } - - HeartRateData *data = new HeartRateData(); - - cJSON *value_item = cJSON_GetObjectItem(heart_root, "value"); - cJSON *timestamp_item = cJSON_GetObjectItem(heart_root, "timestamp"); - - if (value_item && timestamp_item) { - data->Heart = value_item->valueint; - data->timestamp = timestamp_item->valuedouble; - } else { - // 读取的数据异常 - cJSON_Delete(heart_root); - delete data; - return nullptr; - } - cJSON_Delete(heart_root); - return data; -} -// 保存血氧数据 -bool HealthService::UpdateHealthData(const BloodOxygenData &data) { - // 判断文件夹是否存在 - if (!CreateHealthFolder()) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file"); - return false; - } - - // 判断文件是否存在 不存在即创建 并打开以输出模式 - std::ofstream outFile(BLOOD_JSON_PATH, std::ios::trunc); - if (!outFile.is_open()) { - // 文件创建失败 - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, - "Failed to create or open JSON file for writing"); - return false; - } - - // 创建一个 JSON 对象 - cJSON *oxygen_root = cJSON_CreateObject(); - if (oxygen_root == NULL) { - outFile.close(); - return false; - } - - cJSON_AddItemToObject(oxygen_root, "value", cJSON_CreateNumber(data.SPO2)); - cJSON_AddItemToObject(oxygen_root, "timestamp", - cJSON_CreateNumber(data.timestamp)); - - char *jsonData = cJSON_Print(oxygen_root); - if (jsonData == NULL) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to generate JSON data"); - cJSON_free(oxygen_root); - outFile.close(); - return false; - } - - // 写入 JSON 数据到文件 - outFile << jsonData; - - cJSON_free(oxygen_root); - free(jsonData); - outFile.close(); - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHealthData SPO2 JSON is ok"); - - /* 存储bin文件[协议使用] */ - std::string binFilePath = GetBinFilePath(HEALTH_TYPE_OXYGEN); - FILE *fp = fopen(binFilePath.c_str(), "ab+"); - if (fp == NULL) { - return false; - } - - fwrite(&data.timestamp, 4, 1, fp); - fwrite(&data.SPO2, 1, 1, fp); - - fclose(fp); - - return true; -} + // 读取血氧数据 + BloodOxygenData *HealthService::ReadBloodOxygenData() + { + // 判断文件夹是否存在 + if (!CreateHealthFolder()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file"); + return nullptr; + } + + // 读取文件 + std::ifstream inFile(BLOOD_JSON_PATH); + if (!inFile.is_open()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open JSON file"); + return nullptr; + } + + // 读取文件内容到字符串 + std::stringstream buffer; + buffer << inFile.rdbuf(); + std::string jsonDataString = buffer.str(); + const char *jsonData = jsonDataString.c_str(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonData: %s", jsonData); + + // 关闭文件 + inFile.close(); + + if (jsonDataString.empty()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonDataString is empty"); + return nullptr; + } + + cJSON *oxygen_root = cJSON_Parse(jsonData); + if (oxygen_root == NULL) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "oxygen_root is empty"); + return nullptr; + } + + BloodOxygenData *data = new BloodOxygenData(); + + cJSON *value_item = cJSON_GetObjectItem(oxygen_root, "value"); + cJSON *timestamp_item = cJSON_GetObjectItem(oxygen_root, "timestamp"); + + if (value_item && timestamp_item) + { + data->SPO2 = value_item->valueint; + data->timestamp = timestamp_item->valuedouble; + } + else + { + // 读取的数据异常 + cJSON_Delete(oxygen_root); + delete data; + return nullptr; + } + cJSON_Delete(oxygen_root); + return data; + } + // 读取心率数据 + HeartRateData *HealthService::ReadHeartRateData() + { + // 判断文件夹是否存在 + if (!CreateHealthFolder()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file"); + return nullptr; + } + + // 读取文件 + std::ifstream inFile(HEART_JSON_PATH); + if (!inFile.is_open()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open JSON file"); + // 创建一个默认值为 0的数据 存储到json里面 ? + return nullptr; + } + + // 读取文件内容到字符串 + std::stringstream buffer; + buffer << inFile.rdbuf(); + std::string jsonDataString = buffer.str(); + const char *jsonData = jsonDataString.c_str(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonData: %s", jsonData); + + // 关闭文件 + inFile.close(); + + if (jsonDataString.empty()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonDataString is empty"); + return nullptr; + } + + cJSON *heart_root = cJSON_Parse(jsonData); + if (heart_root == NULL) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "heart_root is empty"); + return nullptr; + } + + HeartRateData *data = new HeartRateData(); + + cJSON *value_item = cJSON_GetObjectItem(heart_root, "value"); + cJSON *timestamp_item = cJSON_GetObjectItem(heart_root, "timestamp"); + + if (value_item && timestamp_item) + { + data->Heart = value_item->valueint; + data->timestamp = timestamp_item->valuedouble; + } + else + { + // 读取的数据异常 + cJSON_Delete(heart_root); + delete data; + return nullptr; + } + cJSON_Delete(heart_root); + return data; + } + // 保存血氧数据 + bool HealthService::UpdateHealthData(const BloodOxygenData &data) + { + // 判断文件夹是否存在 + if (!CreateHealthFolder()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file"); + return false; + } + + // 判断文件是否存在 不存在即创建 并打开以输出模式 + std::ofstream outFile(BLOOD_JSON_PATH, std::ios::trunc); + if (!outFile.is_open()) + { + // 文件创建失败 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create or open JSON file for writing"); + return false; + } + + // 创建一个 JSON 对象 + cJSON *oxygen_root = cJSON_CreateObject(); + if (oxygen_root == NULL) + { + outFile.close(); + return false; + } + + cJSON_AddItemToObject(oxygen_root, "value", cJSON_CreateNumber(data.SPO2)); + cJSON_AddItemToObject(oxygen_root, "timestamp", cJSON_CreateNumber(data.timestamp)); + + char *jsonData = cJSON_Print(oxygen_root); + if (jsonData == NULL) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to generate JSON data"); + cJSON_free(oxygen_root); + outFile.close(); + return false; + } + + // 写入 JSON 数据到文件 + outFile << jsonData; + + cJSON_free(oxygen_root); + free(jsonData); + outFile.close(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHealthData SPO2 JSON is ok"); + + /* 存储bin文件[协议使用] */ + std::string binFilePath = GetBinFilePath(HEALTH_TYPE_OXYGEN); + FILE *fp = fopen(binFilePath.c_str(), "ab+"); + if (fp == NULL) + { + return false; + } + + fwrite(&data.timestamp, 4, 1, fp); + fwrite(&data.SPO2, 1, 1, fp); + + fclose(fp); + + return true; + } -// 存储心率 -bool HealthService::UpdateHealthData(const HeartRateData &data) { - // 判断文件夹是否存在 - if (!CreateHealthFolder()) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file"); - return false; - } - - // 判断文件是否存在 不存在即创建 并打开以输出模式 - std::ofstream outFile(HEART_JSON_PATH, std::ios::trunc); - if (!outFile.is_open()) { - // 文件创建失败 - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, - "Failed to create or open JSON file for writing"); - return false; - } - - // 创建一个 JSON 对象 - cJSON *heart_root = cJSON_CreateObject(); - if (heart_root == NULL) { - outFile.close(); - return false; - } - - cJSON_AddItemToObject(heart_root, "value", cJSON_CreateNumber(data.Heart)); - cJSON_AddItemToObject(heart_root, "timestamp", - cJSON_CreateNumber(data.timestamp)); - - char *jsonData = cJSON_Print(heart_root); - if (jsonData == NULL) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to generate JSON data"); - cJSON_free(heart_root); - outFile.close(); - return false; - } - - // 写入 JSON 数据到文件 - outFile << jsonData; - - cJSON_free(heart_root); - free(jsonData); - outFile.close(); - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHealthData Heart JSON is ok"); - - // 写入文件到当天历史数据 - UpdateHourlyHeartRate(data.timestamp, data.Heart); - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHourlyHeartRate is ok"); - - /* 存储bin文件[协议使用] */ - std::string binFilePath = GetBinFilePath(HEALTH_TYPE_HEART); - FILE *fp = fopen(binFilePath.c_str(), "ab+"); - if (fp == NULL) { - return false; - } - - fwrite(&data.timestamp, 4, 1, fp); - fwrite(&data.Heart, 1, 1, fp); - - fclose(fp); - - return true; -} -// 清空健康数据 -bool HealthService::CleanHealthData() { - ClearHourlyHeartRates(); - HeartModel::GetInstance()->ClearDisplayData(); - BloodOxygenModel::GetInstance()->ClearDisplayData(); - - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CleanHealthData is ok"); - return true; -} + // 存储心率 + bool HealthService::UpdateHealthData(const HeartRateData &data) + { + // 判断文件夹是否存在 + if (!CreateHealthFolder()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file"); + return false; + } + + // 判断文件是否存在 不存在即创建 并打开以输出模式 + std::ofstream outFile(HEART_JSON_PATH, std::ios::trunc); + if (!outFile.is_open()) + { + // 文件创建失败 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create or open JSON file for writing"); + return false; + } + + // 创建一个 JSON 对象 + cJSON *heart_root = cJSON_CreateObject(); + if (heart_root == NULL) + { + outFile.close(); + return false; + } + + cJSON_AddItemToObject(heart_root, "value", cJSON_CreateNumber(data.Heart)); + cJSON_AddItemToObject(heart_root, "timestamp", cJSON_CreateNumber(data.timestamp)); + + char *jsonData = cJSON_Print(heart_root); + if (jsonData == NULL) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to generate JSON data"); + cJSON_free(heart_root); + outFile.close(); + return false; + } + + // 写入 JSON 数据到文件 + outFile << jsonData; + + cJSON_free(heart_root); + free(jsonData); + outFile.close(); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHealthData Heart JSON is ok"); + + // 写入文件到当天历史数据 + UpdateHourlyHeartRate(data.timestamp, data.Heart); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHourlyHeartRate is ok"); + + /* 存储bin文件[协议使用] */ + std::string binFilePath = GetBinFilePath(HEALTH_TYPE_HEART); + FILE *fp = fopen(binFilePath.c_str(), "ab+"); + if (fp == NULL) + { + return false; + } + + fwrite(&data.timestamp, 4, 1, fp); + fwrite(&data.Heart, 1, 1, fp); + + fclose(fp); + + return true; + } + // 清空健康数据 + bool HealthService::CleanHealthData() + { + ClearHourlyHeartRates(); + HeartModel::GetInstance()->ClearDisplayData(); + BloodOxygenModel::GetInstance()->ClearDisplayData(); -HealthState HealthService::GetHealthCurrent() { return healthState_; } -void HealthService::SetHealthCurrent(HealthState healthState) { - healthState_ = healthState; -} -/* ------------------------------- 心率当天历史数据处理 - * ------------------------------ */ -static constexpr const char *HEART_DATA_PATH = - "/user/userdata/health/heart_history.bin"; -bool HealthService::LoadDailyHeartRate() -{ - // 初始化心率数组为 0 - ClearHourlyHeartRates(); - - // 获取当前时间 - time_t currentTime = time(nullptr); - tm *currentTm = localtime(¤tTime); - - // 检查是否为同一天 - std::ifstream file(HEART_DATA_PATH, std::ios::binary); - if (!file.is_open()) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Unable to open heart rate data file for reading"); - return false; // 文件打开失败 - } - - // 读取时间戳 - file.read(reinterpret_cast(&lastLoadTime), sizeof(lastLoadTime)); - - // 检查是否为同一天 - if (lastLoadTime != 0) // 确保 lastLoadTime 有效 - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "************************************************"); - tm *lastTm = localtime(&lastLoadTime); - if (currentTm->tm_year == lastTm->tm_year && - currentTm->tm_yday == lastTm->tm_yday) - { - // 如果是同一天,直接读取心率数据 - for (int i = 0; i < MAX_HOURS; ++i) - { - uint16_t heartRate; - if (!file.read(reinterpret_cast(&heartRate), sizeof(heartRate))) // 读取心率 - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Failed to read heart rate data."); - file.close(); - return false; // 读取失败 - } - dailyHeartRates[i] = heartRate; - - // 打印心率数据 - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Hour %d: Heart Rate %d", i, heartRate); - } - - // 计算最大和最小心率 - int maxHeartRate = dailyHeartRates[0]; - int minHeartRate = dailyHeartRates[0]; - - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "maxHeartRate %d: minHeartRate %d", minHeartRate, maxHeartRate); - - for (int i = 1; i < MAX_HOURS; ++i) - { - if (dailyHeartRates[i] > maxHeartRate) - { - maxHeartRate = dailyHeartRates[i]; - } - if ((minHeartRate == 0 && dailyHeartRates[i] != 0)||(dailyHeartRates[i] < minHeartRate && dailyHeartRates[i] != 0)) - { - minHeartRate = dailyHeartRates[i]; - } - } - - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "for maxHeartRate %d: minHeartRate %d", minHeartRate, maxHeartRate); - - // 设置最大和最小心率 - HeartModel::GetInstance()->SetTopAndBottom(maxHeartRate, minHeartRate); - - file.close(); - return true; // 成功读取 - } - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "************************************************"); - } - - // 如果不是同一天,关闭文件 - file.close(); - - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Not same-day data"); - return false; // 不是同一天 -} - -bool HealthService::SaveDailyHeartRate() { - // 判断文件是否存在 不存在即创建 并打开以输出模式 - std::ofstream outFile(HEART_DATA_PATH, std::ios::trunc); - if (!outFile.is_open()) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, - "Error: Unable to open heart rate data file for reading"); - return false; // 文件打开失败 - } - - // 存储一个时间戳最前面 - time_t currentTime = time(nullptr); - outFile.write(reinterpret_cast(¤tTime), - sizeof(currentTime)); - - for (int i = 0; i < MAX_HOURS; ++i) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, - "SaveDailyHeartRate:: Time is %d Heart is %d", i, - dailyHeartRates[i]); - if (!outFile.write(reinterpret_cast(&dailyHeartRates[i]), - sizeof(dailyHeartRates[i]))) // 保存心率值 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CleanHealthData is ok"); + return true; + } + + HealthState HealthService::GetHealthCurrent() { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, - "Error: Failed to write heart rate data."); - outFile.close(); - return false; // 写入失败 + return healthState_; + } + void HealthService::SetHealthCurrent(HealthState healthState) + { + healthState_ = healthState; + } + /* ------------------------------- 心率当天历史数据处理 ------------------------------ */ + static constexpr const char *HEART_DATA_PATH = "/user/userdata/health/heart_history.bin"; + bool HealthService::LoadDailyHeartRate() + { + // 初始化心率数组为 0 + ClearHourlyHeartRates(); + + // 获取当前时间 + time_t currentTime = time(nullptr); + tm *currentTm = localtime(¤tTime); + + // 检查是否为同一天 + std::ifstream file(HEART_DATA_PATH, std::ios::binary); + if (!file.is_open()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Unable to open heart rate data file for reading"); + return false; // 文件打开失败 + } + + // 读取时间戳 + file.read(reinterpret_cast(&lastLoadTime), sizeof(lastLoadTime)); + + // 检查是否为同一天 + if (lastLoadTime != 0) // 确保 lastLoadTime 有效 + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "************************************************"); + tm *lastTm = localtime(&lastLoadTime); + if (currentTm->tm_year == lastTm->tm_year && + currentTm->tm_yday == lastTm->tm_yday) + { + // 如果是同一天,直接读取心率数据 + for (int i = 0; i < MAX_HOURS; ++i) + { + uint16_t heartRate; + if (!file.read(reinterpret_cast(&heartRate), sizeof(heartRate))) // 读取心率 + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Failed to read heart rate data."); + file.close(); + return false; // 读取失败 + } + dailyHeartRates[i] = heartRate; + + // 打印心率数据 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Hour %d: Heart Rate %d", i, heartRate); + } + file.close(); + return true; // 成功读取 + } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "************************************************"); + } + + // 如果不是同一天,关闭文件 + file.close(); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Not same-day data"); + return false; // 不是同一天 } - } - outFile.close(); - return true; // 成功保存 -} -void HealthService::ClearHourlyHeartRates() { - // 清空心率数据,将数组置为 0 - for (int i = 0; i < MAX_HOURS; ++i) { - dailyHeartRates[i] = 0; - } -} -void HealthService::UpdateHourlyHeartRate(time_t timestamp, - uint16_t heartRate) { - // 将时间戳转换为 tm 结构体 - struct tm *timeInfo = localtime(×tamp); // 使用 localtime 获取本地时间 - // 提取小时 - uint16_t hour = static_cast(timeInfo->tm_hour); + bool HealthService::SaveDailyHeartRate() + { + // 判断文件是否存在 不存在即创建 并打开以输出模式 + std::ofstream outFile(HEART_DATA_PATH, std::ios::trunc); + if (!outFile.is_open()) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Unable to open heart rate data file for reading"); + return false; // 文件打开失败 + } + + // 存储一个时间戳最前面 + time_t currentTime = time(nullptr); + outFile.write(reinterpret_cast(¤tTime), sizeof(currentTime)); + + for (int i = 0; i < MAX_HOURS; ++i) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveDailyHeartRate:: Time is %d Heart is %d", i, dailyHeartRates[i]); + if (!outFile.write(reinterpret_cast(&dailyHeartRates[i]), sizeof(dailyHeartRates[i]))) // 保存心率值 + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Failed to write heart rate data."); + outFile.close(); + return false; // 写入失败 + } + } + outFile.close(); + return true; // 成功保存 + } + void HealthService::ClearHourlyHeartRates() + { + // 清空心率数据,将数组置为 0 + for (int i = 0; i < MAX_HOURS; ++i) + { + dailyHeartRates[i] = 0; + } + } + void HealthService::UpdateHourlyHeartRate(time_t timestamp, uint16_t heartRate) + { + // 将时间戳转换为 tm 结构体 + struct tm *timeInfo = localtime(×tamp); // 使用 localtime 获取本地时间 - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, - "Updating heart rate: 小时 %d, 心率值 %d", hour, heartRate); + // 提取小时 + uint16_t hour = static_cast(timeInfo->tm_hour); - // 确保 hour 在有效范围内,并且心率不是异常值(例如负值) - if (hour < MAX_HOURS && heartRate > 0) // 心率不应为负 并且 小时不能为24 - { - dailyHeartRates[hour] = heartRate; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Updating heart rate: 小时 %d, 心率值 %d", hour, heartRate); - // 记录目前更新时间点 - currenthour = hour; - } -} + // 确保 hour 在有效范围内,并且心率不是异常值(例如负值) + if (hour < MAX_HOURS && heartRate > 0) // 心率不应为负 并且 小时不能为24 + { + dailyHeartRates[hour] = heartRate; -uint16_t HealthService::GetHourlyHeartRate(uint16_t hour) { - // 返回指定小时的心率 - if (hour < MAX_HOURS) { - return dailyHeartRates[hour]; // 默认为 0 如果未更新 - } - return 0; // 或者返回一个异常值 -} + // 记录目前更新时间点 + currenthour = hour; + } + } -uint16_t HealthService::GetCurrentHour() { - // 返回目前小时 - return currenthour; + uint16_t HealthService::GetHourlyHeartRate(uint16_t hour) + { + // 返回指定小时的心率 + if (hour < MAX_HOURS) + { + return dailyHeartRates[hour]; // 默认为 0 如果未更新 + } + return 0; // 或者返回一个异常值 + } + + uint16_t HealthService::GetCurrentHour() + { + // 返回目前小时 + return currenthour; + } } -} // namespace OHOS diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartModel.h b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartModel.h index 9f47cc005..4827a8abc 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartModel.h +++ b/code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartModel.h @@ -150,8 +150,7 @@ public: std::string GetCheckString(); uint16_t *GetArrayData(); void SetArrayData(); - void SetTopAndBottom(int maxheart,int minheart); - void UpdateTopAndBottom(int heart); + private: HealthAllDatas healthDatas; uint16_t pretime{0}; @@ -168,8 +167,8 @@ private: uint16_t displayheart; // 显示心率 uint16_t currentheart; // 保存心率 - uint16_t displayheart_max = 0; // 显示最大心率 - uint16_t displayheart_min = 0; // 显示最小心率 + uint16_t displayheart_max; // 显示最大心率 + uint16_t displayheart_min; // 显示最小心率 uint32 timestamp_ms; // 检测时间(存(时、分),大于24小时,改为1天前,小于1分钟为刚刚) diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartChartView.cpp b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartChartView.cpp index 998938959..145cb4d55 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartChartView.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartChartView.cpp @@ -562,7 +562,7 @@ UIViewGroup *HeartChartView::GetchartGroup() { } HeartImageAnimator(); //暂时屏蔽 InitChartView(); - // UpdateChartConfig(); 屏蔽动态适配 + UpdateChartConfig(); SetDataChart(); SetLastHeart(); SetDataTopAndBottom(); @@ -585,7 +585,7 @@ void HeartChartView::OnStart() { HeartImageAnimator(); InitChartView(); - // UpdateChartConfig(); 屏蔽动态适配 + UpdateChartConfig(); SetDataChart(); SetLastHeart(); SetDataTopAndBottom(); diff --git a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartModel.cpp b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartModel.cpp index 06499a2d1..8966addd0 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartModel.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartModel.cpp @@ -200,7 +200,7 @@ HeartModel::HeartModel() { timestamp_ms = 0; } //配置动态数组 - // SetArrayData(); + SetArrayData(); } HeartModel::~HeartModel() { @@ -576,6 +576,20 @@ void HeartModel::UpHeartdata(uint16_t heart) { currentheart = displayheart; // 更新当前心率 valid_counter_++; // 增加有效计数器 disvalid_counter_ = 0; // 清空无效计数器 + + // 更新最大和最小心率 + displayheart_max = + (displayheart_max < displayheart ? displayheart : displayheart_max); + + // 确保最小心率的第一次赋值大于50 + if (displayheart_min == 0 && displayheart > MIN_DISPLAY_HEART) { + displayheart_min = displayheart; // 初始化最小心率 + } else { + displayheart_min = + (displayheart_min > displayheart && displayheart > MIN_DISPLAY_HEART) + ? displayheart + : displayheart_min; + } } else { disvalid_counter_++; // 增加无效计数器 valid_counter_ = 0; // 清零有效计数器 @@ -597,7 +611,6 @@ void HeartModel::UpHeartdata(uint16_t heart) { "检测结果: 成功 valid_counter: %d currentheart: %d", valid_counter_, currentheart); SetResult(HeartResult::SUCCESS); // 标记为成功检测 - UpdateTopAndBottom(currentheart); Heart_Stop(); return; } @@ -639,20 +652,6 @@ void HeartModel::CleanAllData(void) { } } -//设置最大最小值 -void HeartModel::SetTopAndBottom(int maxheart, int minheart) { - displayheart_max = maxheart; - displayheart_min = minheart; -} -//更新最大最小值 -void HeartModel::UpdateTopAndBottom(int heart) { - if (heart > displayheart_max) { - displayheart_max = heart; - } else if (heart < displayheart_min || displayheart_min == 0) { - displayheart_min = heart; - } -} - //配置5个动态心率数据 //最大 最小 void HeartModel::SetArrayData() { @@ -698,7 +697,6 @@ uint16_t *HeartModel::GetArrayData() { return dynamic_heartrate; } // 获取检测字符串 // 获取检测字符串 -// TODO: 适配多国语言 std::string HeartModel::GetCheckString() { std::string check_string = "检测结果未知"; // 默认返回值 -- 2.17.1