Merge #1214 into sdk602patch0911 from refs/changes/1214/head
author袁清梦 <3449750381@qq.com>
Sat, 19 Oct 2024 07:15:27 +0000 (07:15 +0000)
committersnickersun@163.com <accounts_62b90f7fcf51ade33b6f628e@mail.teambition.com>
Sat, 19 Oct 2024 07:15:27 +0000 (07:15 +0000)
系统:增加心率数据的日志记录

* refs/changes/1214/head: (7 commits squashed)

  - 系统:增加心率数据的日志记录

  - #1049手表,运动室外跑步,500步目标测试,实际600步,目标完成度100%,目标完成度需要进行相应增加120%;

    #1048手表,运动室外跑步,1KM目标测试,实际1259米,目标完成度100%,目标完成度需要进行相应增加125%;

    #1052配速,步频,目标完成度,目标完成提示,都有问题;

    #1047手表,运动室外跑步,1KM目标测试,目标进度条在运动过程中不会变更,在运动达标时直接显示满

  - #1033运动中设置步数目标,弹出步数目标达成提醒时界面目标值的单位显示不全(如果目标值较大的话估计单位就显示。。了)

  - #852设置时长目标10min,运动中到达10分钟时无目标达成提醒

  - #1013 运动中从数据面滑至暂停页后停留一会,再滑至数据页,计时会有跳变过程

  - 睡眠:修复开启睡眠会点亮勿扰icon

  - 睡眠:优化主界面睡眠刷新速度

Signed-off-by: Caisking <3449750381@qq.com>
Reviewed-by: snickersun@163.com <accounts_62b90f7fcf51ade33b6f628e@mail.teambition.com>
Merged-by: snickersun@163.com <accounts_62b90f7fcf51ade33b6f628e@mail.teambition.com>
link: https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230/change/1214
code/sdk/application/wearable/fd230app/nativeui/dnotdisturb/src/DnotDisturbModel.cpp
code/sdk/application/wearable/fd230app/nativeui/main/src/MainPresenterSample.cpp
code/sdk/application/wearable/fd230app/nativeui/main/src/dropdown/DropDownCardPage1.cpp
code/sdk/application/wearable/fd230app/nativeui/sleep/src/SleepModel.cpp
code/sdk/application/wearable/fd230app/nativeui/traing/include/TraingModel.h
code/sdk/application/wearable/fd230app/nativeui/traing/src/TraingModel.cpp
code/sdk/application/wearable/fd230app/nativeui/traing/training_card/src/TraingCardPresenter.cpp
code/sdk/application/wearable/fd230app/nativeui/traing/training_card/src/TraingCardView.cpp
code/sdk/application/wearable/service/msg_center/include/notify/debug_output_notification/debug_output_notification.h
code/sdk/application/wearable/service/msg_center/src/notify/debug_output_notification/debug_output_notification.cpp

index 1818c8f..6b398cd 100644 (file)
@@ -34,10 +34,10 @@ namespace OHOS
 
     bool DnotDisturbModel::GetDoNotDisturbModeEnabled() const
     {
-        if(uapi_sleep_mode_flag_get())
-        {
-            return true;
-        }
+        // if(uapi_sleep_mode_flag_get())
+        // {
+        //     return true;
+        // }
 
         return ConfigModel::GetInstance()->GetDnotdisturb();
     }
index 4afa786..802fe5f 100644 (file)
@@ -449,7 +449,7 @@ namespace OHOS
             }
         }
         if (SleepModel::GetInstance().CheckSleepTime()) {
-            //通知消息更新
+            //通知睡眠更新
             GraphicService::GetInstance()->PostGraphicEvent(
             std::bind(&OHOS::SleepModel::UpdateSleepView, &OHOS::SleepModel::GetInstance()));
           }
