#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);
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(¤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<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 *>(¤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<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(¤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<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 *>(¤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<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(×tamp); // 使用 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(×tamp); // 使用 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