心率:优化心率nextday可能不会清空的现象
authorCaisking <3449750381@qq.com>
Sat, 19 Oct 2024 08:19:02 +0000 (16:19 +0800)
committerCaisking <3449750381@qq.com>
Sat, 19 Oct 2024 08:19:02 +0000 (16:19 +0800)
code/sdk/application/wearable/fd230app/nativeui/bloodoxygen/src/BloodOxygenModel.cpp
code/sdk/application/wearable/fd230app/nativeui/heart_blood/health_service/health_service.cpp
code/sdk/application/wearable/fd230app/nativeui/heart_blood/health_service/health_service.h
code/sdk/application/wearable/fd230app/nativeui/heartrate/src/HeartModel.cpp
code/sdk/application/wearable/service/msg_center/src/notify/debug_output_notification/debug_output_notification.cpp

index 1f7cc56..3689e36 100644 (file)
@@ -51,8 +51,9 @@ namespace OHOS
 
     void BloodOxygenModel::ClearDisplayData()
     {
-        currentspo2 = 0;
-        timestamp_ms = 0;
+      // currentspo2 = 0;
+      // timestamp_ms = 0;
+      // 不需要清空
     }
 
     // 血氧监控
index 0ad2b45..595885f 100644 (file)
@@ -448,12 +448,14 @@ bool HealthService::CreateHealthFolder() {
         return true;  
     }
     // 清空健康数据
-    bool HealthService::CleanHealthData()
-    {
+    bool HealthService::CleanHealthData() {
+        //清空心率数组
         ClearHourlyHeartRates();
-        HeartModel::GetInstance()->ClearDisplayData();
-        BloodOxygenModel::GetInstance()->ClearDisplayData();
+        //进行数据存储
+        SaveDailyHeartRate();
 
+        HeartModel::GetInstance()->ClearDisplayData();
+        // BloodOxygenModel::GetInstance()->ClearDisplayData();
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CleanHealthData  is ok");
         return true;
     }
@@ -467,130 +469,112 @@ bool HealthService::CreateHealthFolder() {
         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);  
+    static constexpr const char *HEART_DATA_PATH =  "/user/userdata/health/heart_history.bin";
 
-    // 检查是否为同一天  
-    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; // 文件打开失败  
-    }  
+    //清空数组
+    void HealthService::ClearHourlyHeartRates() {  
+        for (int i = 0; i < MAX_HOURS; ++i) {  
+            dailyHeartRates[i].Heart = 0;  
+            dailyHeartRates[i].timestamp = 0;  
+        }
+    }
+    
+    // 加载心率列表  
+    bool HealthService::LoadDailyHeartRate() {  
+        ClearHourlyHeartRates();  // 清空数组  
+
+        // 使用 RAII 管理文件流  
+        std::ifstream file(HEART_DATA_PATH, std::ios::binary);  
+        if (!file.is_open()) {  
+            std::cerr << "Error: Unable to open heart rate data file for reading" << std::endl;  
+            return false;  
+        }  
 
-    // 读取时间戳  
-    file.read(reinterpret_cast<char *>(&lastLoadTime), sizeof(lastLoadTime));  
+        // 读取时间戳  
+        file.read(reinterpret_cast<char *>(&lastLoadTime), sizeof(lastLoadTime));  
+        if (lastLoadTime == 0) {  
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadDailyHeartRate is not today");  
+            return false; // 无有效数据  
+        }  
 
-    // 检查是否为同一天  
-    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();  
+        time_t now = time(nullptr);  
+        tm *currentTm = localtime(&now);  
+        if (currentTm->tm_year == lastTm->tm_year && currentTm->tm_yday == lastTm->tm_yday) {  
+            // 今天:进行数据读取  
+            for (int i = 0; i < MAX_HOURS; ++i) {  
+                HeartRateData rate; // 假设您有一个 HeartRateData 结构体  
+                if (!file.read(reinterpret_cast<char *>(&rate), sizeof(rate))) {  
+                    std::cerr << "Error: Failed to read heart rate data." << std::endl;  
                     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();  
+                dailyHeartRates[i] = rate; // 保存心率和时间戳  
+                std::cout << "Hour " << i << ": Heart Rate " << rate.Heart << std::endl;  
+            }  
+            return true; // 成功读取  
+        }  
 
-    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Not same-day data");  
-    return false; // 不是同一天  
-}  
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LoadDailyHeartRate is not today");  
+        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; // 文件打开失败
-  }
+    // 保存今日心率列表  
+    bool HealthService::SaveDailyHeartRate() {  
+        std::ofstream outFile(HEART_DATA_PATH, std::ios::binary | std::ios::trunc);  
+        if (!outFile.is_open()) {  
+            std::cerr << "Error: Unable to open heart rate data file for writing" << std::endl;  
+            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() {
-  // 清空心率数据,将数组置为 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 获取本地时间
+        // 存储时间戳  
+        time_t currentTime = time(nullptr);  
+        outFile.write(reinterpret_cast<const char *>(&currentTime), sizeof(currentTime));  
 
-  // 提取小时
-  uint16_t hour = static_cast<uint16_t>(timeInfo->tm_hour);
+        // 存储心率数据  
+        for (const auto& rate : dailyHeartRates) {  
+            if (!outFile.write(reinterpret_cast<const char *>(&rate), sizeof(rate))) {  
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to write heart rate data to file");  
+                return false; // 写入失败  
+            }  
+        }  
 
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
-                "Updating heart rate: 小时 %d, 心率值 %d", hour, heartRate);
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SaveDailyHeartRate is ok");  
+        return true; // 成功保存  
+    }
 
-  // 确保 hour 在有效范围内,并且心率不是异常值(例如负值)
-  if (hour < MAX_HOURS && heartRate > 0) // 心率不应为负 并且 小时不能为24
-  {
-    dailyHeartRates[hour] = heartRate;
+    // 更新心率列表项
+    void HealthService::UpdateHourlyHeartRate(time_t timestamp, uint16_t heartRate) {  
+        struct tm *timeInfo = localtime(&timestamp);  
+        uint16_t hour = static_cast<uint16_t>(timeInfo->tm_hour);  
 
-    // 记录目前更新时间点
-    currenthour = hour;
-  }
-}
+        if (hour < MAX_HOURS && heartRate > 0) {  
+            dailyHeartRates[hour] = {heartRate, timestamp}; // 更新心率和时间戳
+            currenthour = hour; // 记录当前小时
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateHourlyHeartRate is ok");
+        }
+        else {  
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid hour or heart rate value %d",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].Heart; // 默认为 0 如果未更新  
+        }  
+        return 0; // 或者返回一个异常值
+    }
+    //获取指定小时的时间戳
+    time_t HealthService::GetHourlyTimestamp(uint16_t hour) {  
+        if (hour < MAX_HOURS) {  
+            return dailyHeartRates[hour].timestamp; // 默认为 0 如果未更新  
+        }  
+        return 0; // 或者返回一个异常值
+    }
 
