#include "cJSON.h"
#include <sys/stat.h>
#include <ctime>
+#include "kv_store.h"
namespace OHOS
{
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;
- // 判断HEALTH_JSON_PATH是否存在 不存在就创建
if (stat(HEALTH_JSON_PATH, &info) != 0)
{
if (mkdir(HEALTH_JSON_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0)
return false; // Failed to create folder
}
}
- // 判断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)
return false; // Failed to create folder
}
}
- // 判断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)
return healthTypePath + currentDate + ".json";
}
- 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;
- }
+ // 加载 JSON 数据
bool HealthService::LoadJsonData(uint8_t type)
{
- // 创建健康数据文件夹
if (!CreateHealthFolder())
{
return false;
}
- // 获取当天日期对应的JSON文件路径
std::string jsonFilePath = GetJsonFilePath(type);
printf("GetJsonFilePath:%s\r\n", jsonFilePath.c_str());
+
std::ifstream inFile(jsonFilePath);
+ if (!inFile.is_open())
+ {
+ printf("Failed to open JSON file.\r\n");
+ FILE *fp = fopen(jsonFilePath.c_str(), "wb");
+ return false;
+ }
- // 读取JSON文件内容
std::string jsonDataString((std::istreambuf_iterator<char>(inFile)), std::istreambuf_iterator<char>());
const char *jsonData = jsonDataString.c_str();
printf("jsonData:%s\r\n", jsonData);
+ if (jsonDataString.empty())
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " jsonDataString is error");
+ // printf("JSON file is empty.\r\n");
+ return false;
+ }
+
if (type == HEALTH_TYPE_HEART)
{
heart_root = cJSON_Parse(jsonData);
return true;
}
+ // 释放 JSON 数据
+ void HealthService::ReleaseJsonData(uint8_t type)
+ {
+ if (type == HEALTH_TYPE_HEART)
+ {
+ cJSON_Delete(heart_root);
+ }
+ if (type == HEALTH_TYPE_OXYGEN)
+ {
+ cJSON_Delete(oxygen_root);
+ }
+ }
+ // 读取血氧数据
BloodOxygenData *HealthService::ReadBloodOxygenData()
{
- LoadJsonData(HEALTH_TYPE_OXYGEN);
+ if (!LoadJsonData(HEALTH_TYPE_OXYGEN))
+ {
+ return nullptr;
+ }
+
BloodOxygenData *data = new BloodOxygenData();
cJSON *latestData = cJSON_GetObjectItem(oxygen_root, "spo2_latest_data");
- data->SPO2 = cJSON_GetObjectItem(latestData, "value")->valueint;
- data->timestamp = cJSON_GetObjectItem(latestData, "timestamp")->valuedouble;
- cJSON_Delete(oxygen_root);
+ if (latestData != NULL)
+ {
+ data->SPO2 = cJSON_GetObjectItem(latestData, "value")->valueint;
+ data->timestamp = cJSON_GetObjectItem(latestData, "timestamp")->valuedouble;
+ }
+
+ ReleaseJsonData(HEALTH_TYPE_OXYGEN);
+ return data;
+ }
+ HeartRateData *HealthService::ReadHeartRateData()
+ {
+ if (!LoadJsonData(HEALTH_TYPE_HEART))
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadJsonData is error ");
+ return nullptr;
+ }
+
+ HeartRateData *data = new HeartRateData();
+ cJSON *latestData = cJSON_GetObjectItem(heart_root, "heart_latest_data");
+ if (latestData != NULL)
+ {
+ // 读取心率值
+ data->Heart = cJSON_GetObjectItem(latestData, "value")->valueint;
+ data->timestamp = static_cast<uint32_t>(cJSON_GetObjectItem(latestData, "timestamp")->valueint);
+
+ char *jsonStr = cJSON_Print(heart_root);
+ if (jsonStr != NULL)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRootJSONData: %s", jsonStr);
+ cJSON_free(jsonStr);
+ }
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ReadHeartRateData: value %d timestamp %d", data->Heart, data->timestamp);
+ }
+ ReleaseJsonData(HEALTH_TYPE_HEART);
+
return data;
}
+
bool HealthService::UpdateBloodOxygenData(const BloodOxygenData &data)
{
- LoadJsonData(HEALTH_TYPE_OXYGEN);
- cJSON *latestData = cJSON_GetObjectItem(oxygen_root, "spo2_latest_data");
- if (latestData == NULL)
+ if (!LoadJsonData(HEALTH_TYPE_OXYGEN))
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadJsonData is error");
+ // return false;
+ }
+
+ if (oxygen_root == nullptr)
{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "oxygen_root is first");
+ oxygen_root = cJSON_CreateObject();
+ if (oxygen_root == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create cJSON object for oxygen_root");
+ return false;
+ }
+ cJSON_AddItemToObject(oxygen_root, "spo2_latest_data", cJSON_CreateObject());
+ cJSON_AddItemToObject(oxygen_root, "spo2_data_list", cJSON_CreateArray());
+ }
+
+ cJSON *latestData = cJSON_GetObjectItemCaseSensitive(oxygen_root, "spo2_latest_data");
+ if (latestData == NULL || !cJSON_IsObject(latestData))
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get spo2_latest_data object");
+ cJSON_Delete(oxygen_root);
+ oxygen_root = nullptr;
return false;
}
- cJSON_ReplaceItemInObject(latestData, "value", cJSON_CreateNumber(data.SPO2));
- cJSON_ReplaceItemInObject(latestData, "timestamp", cJSON_CreateNumber(data.timestamp));
- // 将数据添加到列表的最后
+ cJSON *SPO2 = cJSON_GetObjectItemCaseSensitive(latestData, "value");
+ if (SPO2 == nullptr && cJSON_IsNumber(SPO2))
+ {
+ // Add spo2_latest_data
+ cJSON_AddItemToObject(latestData, "value", cJSON_CreateNumber(data.SPO2));
+ cJSON_AddItemToObject(latestData, "timestamp", cJSON_CreateNumber(data.timestamp));
+ }
+ else
+ {
+ cJSON_ReplaceItemInObject(latestData, "value", cJSON_CreateNumber(data.SPO2));
+ cJSON_ReplaceItemInObject(latestData, "timestamp", cJSON_CreateNumber(data.timestamp));
+ }
+
+ // Update or add to spo2_data_list
cJSON *dataList = cJSON_GetObjectItem(oxygen_root, "spo2_data_list");
if (dataList != NULL && cJSON_IsArray(dataList))
{
- cJSON *newData = cJSON_CreateObject();
- cJSON_AddItemToObject(newData, "value", cJSON_CreateNumber(data.SPO2));
- cJSON_AddItemToObject(newData, "timestamp", cJSON_CreateNumber(data.timestamp));
- cJSON_AddItemToArray(dataList, newData);
+ // Check if data already exists in the list
+ bool dataExists = false;
+ cJSON *dataItem = NULL;
+ cJSON_ArrayForEach(dataItem, dataList)
+ {
+ cJSON *timestampItem = cJSON_GetObjectItemCaseSensitive(dataItem, "timestamp");
+ if (timestampItem != NULL && cJSON_IsNumber(timestampItem) && timestampItem->valuedouble == data.timestamp)
+ {
+ cJSON_ReplaceItemInObject(dataItem, "value", cJSON_CreateNumber(data.SPO2));
+ dataExists = true;
+ break;
+ }
+ }
+
+ if (!dataExists)
+ {
+ cJSON *newData = cJSON_CreateObject();
+ cJSON_AddItemToObject(newData, "value", cJSON_CreateNumber(data.SPO2));
+ cJSON_AddItemToObject(newData, "timestamp", cJSON_CreateNumber(data.timestamp));
+ cJSON_AddItemToArray(dataList, newData);
+ }
}
- if (UpdateJsonData(HEALTH_TYPE_OXYGEN) == false)
+
+ if (!UpdateJsonData(HEALTH_TYPE_OXYGEN))
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateJsonData is error");
- cJSON_Delete(oxygen_root);
+ printf("UpdateJsonData failed.\r\n");
+ ReleaseJsonData(HEALTH_TYPE_OXYGEN);
return false;
}
- cJSON_Delete(oxygen_root);
+
+ ReleaseJsonData(HEALTH_TYPE_OXYGEN);
return true;
}
- HeartRateData *HealthService::ReadHeartRateData()
+ bool HealthService::UpdateHeartRateData(const HeartRateData &data)
{
- if (!LoadJsonData(HEALTH_TYPE_HEART) && (heart_root == nullptr))
+ if (!LoadJsonData(HEALTH_TYPE_HEART))
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ReadHeartRateData heart_root is error ");
- return nullptr;
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadJsonData is error");
+ // return false;
}
- HeartRateData *data = new HeartRateData();
- cJSON *latestData = cJSON_GetObjectItem(heart_root, "heart_latest_data");
- // 读取心率值
- data->Heart = cJSON_GetObjectItem(latestData, "value")->valueint;
- // 读取时间戳,并转换为 uint32_t 类型
- data->timestamp = static_cast<uint32_t>(cJSON_GetObjectItem(latestData, "timestamp")->valueint);
- // 打印 JSON 数据
- char *jsonStr = cJSON_Print(heart_root);
- if (jsonStr != NULL)
- {
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartRootJSONData: %s", jsonStr);
- cJSON_free(jsonStr);
- }
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ReadHeartRateData: value %d timestamp %d", data->Heart, data->timestamp);
- cJSON_Delete(heart_root);
- return data;
- }
- bool HealthService::UpdateHeartRateData(const HeartRateData &data)
- {
- LoadJsonData(HEALTH_TYPE_HEART);
- cJSON *latestData = cJSON_GetObjectItem(heart_root, "heart_latest_data");
- if (latestData == NULL)
+ if (heart_root == nullptr)
{
+ heart_root = cJSON_CreateObject();
+ if (heart_root == nullptr)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to create cJSON object for heart_root");
+ return false;
+ }
+
+ cJSON_AddItemToObject(heart_root, "heart_latest_data", cJSON_CreateObject());
+ cJSON_AddItemToObject(heart_root, "heart_data_list", cJSON_CreateArray());
+ }
+
+ cJSON *latestData = cJSON_GetObjectItemCaseSensitive(heart_root, "heart_latest_data");
+ if (latestData == NULL || !cJSON_IsObject(latestData))
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get heart_latest_data object");
+ cJSON_Delete(heart_root);
+ heart_root = nullptr;
return false;
}
- cJSON_ReplaceItemInObject(latestData, "value", cJSON_CreateNumber(data.Heart));
- cJSON_ReplaceItemInObject(latestData, "timestamp", cJSON_CreateNumber(data.timestamp));
- // 将数据添加到列表的最后
- cJSON *dataList = cJSON_GetObjectItem(heart_root, "heart_data_list");
- // 获取当前数据列表长度
- int numData = cJSON_GetArraySize(dataList);
+ cJSON *Heart = cJSON_GetObjectItemCaseSensitive(latestData, "value");
+ if (Heart == nullptr && !cJSON_IsNumber(Heart))
+ {
+ // Add heart_latest_data
+ cJSON_AddItemToObject(latestData, "value", cJSON_CreateNumber(data.Heart));
+ cJSON_AddItemToObject(latestData, "timestamp", cJSON_CreateNumber(data.timestamp));
+ }
+ else
+ {
+ cJSON_ReplaceItemInObject(latestData, "value", cJSON_CreateNumber(data.Heart));
+ cJSON_ReplaceItemInObject(latestData, "timestamp", cJSON_CreateNumber(data.timestamp));
+ }
- // 如果数据列表长度已经达到360个,不再添加新数据
- if (numData >= 360)
+ // // 更新heart_latest_data中的value和timestamp值
+ // cJSON_AddItemToObject(latestData, "value", cJSON_CreateNumber(data.Heart));
+ // cJSON_AddItemToObject(latestData, "timestamp", cJSON_CreateNumber(data.timestamp));
+
+ cJSON *dataList = cJSON_GetObjectItem(heart_root, "heart_data_list");
+ if (dataList == NULL || !cJSON_IsArray(dataList))
{
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "heart_data_list is null or not an array");
cJSON_Delete(heart_root);
+ heart_root = nullptr;
return false;
}
- if (dataList != NULL && cJSON_IsArray(dataList))
+ int numData = cJSON_GetArraySize(dataList);
+ if (numData >= 360)
{
- cJSON *newData = cJSON_CreateObject();
- cJSON_AddItemToObject(newData, "value", cJSON_CreateNumber(data.Heart));
- cJSON_AddItemToObject(newData, "timestamp", cJSON_CreateNumber(data.timestamp));
- cJSON_AddItemToArray(dataList, newData);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Data list is full (360 items)");
+ return false;
}
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateJsonData");
+
+ // 添加新数据到dataList中
+ cJSON *newData = cJSON_CreateObject();
+ cJSON_AddItemToObject(newData, "value", cJSON_CreateNumber(data.Heart));
+ cJSON_AddItemToObject(newData, "timestamp", cJSON_CreateNumber(data.timestamp));
+ cJSON_AddItemToArray(dataList, newData);
+
if (UpdateJsonData(HEALTH_TYPE_HEART) == false)
{
- WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateJsonData is error");
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to update JSON data for heart rate");
cJSON_Delete(heart_root);
+ heart_root = nullptr;
return false;
}
- cJSON_Delete(heart_root);
+
return true;
}
cJSON_free(jsonData);
return true;
}
-
}
\ No newline at end of file