修改心率的显示最大最小值为实际值 986/1 986/head
authorCaisking <3449750381@qq.com>
Wed, 18 Sep 2024 12:52:35 +0000 (20:52 +0800)
committerCaisking <3449750381@qq.com>
Wed, 18 Sep 2024 12:52:35 +0000 (20:52 +0800)
code/sdk/application/wearable/fd230app/nativeui/heart_blood/health_service/health_service.cpp
code/sdk/application/wearable/fd230app/nativeui/heartrate/include/HeartModel.h
code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartChartView.cpp
code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartModel.cpp

index 6d9550e..a8491bd 100644 (file)
@@ -1,36 +1,32 @@
 #include "health_service.h"
-#include <iostream>
-#include "wearable_log.h"
+#include "bloodoxygen/include/BloodOxygenModel.h"
 #include "cJSON.h"
-#include <sys/stat.h>
-#include <ctime>
-#include "kv_store.h"
 #include "custom_utils.h"
+#include "heartrate/include/HeartModel.h"
+#include "kv_store.h"
+#include "wearable_log.h"
+#include <cstdint>
+#include <ctime>
 #include <fstream>
+#include <iostream>
 #include <sstream>
 #include <string>
-#include <cstdint>
-#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;
-        }
-    }
+#include <sys/stat.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);
@@ -38,478 +34,471 @@ namespace OHOS
         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;
+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;
     }
-    const char *GET_HEALTH_JSON_PATH_C_STR_OXYGEN()
-    {
-        return HEALTH_JSON_PATH_OXYGEN;
+  }
+  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;
     }