index 4c4d6fb..3ad2db5 100644 (file)
@@ -128,7 +128,7 @@ namespace OHOS
             if (uapi_sleep_mode_flag_get())
             {
                 state = toggleButton[DropDownCardPage1::toggleButton_SLEEP]->GetState();
-                UpdateSleepModelState(state);
+                // UpdateSleepModelState(state);
                 SleepModeModel::GetInstance().SetSleepModeDisabled();
                 // state = toggleButton[DropDownCardPage1::toggleButton_DNOTDISTURB]->GetState();
                 // UpdateDnotdisturbState(DnotDisturbModel::GetInstance().GetDoNotDisturbModeEnabled());
@@ -140,10 +140,10 @@ namespace OHOS
         }
         else if (viewId == DROPDOWN_DNOTDISTURB_TOGGLEBUTTON_VIEWID) // 勿扰开关
         {
-            if (uapi_sleep_mode_flag_get())
-            {
-                return true;
-            }
+            // if (uapi_sleep_mode_flag_get())
+            // {
+            //     return true;
+            // }
 
             if (DnotDisturbModel::GetInstance().GetDoNotDisturbModeEnabled() == false)
             {
@@ -292,11 +292,11 @@ namespace OHOS
             const char *ImageSrc = state ? DROPDOWN_SLEEP_ON_IMAGE : DROPDOWN_SLEEP_OFF_IMAGE;
             toggleButton[DropDownCardPage1::toggleButton_SLEEP]->SetImages(ImageSrc, ImageSrc);
         }
-        //勿扰icon
-        if (toggleButton[DropDownCardPage1::toggleButton_DNOTDISTURB] != nullptr)
-        {
-            const char *ImageSrc = state ? DROPDOWN_DNOTDISTURB_ON_IMAGE : DROPDOWN_DNOTDISTURB_OFF_IMAGE;
-            toggleButton[DropDownCardPage1::toggleButton_DNOTDISTURB]->SetImages(ImageSrc, ImageSrc);
-        }
+        // //勿扰icon
+        // if (toggleButton[DropDownCardPage1::toggleButton_DNOTDISTURB] != nullptr)
+        // {
+        //     const char *ImageSrc = state ? DROPDOWN_DNOTDISTURB_ON_IMAGE : DROPDOWN_DNOTDISTURB_OFF_IMAGE;
+        //     toggleButton[DropDownCardPage1::toggleButton_DNOTDISTURB]->SetImages(ImageSrc, ImageSrc);
+        // }
     }
 }
\ No newline at end of file
index 9938232..f46bd88 100644 (file)
@@ -879,7 +879,7 @@ namespace OHOS
   bool SleepModel::CheckSleepTime()
   {
     // 获取睡眠最新时间
-    if (sleep_update_time != get_sleep_update_timestamp()) {
+    if (sleep_update_time != 0) {
       return true;
       }
     return false;
index c9548ad..701d7b6 100644 (file)
@@ -323,6 +323,7 @@ public:
   int GetSportTagData();         /*获取对应的训练目标的值*/
   int GetGoaldegree();           /*获取训练目标完成百分比*/
   std::string GetTagStr();       /*获取训练目标Str*/
+  void CheckSportTag();
 
   /*配速表以及心率表配置*/
   bool AddHeartRateData(uint32_t timestamp, uint8_t heartRate);
index cdbc359..7bdc5e8 100644 (file)
@@ -32,6 +32,7 @@
 #include "traingrecord/include/TraingRecordModel.h"
 #include "vibrator_service.h"
 #include <algorithm>
+#include <cmath>
 #include <filesystem>
 #include <fstream>
 #include <limits.h>
@@ -450,29 +451,9 @@ void TraingModel::AnalysisData(cywee_activity_result_t *cyweeInfo) {
       ui_api_vibrate_once_func();
     }
     if (TraingCardView::GetInstance()) {
-      TraingCardView::GetInstance()->SetPopupViewStatus(HeartPopup, true);
-    }
-  }
-
-  // 训练目标检查
-  if (sportdata->tag && !Gettagstuats) {
-    sportdata->goaldegree = GetGoaldegree();
-
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->goaldegree %d",
-                  sportdata->goaldegree);
-    if (sportdata->goaldegree >= 100) { //测试
-      // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "currentdata%d", currentdata);
-      uapi_set_screen_on_api(); // 亮屏检测
-      if (true != OHOS::ConfigModel::GetInstance()->GetDnotdisturb()) {
-        ui_api_vibrate_once_func();
-      }
-      if (TraingCardView::GetInstance()) {
-        TraingCardView::GetInstance()->SetPopupViewStatus(GetTagPopup, true);
-        if (TraingCardView::GetInstance()->GetAnimator()) {
-          TraingCardView::GetInstance()->GetAnimator()->Start();
-        }
-      }
-      Gettagstuats = true;
+      GraphicService::GetInstance()->PostGraphicEvent(
+          std::bind(&TraingCardView::SetPopupViewStatus,
+                    TraingCardView::GetInstance(), HeartPopup, true));
     }
   }
 }