-uint16_t HealthService::GetCurrentHour() {
-  // 返回目前小时
-  return currenthour;
-}
+    // 获取当前小时
+    uint16_t HealthService::GetCurrentHour() {  
+        return currenthour;  
+    }  
 } // namespace OHOS
index cd72638..7aa6a07 100644 (file)
@@ -25,31 +25,11 @@ namespace OHOS
         HEALTH_TYPE_HEART,
         HEALTH_TYPE_OXYGEN,
     } HEALTH_TYPE;
-
     typedef struct
     {
         uint8_t SPO2;       // 血氧值
         uint32_t timestamp; // 最近一次检测时间
     } BloodOxygenData;
-
-    typedef struct
-    {
-        uint16_t index; // x
-        uint16_t value; // y
-    } HeartPoints;
-
-    typedef struct
-    {
-        uint16_t perSec;                          // 每秒心率
-        uint16_t rest;                            // 静息心率
-        uint16_t minX;                            // 最小心率点
-        uint16_t minValue;                        // 最小心率
-        uint16_t maxX;                            // 最大心率点
-        uint16_t maxValue;                        // 最大心率
-        uint16_t index;                           // 最近一次测量的点位值,每次遍历数组到这里
-        HeartPoints heartvalue[HEART_MAX_POINTS]; // 心率点
-    } HeartData;
-
     typedef struct
     {
         uint8_t Heart;      // 心率值
@@ -109,12 +89,14 @@ namespace OHOS
         bool LoadDailyHeartRate();
         void UpdateHourlyHeartRate(time_t timestamp, uint16_t heartRate);
         uint16_t GetHourlyHeartRate(uint16_t hour);
+        time_t GetHourlyTimestamp(uint16_t hour); 
         void ClearHourlyHeartRates();
         uint16_t GetCurrentHour();
 
+
     private:
         static const int MAX_HOURS = 24;
-        uint16_t dailyHeartRates[MAX_HOURS]; // 使用数组来存储心率值
+        HeartRateData dailyHeartRates[MAX_HOURS]; // 存储心率值,检测时间戳?使用结构体?
         HealthState healthState_;
         time_t lastLoadTime; // 记录最后加载的时间
         uint16_t currenthour = 0;
index b42dca9..61d8ad1 100644 (file)
@@ -375,8 +375,8 @@ void HeartModel::RefreshHeartRateScreen() {
 // 重新初始化\r
 void HeartModel::ClearDisplayData() {\r
   /*显示的心率数据清空*/\r
-  currentheart = 0;\r
-  timestamp_ms = 0;\r
+  // currentheart = 0;\r
+  // timestamp_ms = 0;\r
   displayheart = 0;\r
   displayheart_max = 0; // 显示最大心率\r
   displayheart_min = 0; // 显示最小心率\r
index bd20513..f9e5e10 100644 (file)
 
 namespace OHOS
 {
+    /**************************************************************************************************** */
+    // 辅助函数
 
+    // 函数:读取文件夹中的文件  
+    std::vector<std::string> readDirectory(const char *path) {  
+        std::vector<std::string> fileNames; // 存储读取的文件名  
+        struct dirent *entry;                // 定义目录项  
+
+        // 打开目录  
+        DIR *dir = opendir(path);  
+        if (!dir) {  
+            std::cerr << "Error opening directory: " << path << " - " << strerror(errno) << std::endl;  
+            return fileNames; // 返回空列表  
+        }  
+
+        // 读取目录项  
+        while ((entry = readdir(dir)) != nullptr) {  
+            // 跳过 . 和 ..  
+            if (entry->d_name[0] != '.') {  
+                fileNames.push_back(entry->d_name); // 存储文件名  
+            }  
+        }  
+
+        // 关闭目录  
+        closedir(dir);  
+        return fileNames;
+    }
+    
+    // 格式化时间的辅助函数  
+    std::string formatTime(uint32_t time) {  
+        char labelTime[20];  
+        if (uapi_get_TIME_STR(time, labelTime, '.', ':', DATE_Y_M_D_H_M) != ERRCODE_SUCC) {  
+            return "--"; // 默认值  
+        } else {  
+            return labelTime; // 成功获取时间  
+        }
+    }
+    /**************************************************************************************************** */
+    
     struct DebugOutputViewMapper
     {
         const int16_t viewId;
@@ -102,7 +140,7 @@ namespace OHOS
         // nextday执行日志
         debugOutputItemInfo[index++] = {9, "nextday_log"};
         // 读取心率
-        debugOutputItemInfo[index++] = {10, "heart_rate"};
+        debugOutputItemInfo[index++] = {10, "heart_rate_data"};
         usedLen = index;
         /* -------------------------------- Add data -------------------------------- */
         for (uint8_t i = 0; i < usedLen; i++)
@@ -171,7 +209,7 @@ namespace OHOS
         result += "bt_earphone_connectstat:" + std::to_string(uapi_dev_runtime_get_earphone_connect_stat()) + " ";
         result += "android_app_connected:" + std::to_string(get_ble_pair()) + " ";
         result += "localAddress:" + (getCurrentWatchMacAddress()) + " ";
-result += "advdata:" + (getCurrentWatchadvdata()) + " ";
+        result += "advdata:" + (getCurrentWatchadvdata()) + " ";
         result += "ble广播状态:" + std::to_string(get_ble_adv_status());
 
         // 蓝牙ble广播开关,基础信息如,地址,广播状态
@@ -280,17 +318,13 @@ result += "advdata:" + (getCurrentWatchadvdata()) + " ";
             }  
 
             // 格式化时间  
-            char labelTime[20];  
             std::string timestr;  
-            if (uapi_get_TIME_STR(systemlogs[i].timestamp, labelTime, '.', ':', DATE_Y_M_D_H_M) != ERRCODE_SUCC)  
-            {  
-                timestr = "--";  
-            }  
-            else  
-            {  
-                timestr = labelTime;  
-            }  
-
+            if (systemlogs[i].timestamp == 0) {  
+                timestr = "--"; // 默认值  
+            } else {  
+                timestr = formatTime(systemlogs[i].timestamp);
+            }
+            
             str << "[" << timestr << "] "<< "\n"; // 拼接日志内容  
         }  
 
@@ -385,18 +419,13 @@ result += "advdata:" + (getCurrentWatchadvdata()) + " ";
         const auto& nextday_logs = logModel->get_nextday_log();   
 
         // 遍历日志并拼接到结果字符串  
-        for (const auto &log : nextday_logs) {  
-            // 格式化时间  
-            char labelTime[20];  
+        for (const auto &log : nextday_logs) {
             std::string timestr;  
-            
-            // 调用时间格式化函数  
-            if (uapi_get_TIME_STR(log, labelTime, '.', ':', DATE_Y_M_D_H_M) != ERRCODE_SUCC) {  
-                timestr = "--"; // 如果获取时间失败,使用默认值  
+            if (log == 0) {  
+                timestr = "--"; // 默认值  
             } else {  
-                timestr = labelTime; // 成功获取时间  
+                timestr = formatTime(log); 
             }  
-            
             result << "[" << timestr << "] "; // 使用格式化后的时间拼接日志记录  
         }  
 
@@ -406,31 +435,6 @@ result += "advdata:" + (getCurrentWatchadvdata()) + " ";
     // 定义心率数据文件夹的路径  
     static const char *HEART_DATA_PATH = "/user/userdata/health/heart";  
 
-    // 函数:读取文件夹中的文件  
-    std::vector<std::string> readDirectory(const char *path) {  
-        std::vector<std::string> fileNames; // 存储读取的文件名  
-        struct dirent *entry;                // 定义目录项  
-
-        // 打开目录  
-        DIR *dir = opendir(path);  
-        if (!dir) {  
-            std::cerr << "Error opening directory: " << path << " - " << strerror(errno) << std::endl;  
-            return fileNames; // 返回空列表  
-        }  
-
-        // 读取目录项  
-        while ((entry = readdir(dir)) != nullptr) {  
-            // 跳过 . 和 ..  
-            if (entry->d_name[0] != '.') {  
-                fileNames.push_back(entry->d_name); // 存储文件名  
-            }  
-        }  
-
-        // 关闭目录  
-        closedir(dir);  
-        return fileNames;  
-    }  
-
     // 主要函数:获取心率  
     std::string DebugOutputViewEventListener::get_heart_rate() {  
         std::ostringstream result;  
@@ -453,30 +457,32 @@ result += "advdata:" + (getCurrentWatchadvdata()) + " ";
         uint32_t checkTime = heartModel->GetCheckTime();  
         uint16_t currentHeartRate = heartModel->GetHeartdata();  
 
-        // 格式化时间  
-        char labelTime[20];  
-        std::string timestr;  
-        if (uapi_get_TIME_STR(checkTime, labelTime, '.', ':', DATE_Y_M_D_H_M) != ERRCODE_SUCC) {  
-            timestr = "--"; // 默认值  
-        } else {  
-            timestr = labelTime; // 成功获取时间  
-        }  
-
-        result << "CurrentHeart: " << currentHeartRate <<"\n"
-            << "CheckTime: " << timestr << "\n";  
+        std::string timestr = formatTime(checkTime);  
 
-        result << "=====================\n";  
+        result << "CurrentHeart: " << currentHeartRate << "\n"  
+            << "Time: " << timestr << "\n";
 
-        result << "Today's HeartRate list\n";  
+        result << "=====================\n";
+        
         // 3. 获取一天的心率列表  
+        result << "Today's HeartRate list\n";  
         for (int serialIndex = 0; serialIndex < 24; ++serialIndex) {  
             uint32_t heartRate = HealthService::GetInstance()->GetHourlyHeartRate(serialIndex);  
-            result << "Hour " << serialIndex << ": " << heartRate << " bmp\n"; // 输出每小时的心率  
+            uint32_t time = HealthService::GetInstance()->GetHourlyTimestamp(serialIndex);  
+            
+            std::string timestr;  
+            if (time == 0) {  
+                timestr = "--"; // 默认值  
+            } else {  
+                timestr = formatTime(time); 
+            }  
+
+            result << "time " << timestr << ""<<"\n" <<"heart " << heartRate <<""<< "\n"; // 输出每小时的心率  
         }  
 
         result << "=====================\n";  
         return result.str(); // 返回完整结果  
-    }
+    }  
 
     bool DebugOutputViewEventListener::OnClick(OHOS::UIView &view, const OHOS::ClickEvent &event)
     {