-    /* --------------------------------- 文件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;
+  }
+  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;
     }
+  }
 
-    /*生成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";
-    }
-
-    /* --------------------------------- 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";
+  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;
-    }
+/*生成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;
 
-    // 存储心率
-    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();
+  return healthTypePath + currentDate + ".bin";
+}
 
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CleanHealthData  is ok");
-        return true;
-    }
+/* --------------------------------- 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;
+}
 
-    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(&currentTime);
-
-        // 检查是否为同一天
-        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<char *>(&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<char *>(&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; // 不是同一天
-    }
+// 存储心率
+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::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<const char *>(&currentTime), 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<const char *>(&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()
+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(&currentTime);  
+
+    // 检查是否为同一天  
+    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<char *>(&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<char *>(&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<const char *>(&currentTime),
+                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<const char *>(&dailyHeartRates[i]),
+                       sizeof(dailyHeartRates[i]))) // 保存心率值
     {
-        // 清空心率数据,将数组置为 0
-        for (int i = 0; i < MAX_HOURS; ++i)
-        {
-            dailyHeartRates[i] = 0;
-        }
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "Error: Failed to write heart rate data.");
+      outFile.close();
+      return false; // 写入失败
     }
-    void HealthService::UpdateHourlyHeartRate(time_t timestamp, uint16_t heartRate)
-    {
-        // 将时间戳转换为 tm 结构体
-        struct tm *timeInfo = localtime(&timestamp); // 使用 localtime 获取本地时间
+  }
+  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(&timestamp); // 使用 localtime 获取本地时间
 
-        // 提取小时
-        uint16_t hour = static_cast<uint16_t>(timeInfo->tm_hour);
+  // 提取小时
+  uint16_t hour = static_cast<uint16_t>(timeInfo->tm_hour);
 
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Updating heart rate: 小时 %d, 心率值 %d", hour, heartRate);
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                "Updating heart rate: 小时 %d, 心率值 %d", hour, heartRate);
 
-        // 确保 hour 在有效范围内,并且心率不是异常值(例如负值)
-        if (hour < MAX_HOURS && heartRate > 0) // 心率不应为负 并且 小时不能为24
-        {
-            dailyHeartRates[hour] = heartRate;
+  // 确保 hour 在有效范围内,并且心率不是异常值(例如负值)
+  if (hour < MAX_HOURS && heartRate > 0) // 心率不应为负 并且 小时不能为24
+  {
+    dailyHeartRates[hour] = heartRate;
 
-            // 记录目前更新时间点
-            currenthour = hour;
-        }
-    }
+    // 记录目前更新时间点
+    currenthour = hour;
+  }
+}
 
-    uint16_t HealthService::GetHourlyHeartRate(uint16_t hour)
-    {
-        // 返回指定小时的心率
-        if (hour < MAX_HOURS)
-        {
-            return dailyHeartRates[hour]; // 默认为 0 如果未更新
-        }
-        return 0; // 或者返回一个异常值
-    }
+uint16_t HealthService::GetHourlyHeartRate(uint16_t hour) {
+  // 返回指定小时的心率
+  if (hour < MAX_HOURS) {
+    return dailyHeartRates[hour]; // 默认为 0 如果未更新
+  }
+  return 0; // 或者返回一个异常值
+}
 
-    uint16_t HealthService::GetCurrentHour()
-    {
-        // 返回目前小时
-        return currenthour;
-    }
+uint16_t HealthService::GetCurrentHour() {
+  // 返回目前小时
+  return currenthour;
 }
+} // namespace OHOS
index 4827a8a..9f47cc0 100644 (file)
@@ -150,7 +150,8 @@ public:
   std::string GetCheckString();\r
   uint16_t *GetArrayData();\r
   void SetArrayData();\r
-\r
+  void SetTopAndBottom(int maxheart,int minheart);\r
+  void UpdateTopAndBottom(int heart);\r
 private:\r
   HealthAllDatas healthDatas;\r
   uint16_t pretime{0};\r
@@ -167,8 +168,8 @@ private:
 \r
   uint16_t displayheart;     // 显示心率\r
   uint16_t currentheart;     // 保存心率\r
-  uint16_t displayheart_max; // 显示最大心率\r
-  uint16_t displayheart_min; // 显示最小心率\r
+  uint16_t displayheart_max = 0; // 显示最大心率\r
+  uint16_t displayheart_min = 0; // 显示最小心率\r
 \r
   uint32\r
       timestamp_ms; // 检测时间(存(时、分),大于24小时,改为1天前,小于1分钟为刚刚)\r
index 7b26631..6584bba 100644 (file)
@@ -561,7 +561,7 @@ UIViewGroup *HeartChartView::GetchartGroup() {
   }
   // HeartImageAnimator(); 暂时屏蔽
   InitChartView();
-  UpdateChartConfig();
+  // UpdateChartConfig(); 屏蔽动态适配
   SetDataChart();
   SetLastHeart();
   SetDataTopAndBottom();
@@ -582,7 +582,7 @@ void HeartChartView::OnStart() {
 
   HeartImageAnimator();
   InitChartView();
-  UpdateChartConfig();
+  // UpdateChartConfig(); 屏蔽动态适配
   SetDataChart();
   SetLastHeart();
   SetDataTopAndBottom();
index f21f91f..aa044d2 100644 (file)
@@ -200,7 +200,7 @@ HeartModel::HeartModel() {
     timestamp_ms = 0;\r
   }\r
   //配置动态数组\r
-  SetArrayData();\r
+  // SetArrayData();\r
 }\r
 \r
 HeartModel::~HeartModel() {\r
@@ -574,20 +574,6 @@ void HeartModel::UpHeartdata(uint16_t heart) {
     currentheart = displayheart; // 更新当前心率\r
     valid_counter_++;            // 增加有效计数器\r
     disvalid_counter_ = 0;       // 清空无效计数器\r
-\r
-    // 更新最大和最小心率\r
-    displayheart_max =\r
-        (displayheart_max < displayheart ? displayheart : displayheart_max);\r
-\r
-    // 确保最小心率的第一次赋值大于50\r
-    if (displayheart_min == 0 && displayheart > MIN_DISPLAY_HEART) {\r
-      displayheart_min = displayheart; // 初始化最小心率\r
-    } else {\r
-      displayheart_min =\r
-          (displayheart_min > displayheart && displayheart > MIN_DISPLAY_HEART)\r
-              ? displayheart\r
-              : displayheart_min;\r
-    }\r
   } else {\r
     disvalid_counter_++; // 增加无效计数器\r
     valid_counter_ = 0;  // 清零有效计数器\r
@@ -609,6 +595,7 @@ void HeartModel::UpHeartdata(uint16_t heart) {
                   "检测结果: 成功 valid_counter: %d currentheart: %d",\r
                   valid_counter_, currentheart);\r
     SetResult(HeartResult::SUCCESS); // 标记为成功检测\r
+    UpdateTopAndBottom(currentheart);\r
     Heart_Stop();\r
     return;\r
   }\r
@@ -649,6 +636,20 @@ void HeartModel::CleanAllData(void) {
   }\r
 }\r
 \r
+//设置最大最小值\r
+void HeartModel::SetTopAndBottom(int maxheart, int minheart) {\r
+  displayheart_max = maxheart;\r
+  displayheart_min = minheart;\r
+}\r
+//更新最大最小值\r
+void HeartModel::UpdateTopAndBottom(int heart) {\r
+  if (heart > displayheart_max) {\r
+    displayheart_max = heart;\r
+  } else if (heart < displayheart_min || displayheart_min == 0) {\r
+    displayheart_min = heart;\r
+  }\r
+}\r
+\r
 //配置5个动态心率数据\r
 //最大 最小\r
 void HeartModel::SetArrayData() {\r
@@ -694,6 +695,7 @@ uint16_t *HeartModel::GetArrayData() { return dynamic_heartrate; }
 \r
 // 获取检测字符串\r
 // 获取检测字符串\r
+// TODO: 适配多国语言\r
 std::string HeartModel::GetCheckString() {\r
   std::string check_string = "检测结果未知"; // 默认返回值\r
 \r