@@ -920,29 +901,90 @@ UIResourceTextId TraingModel::GetIntensity() {
     break;
   }
 }
-/*获取当前的目标值*/
+
+/*
+时长:10~600分钟 实际出值 秒
+距离:1~20km  实际出值 m
+步数:500~50000步 实际出值 步
+卡路里:100~1000kcal 实际出值 kcal
+*/
+
+/* 获取当前的目标值 */
 int TraingModel::GetSportTagData() {
+  if (sportdata->tag == 0)
+    return 0;
+
+  float goaldegree = 0.0f; // 初始化目标完成度
+
+  // 根据设置的训练目标类型去对应相对的数据
+  switch (sportdata->sportTagType) {
+  case ExerciseTag::Duration: {
+    // 转换目标时长为秒
+    float durationInSeconds = static_cast<float>(sportdata->tag * 60);
+    // 计算完成度
+    goaldegree =
+        (static_cast<float>(sportdata->duration) / durationInSeconds) * 100;
+    break;
+  }
+  case ExerciseTag::Calories: {
+    // 计算目标完成度
+    goaldegree =
+        (static_cast<float>(sportdata->calories) / sportdata->tag) * 100;
+    break;
+  }
+  case ExerciseTag::Distance: {
+    float distanceInMeters = static_cast<float>(sportdata->tag * 1000);
+    // 计算目标完成度
+    goaldegree =
+        (static_cast<float>(sportdata->distance) / distanceInMeters) * 100;
+    break;
+  }
+  case ExerciseTag::Steps: {
+    // 计算目标完成度
+    goaldegree = (static_cast<float>(sportdata->steps) / sportdata->tag) * 100;
+    break;
+  }
+  default:
+    break;
+  }
+
+  return static_cast<int>(round(goaldegree)); // 返回目标完成度
+}
+
+/* 获取训练目标完成百分比 */
+int TraingModel::GetGoaldegree() {
+  if (sportdata->tag == 0) {
+    return 0; // 如果目标值为 0,返回 0%
+  }
+
+  int goaldegree = GetSportTagData();
+  WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "goaldegree %d", goaldegree);
+  return goaldegree; // 直接返回目标完成度
+}
+
+/* 训练目标校验 */
+void TraingModel::CheckSportTag() {
   if (sportdata->tag) {
-    // 根据设置的训练目标类型去对应相对的数据
-    switch (sportdata->sportTagType) {
-    case ExerciseTag::Duration:
-      return int(sportdata->duration / 60); // 时间是秒需要转换为目标的分钟
-      break;
-    case ExerciseTag::Calories:
-      return sportdata->calories; //卡路里是kcal
-      break;
-    case ExerciseTag::Distance:
-      return int(sportdata->distance / 1000); //距离是米需要转换为km
-      break;
-    case ExerciseTag::Steps:
-      return sportdata->steps; //步数是步
-      break;
-    default:
-      break;
+    sportdata->goaldegree = GetGoaldegree();
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "sportdata->goaldegree %d",
+                  sportdata->goaldegree);
+    if (sportdata->goaldegree >= 100 && !Gettagstuats) {
+      uapi_set_screen_on_api(); // 亮屏检测
+      if (!OHOS::ConfigModel::GetInstance()->GetDnotdisturb()) {
+        ui_api_vibrate_once_func(); // 震动提示
+      }
+      if (TraingCardView::GetInstance()) {
+        GraphicService::GetInstance()->PostGraphicEvent(
+            std::bind(&TraingCardView::SetPopupViewStatus,
+                      TraingCardView::GetInstance(), GetTagPopup, true));
+        auto animator = TraingCardView::GetInstance()->GetAnimator();
+        if (animator) {
+          animator->Start(); // 启动动画
+        }
+      }
+      Gettagstuats = true; // 更新状态
     }
   }
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Not set Sport_Tag!");
-  return 0; // 添加默认返回值
 }
 //获取运动时长
 int TraingModel::GetDuration() { return sportdata->duration; }
