From 2ab6328bd089678f430f7fbfcad2a86b1d9ca0e0 Mon Sep 17 00:00:00 2001 From: avatarsd Date: Tue, 3 Feb 2026 18:27:58 +0200 Subject: [PATCH 1/3] style(glance-strain): format code in Service.cpp for consistency Apply consistent code formatting by removing unnecessary newlines in function definitions and bodies, aligning with project style guidelines. --- .../Software/Libs/Source/Service.cpp | 226 +++++++----------- 1 file changed, 86 insertions(+), 140 deletions(-) diff --git a/Apps/GlanceStrain/Software/Libs/Source/Service.cpp b/Apps/GlanceStrain/Software/Libs/Source/Service.cpp index bd8abccf..892d7c87 100644 --- a/Apps/GlanceStrain/Software/Libs/Source/Service.cpp +++ b/Apps/GlanceStrain/Software/Libs/Source/Service.cpp @@ -20,136 +20,108 @@ #include "icon_30x30.h" Service::Service(SDK::Kernel &kernel) - : mKernel(kernel), mName("Strain Score"), mGlanceUI(), mGlanceTitle(), mGlanceValue(), mSensorHR(SDK::Sensor::Type::HEART_RATE), mSensorActivity(SDK::Sensor::Type::ACTIVITY) -{ -} + : mKernel(kernel), + mName("Strain Score"), + mGlanceUI(), + mGlanceTitle(), + mGlanceValue(), + mSensorHR(SDK::Sensor::Type::HEART_RATE), + mSensorActivity(SDK::Sensor::Type::ACTIVITY) {} -Service::~Service() -{ - disconnect(); -} +Service::~Service() { disconnect(); } -void Service::run() -{ +void Service::run() { LOG_INFO("Started\n"); createGuiControls(); LOG_DEBUG("GUI controls created\n"); - if (configGui()) - { + if (configGui()) { LOG_DEBUG("GUI configured successfully\n"); connect(); checkDayRollover(); - } - else - { + } else { return; } - while (true) - { + while (true) { SDK::MessageBase *msg; - if (!mKernel.comm.getMessage(msg)) - { + if (!mKernel.comm.getMessage(msg)) { continue; } - switch (msg->getType()) - { - case SDK::MessageType::EVENT_GLANCE_START: - LOG_INFO("GLANCE is now running\n"); - - case SDK::MessageType::COMMAND_APP_STOP: - LOG_INFO("Force exit from the application\n"); - case SDK::MessageType::EVENT_GLANCE_STOP: - LOG_INFO("GLANCE has stopped\n"); - saveJson(); - // disconnect(); - // mKernel.comm.releaseMessage(msg); - // return; - - case SDK::MessageType::EVENT_GLANCE_TICK: - LOG_DEBUG("Glance tick event\n"); - onGlanceTick(); - break; - - case SDK::MessageType::EVENT_SENSOR_LAYER_DATA: - { - LOG_DEBUG("Sensor data event\n"); - auto event = static_cast(msg); - this->onSdlNewData(event->handle, - event->data, - event->count, - event->stride); - } - break; - - default: - break; + switch (msg->getType()) { + case SDK::MessageType::EVENT_GLANCE_START: + LOG_INFO("GLANCE is now running\n"); + + case SDK::MessageType::COMMAND_APP_STOP: + LOG_INFO("Force exit from the application\n"); + case SDK::MessageType::EVENT_GLANCE_STOP: + LOG_INFO("GLANCE has stopped\n"); + saveJson(); + // disconnect(); + // mKernel.comm.releaseMessage(msg); + // return; + + case SDK::MessageType::EVENT_GLANCE_TICK: + LOG_DEBUG("Glance tick event\n"); + onGlanceTick(); + break; + + case SDK::MessageType::EVENT_SENSOR_LAYER_DATA: { + LOG_DEBUG("Sensor data event\n"); + auto event = static_cast(msg); + this->onSdlNewData(event->handle, event->data, event->count, event->stride); + } break; + + default: + break; } mKernel.comm.releaseMessage(msg); } } -void Service::connect() -{ - if (!mSensorHR.isConnected()) - { +void Service::connect() { + if (!mSensorHR.isConnected()) { LOG_DEBUG("Connect to HR sensors...\n"); mSensorHR.connect(); } - if (!mSensorActivity.isConnected()) - { + if (!mSensorActivity.isConnected()) { LOG_DEBUG("Connect to Activity sensor...\n"); mSensorActivity.connect(); } } -void Service::disconnect() -{ +void Service::disconnect() { LOG_DEBUG("Disconnect from sensors...\n"); saveJson(); - if (mSensorHR.isConnected()) - { + if (mSensorHR.isConnected()) { mSensorHR.disconnect(); } - if (mSensorActivity.isConnected()) - { + if (mSensorActivity.isConnected()) { mSensorActivity.disconnect(); } } -void Service::onSdlNewData(uint16_t handle, - const SDK::Sensor::Data *data, - uint16_t count, - uint16_t stride) -{ +void Service::onSdlNewData(uint16_t handle, const SDK::Sensor::Data *data, uint16_t count, uint16_t stride) { SDK::Sensor::DataBatch batch(data, count, stride); - if (mSensorActivity.matchesDriver(handle)) - { - if (count > 0) - { + if (mSensorActivity.matchesDriver(handle)) { + if (count > 0) { SDK::SensorDataParser::Activity p(batch[0]); - if (p.isDataValid()) - { + if (p.isDataValid()) { mActiveMin = p.getDuration(); } } } - if (mSensorHR.matchesDriver(handle)) - { - for (uint16_t i = 0; i < count; ++i) - { + if (mSensorHR.matchesDriver(handle)) { + for (uint16_t i = 0; i < count; ++i) { SDK::SensorDataParser::HeartRate p(batch[i]); - if (p.isDataValid()) - { + if (p.isDataValid()) { uint16_t hr = p.getBpm(); - if (hr >= 50 && hr <= 220) - { + if (hr >= 50 && hr <= 220) { float norm = (static_cast(hr) - 60.0f) / 120.0f; float delta = std::max(0.0f, norm) * 0.75f; mTotalStrain += delta; @@ -157,8 +129,7 @@ void Service::onSdlNewData(uint16_t handle, mMaxHR = std::max(mMaxHR, hr); mSampleCount++; uint64_t ts = p.getTimestamp(); - if (mSamples.size() < 1440u) - { + if (mSamples.size() < 1440u) { mSamples.push_back({ts, hr, delta}); } } @@ -167,8 +138,7 @@ void Service::onSdlNewData(uint16_t handle, } } -void Service::onGlanceTick() -{ +void Service::onGlanceTick() { checkDayRollover(); // float avg_hr = (mSampleCount > 0) ? (mSumHR / static_cast(mSampleCount)) : 0.0f; @@ -179,21 +149,16 @@ void Service::onGlanceTick() std::time_t now = std::time(nullptr); bool need_save = false; - if (mTickCount % 60 == 0) - need_save = true; - if (now - mLastSaveTime > 3600) - need_save = true; - if (need_save) - { + if (mTickCount % 60 == 0) need_save = true; + if (now - mLastSaveTime > 3600) need_save = true; + if (need_save) { saveJson(); mLastSaveTime = now; } - if (mGlanceUI.isInvalid()) - { + if (mGlanceUI.isInvalid()) { auto *upd = mKernel.comm.allocateMessage(); - if (upd) - { + if (upd) { upd->name = mName; upd->controls = mGlanceUI.data(); upd->controlsNumber = static_cast(mGlanceUI.size()); @@ -206,16 +171,12 @@ void Service::onGlanceTick() } } -bool Service::configGui() -{ +bool Service::configGui() { bool status = false; auto *gc = mKernel.comm.allocateMessage(); - if (gc) - { - if (mKernel.comm.sendMessage(gc, 100) && gc->getResult() == SDK::MessageResult::SUCCESS) - { - if (gc->maxControls >= 3) - { + if (gc) { + if (mKernel.comm.sendMessage(gc, 100) && gc->getResult() == SDK::MessageResult::SUCCESS) { + if (gc->maxControls >= 3) { mGlanceUI.setWidth(gc->width); mGlanceUI.setHeight(gc->height); status = true; @@ -227,8 +188,7 @@ bool Service::configGui() return status; } -void Service::createGuiControls() -{ +void Service::createGuiControls() { mGlanceUI.createImage().init({31, 15}, {60, 60}, ICON_60X60_ABGR2222); mGlanceTitle = mGlanceUI.createText(); @@ -246,8 +206,7 @@ void Service::createGuiControls() .alignment(GlanceAlignH_t::GLANCE_ALIGN_H_CENTER); } -void Service::checkDayRollover() -{ +void Service::checkDayRollover() { LOG_DEBUG("Checking day rollover\n"); std::time_t now_t = std::time(nullptr); std::tm tm_now; @@ -256,11 +215,9 @@ void Service::checkDayRollover() std::strftime(now_date, sizeof(now_date), "%Y-%m-%d", &tm_now); LOG_DEBUG("Current date: %s\n", now_date); - if (std::strlen(mCurrentDate) == 0 || std::strcmp(mCurrentDate, now_date) != 0) - { + if (std::strlen(mCurrentDate) == 0 || std::strcmp(mCurrentDate, now_date) != 0) { LOG_DEBUG("Date changed from '%s' to '%s'\n", mCurrentDate, now_date); - if (std::strlen(mCurrentDate) > 0) - { + if (std::strlen(mCurrentDate) > 0) { saveJson(); } std::strncpy(mCurrentDate, now_date, 10); @@ -280,64 +237,53 @@ void Service::checkDayRollover() } } -void Service::saveJson() -{ +void Service::saveJson() { LOG_DEBUG("Saving JSON to %s\n", mJsonPath); auto json_buf = std::make_shared>(); size_t offset = 0; float avg_hr = (mSampleCount > 0) ? (mSumHR / static_cast(mSampleCount)) : 0.0f; - offset = std::snprintf(reinterpret_cast(json_buf->data()), json_buf->size(), - "{\"date\":\"%s\",\"total_strain\":%.1f,\"avg_hr\":%.1f,\"max_hr\":%u,\"active_min\":%lu,\"samples\":[", - mCurrentDate, mTotalStrain, avg_hr, mMaxHR, mActiveMin); + offset = std::snprintf( + reinterpret_cast(json_buf->data()), json_buf->size(), + "{\"date\":\"%s\",\"total_strain\":%.1f,\"avg_hr\":%.1f,\"max_hr\":%u,\"active_min\":%lu,\"samples\":[", + mCurrentDate, mTotalStrain, avg_hr, mMaxHR, mActiveMin); LOG_DEBUG("Initial JSON offset: %zu\n", offset); bool first_sample = true; - for (const auto &s : mSamples) - { - if (!first_sample) - { - offset += std::snprintf(reinterpret_cast(json_buf->data()) + offset, json_buf->size() - offset, ","); - } - else - { + for (const auto &s : mSamples) { + if (!first_sample) { + offset += + std::snprintf(reinterpret_cast(json_buf->data()) + offset, json_buf->size() - offset, ","); + } else { first_sample = false; } offset += std::snprintf(reinterpret_cast(json_buf->data()) + offset, json_buf->size() - offset, "{\"timestamp\":%llu,\"hr\":%hu,\"strain_delta\":%.3f}", - static_cast(s.timestamp), static_cast(s.hr), s.strain_delta); + static_cast(s.timestamp), static_cast(s.hr), + s.strain_delta); } LOG_DEBUG("Samples processed, offset: %zu\n", offset); offset += std::snprintf(reinterpret_cast(json_buf->data()) + offset, json_buf->size() - offset, "]}"); LOG_DEBUG("Final JSON offset: %zu\n", offset); - if (offset > 0 && offset < json_buf->size()) - { + if (offset > 0 && offset < json_buf->size()) { // mKernel.fs.mkdir("/Apps"); // mKernel.fs.mkdir("/Apps/strain"); // mKernel.fs.mkdir("/Apps/strain/storage"); auto file = mKernel.fs.file(mJsonPath); - if (file && file->open(true, true)) - { // write mode, create/override + if (file && file->open(true, true)) { // write mode, create/override size_t bw; file->write(reinterpret_cast(json_buf->data()), offset, bw); - if (bw == offset) - { + if (bw == offset) { LOG_INFO("Saved strain data to %s\n", mJsonPath); - } - else - { + } else { LOG_ERROR("Failed to write complete JSON data\n"); } file->close(); - } - else - { + } else { LOG_ERROR("Failed to open file %s for writing\n", mJsonPath); } - } - else - { + } else { LOG_ERROR("JSON buffer overflow or empty\n"); } } \ No newline at end of file From f31ca7205c8986e12bf4990d48c4787f9d9e507f Mon Sep 17 00:00:00 2001 From: avatarsd Date: Tue, 3 Feb 2026 20:31:37 +0200 Subject: [PATCH 2/3] fix(glance-strain): correct stop logic to save and disconnect on app stop Move saveJson() and disconnect() calls from EVENT_GLANCE_STOP to COMMAND_APP_STOP case, add timeout to sensor connect calls, and include debug log in onSdlNewData for better tracing. --- .../GlanceStrain/Software/Libs/Source/Service.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Apps/GlanceStrain/Software/Libs/Source/Service.cpp b/Apps/GlanceStrain/Software/Libs/Source/Service.cpp index 892d7c87..ef468680 100644 --- a/Apps/GlanceStrain/Software/Libs/Source/Service.cpp +++ b/Apps/GlanceStrain/Software/Libs/Source/Service.cpp @@ -56,12 +56,12 @@ void Service::run() { case SDK::MessageType::COMMAND_APP_STOP: LOG_INFO("Force exit from the application\n"); + saveJson(); + disconnect(); + mKernel.comm.releaseMessage(msg); + return; case SDK::MessageType::EVENT_GLANCE_STOP: LOG_INFO("GLANCE has stopped\n"); - saveJson(); - // disconnect(); - // mKernel.comm.releaseMessage(msg); - // return; case SDK::MessageType::EVENT_GLANCE_TICK: LOG_DEBUG("Glance tick event\n"); @@ -85,11 +85,11 @@ void Service::run() { void Service::connect() { if (!mSensorHR.isConnected()) { LOG_DEBUG("Connect to HR sensors...\n"); - mSensorHR.connect(); + mSensorHR.connect(2000); } if (!mSensorActivity.isConnected()) { LOG_DEBUG("Connect to Activity sensor...\n"); - mSensorActivity.connect(); + mSensorActivity.connect(2000); } } @@ -106,7 +106,8 @@ void Service::disconnect() { void Service::onSdlNewData(uint16_t handle, const SDK::Sensor::Data *data, uint16_t count, uint16_t stride) { SDK::Sensor::DataBatch batch(data, count, stride); - + + LOG_DEBUG("New data from SDL...\n"); if (mSensorActivity.matchesDriver(handle)) { if (count > 0) { SDK::SensorDataParser::Activity p(batch[0]); From 55ed6ada031869fbd4c3f168b857e18afed7c5d5 Mon Sep 17 00:00:00 2001 From: avatarsd Date: Fri, 6 Feb 2026 11:23:45 +0200 Subject: [PATCH 3/3] fix(glance-strain): adjust stop logic to save on glance stop and move gui config to start event Refactor the Service::run() method to handle GUI configuration within the EVENT_GLANCE_START case, and modify stop handling to save JSON on EVENT_GLANCE_STOP instead of COMMAND_APP_STOP. Also, move checkDayRollover() from onGlanceTick() to saveJson() to ensure it runs during save operations. --- .../Software/Libs/Source/Service.cpp | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Apps/GlanceStrain/Software/Libs/Source/Service.cpp b/Apps/GlanceStrain/Software/Libs/Source/Service.cpp index ef468680..908817a6 100644 --- a/Apps/GlanceStrain/Software/Libs/Source/Service.cpp +++ b/Apps/GlanceStrain/Software/Libs/Source/Service.cpp @@ -35,13 +35,7 @@ void Service::run() { createGuiControls(); LOG_DEBUG("GUI controls created\n"); - if (configGui()) { - LOG_DEBUG("GUI configured successfully\n"); - connect(); - checkDayRollover(); - } else { - return; - } + while (true) { SDK::MessageBase *msg; @@ -53,15 +47,23 @@ void Service::run() { switch (msg->getType()) { case SDK::MessageType::EVENT_GLANCE_START: LOG_INFO("GLANCE is now running\n"); + if (configGui()) { + LOG_DEBUG("GUI configured successfully\n"); + connect(); + checkDayRollover(); + } + break; case SDK::MessageType::COMMAND_APP_STOP: LOG_INFO("Force exit from the application\n"); - saveJson(); - disconnect(); - mKernel.comm.releaseMessage(msg); - return; + // saveJson(); + // disconnect(); + // mKernel.comm.releaseMessage(msg); + // return; + break; case SDK::MessageType::EVENT_GLANCE_STOP: LOG_INFO("GLANCE has stopped\n"); + saveJson(); case SDK::MessageType::EVENT_GLANCE_TICK: LOG_DEBUG("Glance tick event\n"); @@ -140,8 +142,6 @@ void Service::onSdlNewData(uint16_t handle, const SDK::Sensor::Data *data, uint1 } void Service::onGlanceTick() { - checkDayRollover(); - // float avg_hr = (mSampleCount > 0) ? (mSumHR / static_cast(mSampleCount)) : 0.0f; mGlanceValue.print("%.1f", mTotalStrain); @@ -239,6 +239,8 @@ void Service::checkDayRollover() { } void Service::saveJson() { + checkDayRollover(); + LOG_DEBUG("Saving JSON to %s\n", mJsonPath); auto json_buf = std::make_shared>(); size_t offset = 0;