${CMAKE_CURRENT_SOURCE_DIR}/nativeui/UIInitializer/
${CMAKE_CURRENT_SOURCE_DIR}/nativeui/InitComponent/include
${CMAKE_CURRENT_SOURCE_DIR}/nativeui/uisample/uitest/framework/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heart_blood/health_service/
${CMAKE_CURRENT_SOURCE_DIR}/nativeui/alipay/include
${CMAKE_CURRENT_SOURCE_DIR}/nativeui/alipay/include/AlipayList
${CMAKE_CURRENT_SOURCE_DIR}/nativeui/screennotify/src/ui_screennotify.cpp
${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heart_blood/src/BloodCardView.cpp
${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heart_blood/src/HeartCardView.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/nativeui/heart_blood/health_service/health_service.cpp
${CMAKE_CURRENT_SOURCE_DIR}/nativeui/traing/src/TraingView.cpp
${CMAKE_CURRENT_SOURCE_DIR}/nativeui/language/LanguageInit.cpp
bool GetCheckStatus();
void SetCheckStatus(bool checkstatus);
+
void UpSPO2data(uint16_t spo2);
uint16_t GetSPO2data();
uint16_t GetShowSPO2data();
uint16_t GetCheckTime(); // 获取距离上传测试时间
void SetCheckTime(uint16_t time); // 设置本次测试完的时间
-
+ void StartTest(); // 开始检测
+ void SetWearStatus(int32_t wear); // 佩戴检测
+ bool GetWearStatus(void);
+ bool StopTest(); // 结束检测
private:
BloodOxygenModel();
bool OxygenView;
bool BandoffView;
bool CheckView;
bool ResultView;
- bool CheckStatus; // 检测状态标志
- uint16_t Show_SPO2_; // 显示血氧
- uint16_t SPO2_; // 保存血氧
- uint16_t TIME_; // 检测时间(存(时、分),大于24小时,改为1天前,小于1分钟为刚刚)
- bool initstatus = true;
+ bool CheckStatus; // 检测状态标志
+ bool WearStatus; // 佩戴状态
+ uint16_t Show_SPO2_; // 显示血氧
+ uint16_t SPO2_; // 保存血氧
+ uint64_t timestamp_ms; // 时间戳
+ int32_t wear_; // 佩戴状态
+
+ uint8_t wear_error = 0; // 佩戴错误计数器
+ uint8_t spo2_count = 0; // 有效血氧结果计数器
+ bool initstatus = true;
};
}
+
/*
* Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
* Description: bloodOxygen view
bool OnClick(UIView &view, const ClickEvent &event) override;
bool OnKeyAct(UIView &view, const KeyEvent &event) override; // 增加按键事件
- uint16_t GetCurrentTime();
- std::string GetTDOA(uint16_t new_time, uint16_t old_time);
+ uint64_t GetCurrentTime();
+ std::string GetTDOA(uint64_t new_time, uint64_t old_time);
private:
bool CheckPointersValue(void);
#include "DialModelSPO2.h"
#include "wearable_log.h"
#include "BloodOxygenPresenter.h"
+#include "wearable_log.h"
+#include "health_service.h"
+#include "custom_utils.h"
+extern "C" errcode_t uapi_get_timestamp_ms(uint64_t *tm);
namespace OHOS
{
- BloodOxygenModel::BloodOxygenModel() : OxygenView(false), BandoffView(false), CheckView(false), ResultView(false), CheckStatus(false), SPO2_(DialModelSPO2::GetInstance()->GetSPO2Data())
+ /**
+ * @brief Constructor for the BloodOxygenModel class.
+ */
+ BloodOxygenModel::BloodOxygenModel() : OxygenView(false), BandoffView(false), CheckView(false), ResultView(false), CheckStatus(false), WearStatus(true)
{
+ BloodOxygenData *data = new BloodOxygenData;
+ data = HeartService::GetInstance()->ReadBloodOxygenData();
+ SPO2_ = data->SPO2;
+ timestamp_ms = data->timestamp;
}
+ /**
+ * @brief Get the status of the BloodOxygenView.
+ * @return The status of the BloodOxygenView.
+ */
bool BloodOxygenModel::GetBloodOxygenViewStatus() { return OxygenView; }
+ /**
+ * @brief Get the status of the BandoffView.
+ * @return The status of the BandoffView.
+ */
bool BloodOxygenModel::GetBloodBandoffViewStatus() { return BandoffView; }
+ /**
+ * @brief Get the status of the CheckView.
+ * @return The status of the CheckView.
+ */
bool BloodOxygenModel::GetBloodCheckViewStatus() { return CheckView; }
+ /**
+ * @brief Set the status of the BandoffView.
+ * @param bandoffViewStatus The status to set.
+ */
void BloodOxygenModel::SetBloodBandoffViewStatus(bool bandoffViewStatus) { BandoffView = bandoffViewStatus; }
+ /**
+ * @brief Set the status of the BloodOxygenView.
+ * @param oxygenViewStatus The status to set.
+ */
void BloodOxygenModel::SetBloodOxygenViewStatus(bool oxygenViewStatus) { OxygenView = oxygenViewStatus; }
+ /**
+ * @brief Set the status of the CheckView.
+ * @param checkViewStatus The status to set.
+ */
void BloodOxygenModel::SetBloodCheckViewStatus(bool checkViewStatus) { CheckView = checkViewStatus; }
+ /**
+ * @brief Get the CheckStatus.
+ * @return The CheckStatus.
+ */
bool BloodOxygenModel::GetCheckStatus() { return CheckStatus; }
+ /**
+ * @brief Set the CheckStatus.
+ * @param checkstatus The status to set.
+ */
void BloodOxygenModel::SetCheckStatus(bool checkstatus) { CheckStatus = checkstatus; }
+ /**
+ * @brief Get the SPO2 data.
+ * @return The SPO2 data.
+ */
uint16_t BloodOxygenModel::GetSPO2data() { return SPO2_; }
+ /**
+ * @brief Get the Show SPO2 data.
+ * @return The Show SPO2 data.
+ */
uint16_t BloodOxygenModel::GetShowSPO2data() { return Show_SPO2_; }
+ /**
+ * @brief Update the SPO2 data.
+ * @param spo2 The SPO2 value to update.
+ */
void BloodOxygenModel::UpSPO2data(uint16_t spo2)
{
Show_SPO2_ = spo2;
}
}
+ /**
+ * @brief Get the timestamp of the last check.
+ * @return The timestamp of the last check.
+ */
uint16_t BloodOxygenModel::GetCheckTime()
{
- if (initstatus)
+ return timestamp_ms;
+ }
+
+ /**
+ * @brief Set the timestamp of the last check.
+ * @param time The timestamp to set.
+ */
+ void BloodOxygenModel::SetCheckTime(uint16_t time)
+ {
+ timestamp_ms = time;
+ }
+
+ /**
+ * @brief Start the blood oxygen test.
+ */
+ void BloodOxygenModel::StartTest()
+ {
+ wear_error = 0;
+ spo2_count = 0;
+ }
+
+ /**
+ * @brief Set the wear status.
+ * @param wear The wear status to set.
+ */
+ void BloodOxygenModel::SetWearStatus(int32_t wear)
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Weartest::%d", wear);
+ wear_ = wear;
+ if (wear_ != 1)
{
- TIME_ = BloodOxygenPresenter::GetInstance()->GetCurrentTime();
- initstatus = false;
+ wear_error++;
+ if (wear_error >= 10)
+ {
+ WearStatus = false;
+ }
}
- return TIME_;
+ WearStatus = true;
}
- void BloodOxygenModel::SetCheckTime(uint16_t time) { TIME_ = time; }
+ /**
+ * @brief Get the wear status.
+ * @return The wear status.
+ */
+ bool BloodOxygenModel::GetWearStatus() { return WearStatus; }
+
+ /**
+ * @brief Stop the blood oxygen test.
+ * @return The status of stopping the test.
+ */
+ bool BloodOxygenModel::StopTest()
+ {
+ wear_error = 0;
+ spo2_count = 0;
+ }
+ /**
+ * @brief Get an instance of the BloodOxygenModel.
+ * @return An instance of the BloodOxygenModel.
+ */
BloodOxygenModel *BloodOxygenModel::GetInstance()
{
static BloodOxygenModel instance;
#include "ppg_service.h"
#include "displaybrightness/include/DisplayBrightnessModel.h"
#include "power_display_service.h"
+#include "custom_utils.h"
+extern "C" errcode_t uapi_get_timestampe_ms(uint64_t *tm);
#define BLOODKEYABLE 0
namespace OHOS
static constexpr uint16_t PROGRESS_VALUE_MAX = 10;
/* -------------------------------------------------------------------------- */
// 获取当前的"时间分"
- uint16_t BloodOxygenPresenter::GetCurrentTime()
+ uint64_t BloodOxygenPresenter::GetCurrentTime()
{
- time_t now = time(0);
- struct tm *tblock = localtime(&now);
-
- uint16_t current_time = tblock->tm_hour * 60 + tblock->tm_min;
- return current_time;
+ uint64_t timestamp_ms;
+ errcode_t result = uapi_get_timestampe_ms(×tamp_ms);
+ return timestamp_ms;
}
- // 获取时间差
- std::string BloodOxygenPresenter::GetTDOA(uint16_t new_time, uint16_t old_time)
+ // 获取时间差,现在传进来的是两个时间戳
+ std::string BloodOxygenPresenter::GetTDOA(uint64_t new_time, uint64_t old_time)
{
if (new_time == old_time)
{
}
int time_diff = new_time - old_time;
- if (time_diff > 60)
+ int hours = time_diff / 3600000; // 将毫秒转换为小时
+ int minutes = (time_diff % 3600000) / 60000; // 将剩余的毫秒转换为分钟
+
+ std::stringstream ss;
+ if (hours > 0)
{
- int hours = time_diff / 60;
- int minutes = time_diff % 60;
- std::stringstream ss;
ss << hours << "小时";
- if (minutes > 0)
- {
- ss << minutes << "分钟";
- }
- return ss.str() + "前";
}
- else
+ if (minutes > 0)
+ {
+ ss << minutes << "分钟";
+ }
+ if (hours == 0 && minutes == 0)
{
- std::stringstream ss;
- ss << time_diff << "分钟前";
- return ss.str();
+ ss << "不到1分钟";
}
+ ss << "前";
+ return ss.str();
}
+
/* -------------------------------------------------------------------------- */
BloodOxygenPresenter::BloodOxygenPresenter()
{
uint8_t md = PPG_SERVICE_CMD_TYPE_DO_SPO2_TEST;
send_ppg_cmd_msg(md);
startspo2 = false;
+ BloodOxygenModel::GetInstance()->StartTest();
}
}
uint8_t md = PPG_SERVICE_CMD_TYPE_STOP_SPO2_TEST;
send_ppg_cmd_msg(md);
startspo2 = true;
+ BloodOxygenModel::GetInstance()->StopTest();
}
}
+
+ if (BloodOxygenModel::GetInstance()->GetWearStatus() == false)
+ {
+ BloodOxygenView::GetInstance()->ChangeView(BLOODCHECKVIEW, BLOODRESULT);
+ BloodOxygenModel::GetInstance()->SetCheckStatus(false); // 关闭检测
+ BloodOxygenModel::GetInstance()->SetBloodCheckViewStatus(false);
+ }
}
void BloodOxygenPresenter::ReturnInterface()
}
BloodOxygenModel::GetInstance()->SetCheckStatus(false); // 关闭检测
BloodOxygenModel::GetInstance()->SetBloodCheckViewStatus(false);
+ uint64_t timestamp_ms = GetCurrentTime();
+ BloodOxygenModel::GetInstance()->SetCheckTime(timestamp_ms); // 更新时间
}
- uint16_t time = GetCurrentTime();
- BloodOxygenModel::GetInstance()->SetCheckTime(time); // 更新时间
}
}
void BloodOxygenPresenter::Notify(void)
// 更新数据
std::string bloodoxygenStr = std::to_string(spo2_);
percent->SetText(bloodoxygenStr.c_str());
- // 更新时间
- uint16_t time = BloodOxygenPresenter::GetInstance()->GetCurrentTime();
- uint16_t check_time = BloodOxygenModel::GetInstance()->GetCheckTime();
- std::string TimeStr = BloodOxygenPresenter::GetInstance()->GetTDOA(time, check_time) + "检测";
- timeLabel->SetText(TimeStr.c_str());
}
else
{
percent->SetText("--");
- timeLabel->SetText("暂无检测结果");
+ // 更新时间
+ uint32_t time = BloodOxygenPresenter::GetInstance()->GetCurrentTime();
+ uint32_t check_time = BloodOxygenModel::GetInstance()->GetCheckTime();
+ std::string TimeStr = BloodOxygenPresenter::GetInstance()->GetTDOA(time, check_time) + "检测";
+ timeLabel->SetText(TimeStr.c_str());
+ // timeLabel->SetText("暂无检测结果");
}
}
{
std::string bloodoxygenStr = std::to_string(spo2_);
percent->SetText(bloodoxygenStr.c_str());
- // 更新时间
- uint16_t time = BloodOxygenPresenter::GetInstance()->GetCurrentTime();
- uint16_t check_time = BloodOxygenModel::GetInstance()->GetCheckTime();
- TimeStr = BloodOxygenPresenter::GetInstance()->GetTDOA(time, check_time);
}
else
{
percent->SetText("--");
- TimeStr = "暂无测量数据";
+ // 更新时间
+ uint64_t time = BloodOxygenPresenter::GetInstance()->GetCurrentTime();
+ uint64_t check_time = BloodOxygenModel::GetInstance()->GetCheckTime();
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "time:%lld check_time:%lld", time, check_time);
+ TimeStr = BloodOxygenPresenter::GetInstance()->GetTDOA(time, check_time);
+ // TimeStr = "暂无测量数据";
}
percent->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS);
percent->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
--- /dev/null
+{
+ "spo2_latest_data": {
+ "oxygen_value": 98,
+ "timestamp": 1646769855
+ },
+ "spo2_data_list": [
+ {
+ "oxygen_value": 95,
+ "timestamp": 1646769823
+ },
+ {
+ "oxygen_value": 97,
+ "timestamp": 1646769844
+ },
+ {
+ "oxygen_value": 96,
+ "timestamp": 1646769849
+ },
+ {
+ "oxygen_value": 98,
+ "timestamp": 1646769855
+ }
+ ],
+ "heart_latest_data": {
+ "heart_value": 88,
+ "timestamp": 1646769855
+ },
+ "heart_data_list": [
+ {
+ "heart_value": 95,
+ "timestamp": 1646769823
+ },
+ {
+ "heart_value": 57,
+ "timestamp": 1646769844
+ },
+ {
+ "heart_value": 86,
+ "timestamp": 1646769849
+ },
+ {
+ "heart_value": 88,
+ "timestamp": 1646769855
+ }
+ ]
+}
\ No newline at end of file
--- /dev/null
+#include "health_service.h"
+#include <iostream>
+#include <fstream>
+#include "wearable_log.h"
+#include "cJSON.h"
+namespace OHOS
+{
+ static HeartService *g_pHeartService = nullptr;
+ cJSON *root = NULL;
+ HeartService::HeartService()
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "HeartService::HeartService");
+ g_pHeartService = this;
+ }
+
+ HeartService::~HeartService()
+ {
+ g_pHeartService = nullptr;
+ }
+
+ HeartService *HeartService::GetInstance()
+ {
+ static HeartService instance;
+ return &instance;
+ }
+
+ bool HeartService::LoadJsonData()
+ {
+ std::ifstream inFile(HEALTH_JSON_PATH);
+ if (!inFile.is_open())
+ {
+ return -1;
+ }
+ std::string jsonDataString((std::istreambuf_iterator<char>(inFile)), std::istreambuf_iterator<char>());
+ const char *jsonData = jsonDataString.c_str();
+ root = cJSON_Parse(jsonData);
+ return true;
+ }
+
+ BloodOxygenData *HeartService::ReadBloodOxygenData()
+ {
+ LoadJsonData();
+ BloodOxygenData *data = new BloodOxygenData();
+ cJSON *latestData = cJSON_GetObjectItem(root, "spo2_latest_data");
+ data->SPO2 = cJSON_GetObjectItem(latestData, "oxygen_value")->valueint;
+ data->timestamp = cJSON_GetObjectItem(latestData, "timestamp")->valuedouble;
+ return data;
+ }
+
+ bool HeartService::UpdateBloodOxygenData(const BloodOxygenData &data)
+ {
+ LoadJsonData();
+ cJSON *latestData = cJSON_GetObjectItem(root, "spo2_latest_data");
+ if (latestData == NULL)
+ {
+ return false;
+ }
+ cJSON_ReplaceItemInObject(latestData, "oxygen_value", cJSON_CreateNumber(data.SPO2));
+ cJSON_ReplaceItemInObject(latestData, "timestamp", cJSON_CreateNumber(data.timestamp));
+
+ // 将数据添加到列表的最后
+ cJSON *dataList = cJSON_GetObjectItem(root, "spo2_data_list");
+ if (dataList != NULL && cJSON_IsArray(dataList))
+ {
+ cJSON *newData = cJSON_CreateObject();
+ cJSON_AddItemToObject(newData, "oxygen_value", cJSON_CreateNumber(data.SPO2));
+ cJSON_AddItemToObject(newData, "timestamp", cJSON_CreateNumber(data.timestamp));
+ cJSON_AddItemToArray(dataList, newData);
+ }
+ if (UpdateJsonData() == false)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "UpdateJsonData is error");
+ return false;
+ }
+ return true;
+ }
+ HeartRateData *HeartService::ReadHeartRateData()
+ {
+ LoadJsonData();
+ HeartRateData *data = new HeartRateData();
+ cJSON *latestData = cJSON_GetObjectItem(root, "heart_latest_data");
+ data->Heart = cJSON_GetObjectItem(latestData, "heart_value")->valueint;
+ data->timestamp = cJSON_GetObjectItem(latestData, "timestamp")->valuedouble;
+ return data;
+ }
+
+ bool HeartService::UpdateHeartRateData(const HeartRateData &data)
+ {
+ LoadJsonData();
+ cJSON *latestData = cJSON_GetObjectItem(root, "heart_latest_data");
+ if (latestData == NULL)
+ {
+ return false;
+ }
+ cJSON_ReplaceItemInObject(latestData, "heart_value", cJSON_CreateNumber(data.Heart));
+ cJSON_ReplaceItemInObject(latestData, "timestamp", cJSON_CreateNumber(data.timestamp));
+
+ // 将数据添加到列表的最后
+ cJSON *dataList = cJSON_GetObjectItem(root, "heart_data_list");
+ if (dataList != NULL && cJSON_IsArray(dataList))
+ {
+ cJSON *newData = cJSON_CreateObject();
+ cJSON_AddItemToObject(newData, "heart_value", cJSON_CreateNumber(data.Heart));
+ cJSON_AddItemToObject(newData, "timestamp", cJSON_CreateNumber(data.timestamp));
+ cJSON_AddItemToArray(dataList, newData);
+ }
+ if (UpdateJsonData() == false)
+ {
+ WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "UpdateJsonData is error");
+ return false;
+ }
+ return true;
+ }
+
+ bool HeartService::UpdateJsonData()
+ {
+ std::ofstream outFile(HEALTH_JSON_PATH);
+ if (!outFile.is_open())
+ {
+ return false;
+ }
+ char *jsonData = cJSON_Print(root);
+ if (jsonData == NULL)
+ {
+ outFile.close();
+ return false;
+ }
+ outFile << jsonData;
+ outFile.close();
+ cJSON_free(jsonData);
+ return true;
+ }
+}
\ No newline at end of file
--- /dev/null
+#ifndef HEART_SERVICE_H
+#define HEART_SERVICE_H
+
+#include "stdio.h"
+#include "string"
+
+#define HEART_MAX_POINTS 360
+namespace OHOS
+{
+ typedef struct
+ {
+ uint16_t SPO2; // 血氧值
+ uint64_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
+ {
+ uint16_t Heart; // 心率值
+ uint64_t timestamp; // 最近一次检测时间
+ } HeartRateData;
+
+ class HeartService
+ {
+ public:
+ HeartService();
+ ~HeartService();
+ static HeartService *GetInstance(void);
+ bool LoadJsonData(); // 加载json
+ BloodOxygenData *ReadBloodOxygenData(); // 读取血氧数据
+ bool UpdateBloodOxygenData(const BloodOxygenData &data); // 更新血氧数据
+ HeartRateData *ReadHeartRateData(); // 读取心率数据
+ bool UpdateHeartRateData(const HeartRateData &data); // 更新心率数据
+ bool UpdateJsonData(); // 更新json
+ private:
+ static constexpr const char *HEALTH_JSON_PATH = "/user/userdata/health.json";
+ };
+}
+#endif // HEALTH_MODEL_H
\ No newline at end of file
if (bloodoxygen != 0)\r
{\r
// 更新时间\r
- uint16_t time = BloodOxygenPresenter::GetInstance()->GetCurrentTime();\r
- uint16_t check_time = BloodOxygenModel::GetInstance()->GetCheckTime();\r
+ uint64_t time = BloodOxygenPresenter::GetInstance()->GetCurrentTime();\r
+ uint64_t check_time = BloodOxygenModel::GetInstance()->GetCheckTime();\r
std::string TimeStr = BloodOxygenPresenter::GetInstance()->GetTDOA(time, check_time) + "检测";\r
timeLabel->SetText(TimeStr.c_str());\r
}\r
void HandleMaxHeart(uint16_t coord, uint16_t value);\r
void HandleMinHeart(uint16_t coord, uint16_t value);\r
void SetHeartRatePerSec(uint32_t sec);\r
- void SetWearStatus(bool status);\r
- bool GetWearStatus(void);\r
uint16_t GetHeartRateMax(void);\r
uint16_t GetHeartRateMin(void);\r
\r
\r
bool GetCheckStatus();\r
void SetCheckStatus(bool checkstatus);\r
+ void SetWearStatus(uint8_t wear);\r
+ bool GetWearStatus(void);\r
+\r
+ void Heart_Start();\r
+ void Heart_Stop();\r
void UpHeartdata(uint16_t heart);\r
\r
uint16_t GetHeartdata();\r
uint16_t GetShowHeartdata();\r
- uint16_t GetCheckTime(); // 获取距离上传测试时间\r
- void SetCheckTime(uint16_t time); // 设置本次测试完的时间\r
+ uint64_t GetCheckTime(); // 获取距离上传测试时间\r
+ void SetCheckTime(uint64_t time); // 设置本次测试完的时间\r
uint16_t GetIndex(); // 测试点位\r
void SetIndex(uint16_t index);\r
\r
bool CheckStatus; // 检测状态标志\r
uint16_t Show_Heart_; // 显示血氧\r
uint16_t Heart_; // 保存血氧\r
- uint16_t TIME_; // 检测时间(存(时、分),大于24小时,改为1天前,小于1分钟为刚刚)\r
+ uint64 TIME_; // 检测时间(存(时、分),大于24小时,改为1天前,小于1分钟为刚刚)\r
\r
bool initstatus = true;\r
+ bool wearstatus;\r
+ uint8_t wear_;\r
+ uint64 timestamp_ms;\r
+ uint8_t wear_error;\r
};\r
}\r
\r
void ChangeView(int16_t hideView, int16_t showView);
UIScrollView *GetHeartScrollView(int ViewId);
void UpHeartText(); // 更新心率结果文本
+
private:
bool InitImageDisplay(void); // 初始化背景图片
bool InitLabel(void); // 初始化标签
return nullptr;
}
imageAnimator->SetImageAnimatorSrc(g_imageAnimatorInfo_Time, CHECKIMAGEANIMATORVIEW_SIZE, CHECKIMAGEANIMATORVIEW_SPEED);
- imageAnimator->SetRepeatTimes(20);
+ imageAnimator->SetRepeatTimes(30);
imageAnimator->SetRepeat(false);
imageAnimator->Start();
HeartCheckScrollView->Add(imageAnimator);
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HeartView::new HeartText fail");
return nullptr;
}
- HeartText->SetPosition(133, 110); // widget's left position and top position
- HeartText->Resize(200, 200); // widget's width and height
+ HeartText->SetPosition(83, 110); // widget's left position and top position
+ HeartText->Resize(300, 250); // widget's width and height
HeartText->SetViewId("label"); // Set style
HeartText->SetStyle(STYLE_TEXT_FONT, 140);
uint16_t heart_ = HeartModel::GetInstance()->GetHeartdata();
-#include "HeartModel.h"\r
+#include "heartrate/include/HeartModel.h"\r
#include "wearable_log.h"\r
#include "graphic_service.h"\r
#include "IndoorWalkPreparedView.h"\r
#include "IndoorWalkPresenter.h"\r
#include "MainViewSample.h"\r
-#include "HeartRateView.h"\r
+#include "heartrate/include/HeartRateView.h"\r
#include <iostream>\r
#include <random>\r
#include "heartrate/include/HeartView.h"\r
#include "heartrate/include/HeartPresenter.h"\r
#include "DialModelHeartRate.h"\r
+#include "health_service.h"\r
+#include "custom_utils.h"\r
+\r
+extern "C" errcode_t uapi_get_timestampe_ms(uint64_t *tm);\r
#ifdef __cplusplus\r
extern "C"\r
{\r
ResultView = false;\r
CheckStatus = false;\r
// 初始化血氧值\r
- Heart_ = DialModelHeartRate::GetInstance()->GetHeartData();\r
+ HeartRateData *data = new HeartRateData;\r
+ data = HeartService::GetInstance()->ReadHeartRateData();\r
+ Heart_ = data->Heart;\r
+ TIME_ = data->timestamp;\r
}\r
\r
HeartModel::~HeartModel()\r
aveCount = value;\r
}\r
\r
- void HeartModel::SetWearStatus(bool status)\r
- {\r
- wearStatus = status;\r
- }\r
-\r
- bool HeartModel::GetWearStatus(void)\r
- {\r
- return wearStatus;\r
- }\r
-\r
void HeartModel::RefreshHeartRateScreen(uint16_t perSec, uint16_t rest, uint16_t maxRate, uint16_t minRate)\r
{\r
UNUSED(rest);\r
}\r
}\r
}\r
- bool HeartModel::GetHeartViewStatus()\r
- {\r
- return HeartView;\r
- }\r
-\r
- bool HeartModel::GetHeartBandoffViewStatus()\r
- {\r
- return BandoffView;\r
- }\r
-\r
- bool HeartModel::GetHeartCheckViewStatus()\r
- {\r
- return CheckView;\r
- }\r
-\r
- void HeartModel::SetHeartBandoffViewStatus(bool bandoffViewStatus)\r
- {\r
- BandoffView = bandoffViewStatus;\r
- }\r
-\r
- bool HeartModel::GetHeartResultViewStaus()\r
- {\r
- return ResultView;\r
- }\r
-\r
- void HeartModel::SetHeartResultViewStatus(bool resultViewStatus)\r
+ /* ---------------------------------- 状态检测 ---------------------------------- */\r
+ /**\r
+ * @brief 设置佩戴状态\r
+ */\r
+ void HeartModel::Heart_Start()\r
{\r
- ResultView = resultViewStatus;\r
- }\r
+ //进行初始化操作\r
+ timestamp_ms=0;\r
\r
- void HeartModel::SetHeartViewStatus(bool heartViewStatus)\r
- {\r
- HeartView = heartViewStatus;\r
}\r
-\r
- void HeartModel::SetHeartCheckViewStatus(bool checkViewStatus)\r
+ /**\r
+ * @brief 设置结束状态\r
+ */\r
+ void HeartModel::Heart_Stop()\r
{\r
- CheckView = checkViewStatus;\r
}\r
\r
- bool HeartModel::GetCheckStatus()\r
+ /**\r
+ * @brief 设置佩戴状态\r
+ *\r
+ * @param wear 佩戴状态值\r
+ */\r
+ void HeartModel::SetWearStatus(uint8_t wear)\r
{\r
- return CheckStatus;\r
- }\r
-\r
- void HeartModel::SetCheckStatus(bool checkStatus)\r
- {\r
- CheckStatus = checkStatus;\r
- }\r
-\r
- uint16_t HeartModel::GetHeartdata()\r
- {\r
- return Heart_;\r
- }\r
-\r
- uint16_t HeartModel::GetShowHeartdata()\r
- {\r
- return Show_Heart_;\r
- }\r
+ // 设置佩戴状态\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Weartest::%d", wear);\r
+ wear_ = wear_;\r
\r
+ // 佩戴信息为错误\r
+ if (wear_ != 1)\r
+ {\r
+ // 佩戴错误计时器计数\r
+ wear_error++;\r
+ // 计数达到10次,停止检测\r
+ if (wear_error >= 10)\r
+ {\r
+ wearStatus = false;\r
+ }\r
+ }\r
+ wearStatus = true;\r
+ }\r
+\r
+ /**\r
+ * @brief 获取佩戴状态\r
+ *\r
+ * @return 佩戴状态\r
+ */\r
+ bool HeartModel::GetWearStatus(void) { return wearStatus; }\r
+\r
+ /**\r
+ * @brief 设置心率带视图状态\r
+ *\r
+ * @param bandoffViewStatus 心率带视图状态值\r
+ */\r
+ void HeartModel::SetHeartBandoffViewStatus(bool bandoffViewStatus) { BandoffView = bandoffViewStatus; }\r
+\r
+ /**\r
+ * @brief 获取心率带视图状态\r
+ *\r
+ * @return 心率带视图状态\r
+ */\r
+ bool HeartModel::GetHeartBandoffViewStatus() { return BandoffView; }\r
+\r
+ /**\r
+ * @brief 获取心率视图状态\r
+ *\r
+ * @return 心率视图状态\r
+ */\r
+ bool HeartModel::GetHeartViewStatus() { return HeartView; }\r
+\r
+ /**\r
+ * @brief 设置心率视图状态\r
+ *\r
+ * @param heartViewStatus 心率视图状态值\r
+ */\r
+ void HeartModel::SetHeartViewStatus(bool heartViewStatus) { HeartView = heartViewStatus; }\r
+\r
+ /**\r
+ * @brief 获取心率检测视图状态\r
+ *\r
+ * @return 心率检测视图状态\r
+ */\r
+ bool HeartModel::GetHeartCheckViewStatus() { return CheckView; }\r
+\r
+ /**\r
+ * @brief 设置心率检测视图状态\r
+ *\r
+ * @param checkViewStatus 心率检测视图状态值\r
+ */\r
+ void HeartModel::SetHeartCheckViewStatus(bool checkViewStatus) { CheckView = checkViewStatus; }\r
+\r
+ /**\r
+ * @brief 获取心率结果视图状态\r
+ *\r
+ * @return 心率结果视图状态\r
+ */\r
+ bool HeartModel::GetHeartResultViewStaus() { return ResultView; }\r
+\r
+ /**\r
+ * @brief 设置心率结果视图状态\r
+ *\r
+ * @param resultViewStatus 心率结果视图状态值\r
+ */\r
+ void HeartModel::SetHeartResultViewStatus(bool resultViewStatus) { ResultView = resultViewStatus; }\r
+\r
+ /**\r
+ * @brief 获取检测状态\r
+ *\r
+ * @return 检测状态\r
+ */\r
+ bool HeartModel::GetCheckStatus() { return CheckStatus; }\r
+\r
+ /**\r
+ * @brief 设置检测状态\r
+ *\r
+ * @param checkStatus 检测状态值\r
+ */\r
+ void HeartModel::SetCheckStatus(bool checkStatus) { CheckStatus = checkStatus; }\r
+\r
+ /**\r
+ * @brief 获取心率数据\r
+ *\r
+ * @return 心率数据\r
+ */\r
+ uint16_t HeartModel::GetHeartdata() { return Heart_; }\r
+\r
+ /**\r
+ * @brief 获取显示的心率数据\r
+ *\r
+ * @return 显示的心率数据\r
+ */\r
+ uint16_t HeartModel::GetShowHeartdata() { return Show_Heart_; }\r
+\r
+ /**\r
+ * @brief 更新心率数据\r
+ *\r
+ * @param heart 心率值\r
+ */\r
void HeartModel::UpHeartdata(uint16_t heart)\r
{\r
Show_Heart_ = heart;\r
}\r
}\r
\r
- uint16_t HeartModel::GetCheckTime()\r
+ /**\r
+ * @brief 获取检测时间\r
+ *\r
+ * @return 检测时间\r
+ */\r
+ uint64_t HeartModel::GetCheckTime()\r
{\r
if (initstatus)\r
{\r
+ // 获取当前时间\r
TIME_ = HeartPresenter::GetInstance()->GetCurrentTime();\r
initstatus = false;\r
}\r
return TIME_;\r
}\r
\r
- void HeartModel::SetCheckTime(uint16_t time)\r
- {\r
- TIME_ = time;\r
- }\r
+ /**\r
+ * @brief 设置检测时间\r
+ *\r
+ * @param time 检测时间值\r
+ */\r
+ void HeartModel::SetCheckTime(uint64_t time) { TIME_ = time; }\r
+\r
}\r
-#include "HeartPresenter.h"
+
#include "common/task_manager.h"
#include "components/ui_label.h"
#include "ChangeSliceListener.h"
#include "power_display_service.h"
#include "heartrate/include/HeartView.h"
-#include "HeartModel.h"
-#include "HeartCheckView.h"
-#include "HeartBandoffView.h"
+#include "heartrate/include/HeartModel.h"
+#include "heartrate/include/HeartPresenter.h"
+#include "heartrate/include/HeartCheckView.h"
+#include "heartrate/include/HeartBandoffView.h"
+#include "health_service.h"
#define HEARTKEYABLE 0
static constexpr uint16_t BUTTON_HEIGHT2 = 80;
// 标签设置
- static constexpr uint16_t PERCENT_X = 133;
+ static constexpr uint16_t PERCENT_X = 83;
static constexpr uint16_t PERCENT_Y = 103;
static constexpr uint16_t PERCENT_FONT_SIZE = 140;
static constexpr uint16_t TIMELABEL_X = 90;
return false;
}
percent->SetPosition(PERCENT_X, PERCENT_Y); // widget's left position and top position
- percent->Resize(200, 200); // widget's width and height
+ percent->Resize(300, 250); // widget's width and height
percent->SetViewId("label2"); // Set style
percent->SetStyle(STYLE_TEXT_FONT, PERCENT_FONT_SIZE);
uint16_t heart_ = HeartModel::GetInstance()->GetHeartdata();
{
#if USE_OFFLINE_DIAL
mainClockView = new DialViewGroup();
-#if 0
+#if 1
std::string filePath = dynamic_cast<MainPresenterSample *>(presenter_)->GetDialPath();
if (filePath.size() == 0)
{
- filePath = RES_PATH "/dials/dog.bin";
+ filePath = RES_PATH "/dials/Dynamic_cat.bin";
}
#endif
// DialUpdateModel::GetInstance()->LoadDialConfigFromJson();
- uint8_t fileid = DialUpdateModel::GetInstance()->GetDialConfigPath();
- std::string filePath = dialInfo[fileid].dialPath;
+ //uint8_t fileid = DialUpdateModel::GetInstance()->GetDialConfigPath();
+ //std::string filePath = dialInfo[fileid].dialPath;
mainClockView->SetDial(filePath);
-
#else
mainClockView = new MainClockView();
#endif
}\r
}\r
/* -------------------------------------------------------------------------- */\r
- #if 0\r
+ #if 1\r
uint32_t resId = dialHeader->previewImgId | dirId_;\r
uint32_t curReadPt = ftell(file);\r
ImageInfo* info = ImageCacheManager::GetInstance().LoadOneInMultiRes(resId, file_, file, false, imageOffset_);\r
${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/phoneservice/include
${CMAKE_CURRENT_SOURCE_DIR}/../../fd230app/nativeui/main/include/dial
${CMAKE_CURRENT_SOURCE_DIR}/../../fd230app/nativeui/bloodoxygen/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../fd230app/nativeui/heartrate/include
${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/main/include
${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/player/include
${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/bluetooth/include
${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/main/include
${CMAKE_CURRENT_SOURCE_DIR}/../../fd230app/nativeui/main/include/dial
${CMAKE_CURRENT_SOURCE_DIR}/../../fd230app/nativeui/bloodoxygen/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../fd230app/nativeui/heartrate/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../fd230app/nativeui/clock/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../fd230app/nativeui/activity/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../fd230app/nativeui/rtcservice/include
${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/player/include
${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativeui/bluetooth/include
${CMAKE_CURRENT_SOURCE_DIR}/../../nativeapp/nativelauncher/include
#include "DialModelHeartRate.h"
#include "DialModelSPO2.h"
#include "BloodOxygenModel.h"
+#include "HeartModel.h"
#include "ppg_service.h"
#include "CallerLogModel.h"
#include "notification_manager.h"
unused(req);
if ( topic == TOPIC_EVENT_WEARSTATE_UPDATE)
{
- // req->msgId
+ int32_t wear = *((int32_t*)(req->data)); // 进行类型转换
+
+ BloodOxygenModel::GetInstance()->SetWearStatus(wear);
+ HeartModel::GetInstance()->SetWearStatus(wear);
}
}
//心率
u_int8_t heart = *((u_int8_t*)(req->data)); // 进行类型转换
//通知对应信息进行更新
DialModelHeartRate::GetInstance()->UpdateHeartRate(heart);
+ HeartModel::GetInstance()->UpHeartdata(heart);
}
}
//开始检测心率
(void)sprintf_s(str, VER_STR_MAX, "\r\nVersion:%s %s %s\r\n",\r
get_version_string(), TARGET_NAME, BUILD_TIME);\r
#else\r
-#warning no BUILD_TIME\r
+//#warning no BUILD_TIME\r
(void)sprintf_s(str, VER_STR_MAX, "\r\nVersion:%s\r\n", get_version_string());\r
#endif\r
wstp_print(str);\r
--- /dev/null
+{
+ "spo2_latest_data": {
+ "oxygen_value": 98,
+ "timestamp": 1646769855
+ },
+ "spo2_data_list": [
+ {
+ "oxygen_value": 95,
+ "timestamp": 1646769823
+ },
+ {
+ "oxygen_value": 97,
+ "timestamp": 1646769844
+ },
+ {
+ "oxygen_value": 96,
+ "timestamp": 1646769849
+ },
+ {
+ "oxygen_value": 98,
+ "timestamp": 1646769855
+ }
+ ],
+ "heart_latest_data": {
+ "heart_value": 88,
+ "timestamp": 1646769855
+ },
+ "heart_data_list": [
+ {
+ "heart_value": 95,
+ "timestamp": 1646769823
+ },
+ {
+ "heart_value": 57,
+ "timestamp": 1646769844
+ },
+ {
+ "heart_value": 86,
+ "timestamp": 1646769849
+ },
+ {
+ "heart_value": 88,
+ "timestamp": 1646769855
+ }
+ ]
+}
\ No newline at end of file
hx3695_msg_callback_t func = hx3695_get_send_msg_callback_func();\r
if(func != NULL)\r
{\r
+ hrsresult.wearstatus = hrs_wear_status;\r
func(HX3695_MSG_TYPE_WEARSTAT_UPDATE,&hrsresult.wearstatus,sizeof(int32_t));\r
func(HX3695_MSG_TYPE_HRS_UPDATE,&hrsresult,sizeof(FT_CUSTOM_RESULTS_t));\r
}\r
return ERRCODE_SUCC;
}
+
+//穿戴状态
+errcode_t update_wearstatus_event_notify(int32_t wearstatus)
+{
+ CustomEventPublish(TOPIC_EVENT_WEARSTATE_UPDATE,(uint8_t*)&wearstatus,sizeof(wearstatus));
+ return 0;
+}
+errcode_t update_wearstatus_event_sendmsg_toUI(int32_t wearstatus)
+{
+ /**通过UI事件发送Notify*/
+ GraphicService::GetInstance()->PostGraphicEvent(std::bind(update_wearstatus_event_notify, wearstatus));
+ return ERRCODE_SUCC;
+}
+
#include "hx3695_hal.h"
void hx3695_msg_callback(uint8_t msg_type, uint8_t *msg_data, int32_t msg_datalen)
break;
case HX3695_MSG_TYPE_WEARSTAT_UPDATE:
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "HX3695_MSG_TYPE_WEARSTATUS_UPDATE = %d", sensor_data.wearstatus);
- //update_wearstatus_event_sendmsg_toUI(sensor_data.wearstatus);
+ update_wearstatus_event_sendmsg_toUI(sensor_data.wearstatus);
break;
default:
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Unknown sensor message type");
tz.tz_minuteswest = zone*60;
settimeofday(&tv, &tz);
-
-
-
}else{
printf("convert to time failed ret %d!\n",ret);
return ERRCODE_FAIL;