@@ -1001,16 +1043,7 @@ void TraingModel::printTrainingData(const Trainingdata &data) {
   printf("cir: %u\n", data.cir);
   printf("alt: %u\n", data.alt);
 }
-/*获取训练目标完成百分比*/
-int TraingModel::GetGoaldegree() {
-  if (sportTag_ == 0) {
-    return 0;
-  }
-  int currentdata = GetSportTagData();
-  float completeness = (static_cast<float>(currentdata) / sportdata->tag) * 100;
 
-  return round(completeness); // 四舍五入
-}
 /*
     uint32_t src; // 训练来源:0 - 手表开启的训练,1 - APP开启的训练
     uint32_t bt;  // 运动类型:0 - 健身类,1 - 舞蹈类,2 - 休闲运动,3 - 球类,4
@@ -2025,4 +2058,4 @@ bool TraingModel::LoadDataFormJson(std::vector<SportData> &sportDataVector) {
   return true;
 }
 
-} // namespace OHOS
\ No newline at end of file
+} // namespace OHOS
index a967534..10982c3 100644 (file)
@@ -293,6 +293,9 @@ void TraingCardPresenter::UpdateDataView() {
   GraphicService::GetInstance()->PostGraphicEvent(std::bind(\r
       &TrainingDataView::UpdataTime, TrainingDataView::GetInstance()));\r
 \r
+  // 更新目标完成度\r
+  TraingModel::GetInstance()->CheckSportTag();\r
+\r
   // 刷新训练数据:心率、卡路里、距离、步数、训练强度、目标完成度\r
   SportData *sportdata = TraingModel::GetInstance()->GetSportdata();\r
   RefreshData(sportdata);\r
@@ -377,7 +380,8 @@ bool TraingCardPresenter::send_sport_cmd(training_ble *cmd) {
   // 获取当前的运动状态\r
   ExerciseState currentState = TraingModel::GetInstance()->GetSportState();\r
   ExerciseState cmdstate = static_cast<ExerciseState>(cmd->controlmd);\r
-  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cmdstate:%d currentState:%d", cmdstate,currentState);\r
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cmdstate:%d currentState:%d",\r
+                cmdstate, currentState);\r
 \r
   switch (cmd->controlmd) {\r
   case SETGOAL:\r
index 32fc924..d0ef24a 100644 (file)
@@ -19,6 +19,7 @@
 #include "traing/include/TraingModel.h"\r
 #include "uicomponents/UIComponents.h"\r
 \r
+\r
 extern "C" {\r
 void InitTimer();\r
 void DisableTimer();\r
@@ -388,7 +389,9 @@ void TraingCardView::OnStart() {
   swipe_->SetDraggable(true);\r
   swipe_->SetStyle(STYLE_BACKGROUND_COLOR, BACK_GROUND_COLOR);\r
   swipe_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);\r
-  swipe_->EnableScreenCap(true);\r
+\r
+  swipe_->EnableScreenCap(false);\r
+\r
   swipe_->SetAnimatorTime(50);\r
 \r
   SetContainerView(swipe_);\r
@@ -414,6 +417,8 @@ void TraingCardView::SetPopupViewStatus(PopupType type, bool status) {
     cardview->SetVisible(!status);\r
   }\r
   popupView->SetVisible(status);\r
+  //刷新\r
+  RootView::GetInstance()->Invalidate();\r
 }\r
 /*结束弹窗界面*/\r
 void TraingCardView::ShowEndView() {\r
@@ -522,6 +527,10 @@ void TraingCardView::ShowHeartView() {
   std::string heartStr = "当前心率高于" + std::to_string(maxheart) + "次/分钟";\r
   InitLabel(labelnote, 53, 269, 360, 35, "label3", heartStr.c_str(),\r
             DEFAULT_VECTOR_FONT_FILENAME_EN, 30);\r
+  \r
+  labelnote->SetLineBreakMode(UILabel::LINE_BREAK_OSCILLATION);\r
+  labelnote->SetRollSpeed(70);\r
+\r
   heartView->Add(labelnote);\r
 \r
   InitImageView(heartiamge, 193, 149, 80, 80, "note", WARNING_IMAGE);\r
@@ -599,6 +608,9 @@ void TraingCardView::InitImageAnimator() {
   //DEFAULT_VECTOR_FONT_FILENAME_EN\r
   InitLabel(labeltag, 70, 215, 326, 97, "label2", tagString.c_str(),\r
             DEFAULT_VECTOR_FONT_FILENAME_EN, 80);\r
+\r
+  labeltag->SetLineBreakMode(UILabel::LINE_BREAK_OSCILLATION);\r
+  labeltag->SetRollSpeed(70);\r
   \r
   labeltag->SetTextColor(Color::GetColorFromRGBA(0x4f, 0xc3, 0x4c, 0xff));\r
   getView->Add(labeltag);\r
index 821a4d3..8c33171 100644 (file)
@@ -42,6 +42,7 @@ namespace OHOS
         std::string get_sleep_time(void);
         std::string get_free_memory(void);
         std::string get_nextday_log(void);
+        std::string get_heart_rate(void);
 
       private:
         DebugOutputViewEventListener();
index 134d2c3..bd20513 100644 (file)
@@ -27,7 +27,6 @@
 #include "vibrator_service.h"
 #include "wearable_log.h"
 #include <array>
-
 #include <cmsis_os2.h>
 #include <cstdint>
 #include <custom_runtime.h>
 #include <cerrno>
 #include "bleService.h"
 #include "sleep/include/SleepModel.h"
+#include "heartrate/include/HeartModel.h"
+#include "heart_blood/health_service/health_service.h"
 #include "BluetoothModel.h"
+#include <iostream>  
+#include <sstream>  
+#include <vector>  
+#include <dirent.h>  
+#include <string>  
+#include <cstring>  
+#include <cstdint> 
+
 namespace OHOS
 {
 
@@ -92,6 +101,8 @@ namespace OHOS
         debugOutputItemInfo[index++] = {8, "system_free_memory"};
         // nextday执行日志
         debugOutputItemInfo[index++] = {9, "nextday_log"};
+        // 读取心率
+        debugOutputItemInfo[index++] = {10, "heart_rate"};
         usedLen = index;
         /* -------------------------------- Add data -------------------------------- */
         for (uint8_t i = 0; i < usedLen; i++)
@@ -365,7 +376,7 @@ result += "advdata:" + (getCurrentWatchadvdata()) + " ";
         return result;
     }
 
-
+    //获取nextday执行日志
     std::string DebugOutputViewEventListener::get_nextday_log() {  
         std::ostringstream result;   
         result << "nextday_log:\n"; // 添加标题  
@@ -389,7 +400,82 @@ result += "advdata:" + (getCurrentWatchadvdata()) + " ";
             result << "[" << timestr << "] "; // 使用格式化后的时间拼接日志记录  
         }  
 
-        return result.str(); 
+        return result.str();
+    }
+
+    // 定义心率数据文件夹的路径  
+    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;  
+
+        // 1. 读取文件并形成文件名字符串  
+        std::vector<std::string> heartFiles = readDirectory(HEART_DATA_PATH);  
+        if (heartFiles.empty()) {  
+            result << "No heart rate files found in directory.\n";  
+        } else {  
+            result << "Heart rate files:\n";  
+            for (const auto &file : heartFiles) {  
+                result << file << "\n"; // 输出文件名  
+            }  
+        }  
+
+        result << "=====================\n";  
+
+        // 2. 获取模型里的数据(当前值与时间)  
+        auto heartModel = HeartModel::GetInstance();  
+        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";  
+
+        result << "=====================\n";  
+
+        result << "Today's HeartRate list\n";  
+        // 3. 获取一天的心率列表  
+        for (int serialIndex = 0; serialIndex < 24; ++serialIndex) {  
+            uint32_t heartRate = HealthService::GetInstance()->GetHourlyHeartRate(serialIndex);  
+            result << "Hour " << serialIndex << ": " << heartRate << " bmp\n"; // 输出每小时的心率  
+        }  
+
+        result << "=====================\n";  
+        return result.str(); // 返回完整结果  
     }
 
     bool DebugOutputViewEventListener::OnClick(OHOS::UIView &view, const OHOS::ClickEvent &event)
@@ -456,6 +542,9 @@ result += "advdata:" + (getCurrentWatchadvdata()) + " ";
         case 9:
             str = get_nextday_log();
             break;
+        case 10:
+            str = get_heart_rate();
+            break;
         default:
             str = "--";
             break;