diff options
author | Avamander <avamander@gmail.com> | 2021-06-10 00:44:49 +0300 |
---|---|---|
committer | Avamander <avamander@gmail.com> | 2021-12-04 22:03:40 +0200 |
commit | bda96dc595aecb56739cc02de7e7d2d825927b7f (patch) | |
tree | 152bc21ba805fedb05f73db17311f4a6c2877443 /src/displayapp | |
parent | 6ba28786055e0538cf0b7631cd33b36f02d46deb (diff) |
Initial Weather service skeleton
Diffstat (limited to 'src/displayapp')
-rw-r--r-- | src/displayapp/screens/Weather.cpp | 246 | ||||
-rw-r--r-- | src/displayapp/screens/Weather.h | 54 |
2 files changed, 300 insertions, 0 deletions
diff --git a/src/displayapp/screens/Weather.cpp b/src/displayapp/screens/Weather.cpp new file mode 100644 index 00000000..014761bf --- /dev/null +++ b/src/displayapp/screens/Weather.cpp @@ -0,0 +1,246 @@ +#include "Weather.h" +#include <lvgl/lvgl.h> +#include "../DisplayApp.h" +#include "Label.h" +#include "Version.h" +#include "components/battery/BatteryController.h" +#include "components/ble/BleController.h" +#include "components/brightness/BrightnessController.h" +#include "components/datetime/DateTimeController.h" +#include "drivers/Watchdog.h" +#include "components/ble/weather/WeatherData.h" + +using namespace Pinetime::Applications::Screens; + +Weather::Weather(Pinetime::Applications::DisplayApp* app, + Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Battery& batteryController, + Pinetime::Controllers::BrightnessController& brightnessController, + Pinetime::Controllers::Ble& bleController, + Pinetime::Drivers::WatchdogView& watchdog) + : Screen(app), + dateTimeController {dateTimeController}, + batteryController {batteryController}, + brightnessController {brightnessController}, + bleController {bleController}, + watchdog {watchdog}, + screens {app, + 0, + {[this]() -> std::unique_ptr<Screen> { + return CreateScreen1(); + }, + [this]() -> std::unique_ptr<Screen> { + return CreateScreen2(); + }, + [this]() -> std::unique_ptr<Screen> { + return CreateScreen3(); + }, + [this]() -> std::unique_ptr<Screen> { + return CreateScreen4(); + }, + [this]() -> std::unique_ptr<Screen> { + return CreateScreen5(); + }}, + Screens::ScreenListModes::UpDown} { +} + +Weather::~Weather() { + lv_obj_clean(lv_scr_act()); +} + +bool Weather::Refresh() { + if (running) { + screens.Refresh(); + } + return running; +} + +bool Weather::OnButtonPushed() { + running = false; + return true; +} + +bool Weather::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return screens.OnTouchEvent(event); +} + +std::unique_ptr<Screen> Weather::CreateScreen1() { + lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_recolor(label, true); + lv_label_set_text_fmt(label, + "#FFFF00 InfiniTime#\n\n" + "#444444 Version# %ld.%ld.%ld\n\n" + "#444444 Build date#\n" + "%s\n" + "%s\n", + Version::Major(), + Version::Minor(), + Version::Patch(), + __DATE__, + __TIME__); + lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); + lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + return std::unique_ptr<Screen>(new Screens::Label(0, 5, app, label)); +} + +std::unique_ptr<Screen> Weather::CreateScreen2() { + auto batteryPercent = static_cast<uint8_t>(batteryController.PercentRemaining()); + float batteryVoltage = batteryController.Voltage(); + + auto resetReason = [this]() { + switch (watchdog.ResetReason()) { + case Drivers::Watchdog::ResetReasons::Watchdog: + return "wtdg"; + case Drivers::Watchdog::ResetReasons::HardReset: + return "hardr"; + case Drivers::Watchdog::ResetReasons::NFC: + return "nfc"; + case Drivers::Watchdog::ResetReasons::SoftReset: + return "softr"; + case Drivers::Watchdog::ResetReasons::CpuLockup: + return "cpulock"; + case Drivers::Watchdog::ResetReasons::SystemOff: + return "off"; + case Drivers::Watchdog::ResetReasons::LpComp: + return "lpcomp"; + case Drivers::Watchdog::ResetReasons::DebugInterface: + return "dbg"; + case Drivers::Watchdog::ResetReasons::ResetPin: + return "rst"; + default: + return "?"; + } + }(); + + // uptime + static constexpr uint32_t secondsInADay = 60 * 60 * 24; + static constexpr uint32_t secondsInAnHour = 60 * 60; + static constexpr uint32_t secondsInAMinute = 60; + uint32_t uptimeSeconds = dateTimeController.Uptime().count(); + uint32_t uptimeDays = (uptimeSeconds / secondsInADay); + uptimeSeconds = uptimeSeconds % secondsInADay; + uint32_t uptimeHours = uptimeSeconds / secondsInAnHour; + uptimeSeconds = uptimeSeconds % secondsInAnHour; + uint32_t uptimeMinutes = uptimeSeconds / secondsInAMinute; + uptimeSeconds = uptimeSeconds % secondsInAMinute; + // TODO handle more than 100 days of uptime + + if (batteryPercent == -1) + batteryPercent = 0; + + // hack to not use the flot functions from printf + uint8_t batteryVoltageBytes[2]; + batteryVoltageBytes[1] = static_cast<uint8_t>(batteryVoltage); // truncate whole numbers + batteryVoltageBytes[0] = + static_cast<uint8_t>((batteryVoltage - batteryVoltageBytes[1]) * 100); // remove whole part of flt and shift 2 places over + // + + lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_recolor(label, true); + lv_label_set_text_fmt(label, + "#444444 Date# %02d/%02d/%04d\n" + "#444444 Time# %02d:%02d:%02d\n" + "#444444 Uptime#\n %02lud %02lu:%02lu:%02lu\n" + "#444444 Battery# %d%%/%1i.%02iv\n" + "#444444 Backlight# %s\n" + "#444444 Last reset# %s\n", + dateTimeController.Day(), + static_cast<uint8_t>(dateTimeController.Month()), + dateTimeController.Year(), + dateTimeController.Hours(), + dateTimeController.Minutes(), + dateTimeController.Seconds(), + uptimeDays, + uptimeHours, + uptimeMinutes, + uptimeSeconds, + batteryPercent, + batteryVoltageBytes[1], + batteryVoltageBytes[0], + brightnessController.ToString(), + resetReason); + lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + return std::unique_ptr<Screen>(new Screens::Label(1, 4, app, label)); +} + +std::unique_ptr<Screen> Weather::CreateScreen3() { + lv_mem_monitor_t mon; + lv_mem_monitor(&mon); + + lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_recolor(label, true); + auto& bleAddr = bleController.Address(); + lv_label_set_text_fmt(label, + "#444444 BLE MAC#\n" + " %02x:%02x:%02x:%02x:%02x:%02x" + "\n" + "#444444 Memory#\n" + " #444444 used# %d (%d%%)\n" + " #444444 frag# %d%%\n" + " #444444 free# %d" + "\n" + "#444444 Steps# %li", + bleAddr[5], + bleAddr[4], + bleAddr[3], + bleAddr[2], + bleAddr[1], + bleAddr[0], + (int) mon.total_size - mon.free_size, + mon.used_pct, + mon.frag_pct, + (int) mon.free_biggest_size, + 0); + lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + return std::unique_ptr<Screen>(new Screens::Label(2, 5, app, label)); +} + +bool sortById(const TaskStatus_t& lhs, const TaskStatus_t& rhs) { + return lhs.xTaskNumber < rhs.xTaskNumber; +} + +std::unique_ptr<Screen> Weather::CreateScreen4() { + TaskStatus_t tasksStatus[7]; + lv_obj_t* infoTask = lv_table_create(lv_scr_act(), NULL); + lv_table_set_col_cnt(infoTask, 3); + lv_table_set_row_cnt(infoTask, 8); + lv_obj_set_pos(infoTask, 10, 10); + + lv_table_set_cell_value(infoTask, 0, 0, "#"); + lv_table_set_col_width(infoTask, 0, 50); + lv_table_set_cell_value(infoTask, 0, 1, "Task"); + lv_table_set_col_width(infoTask, 1, 80); + lv_table_set_cell_value(infoTask, 0, 2, "Free"); + lv_table_set_col_width(infoTask, 2, 90); + + auto nb = uxTaskGetSystemState(tasksStatus, 7, nullptr); + std::sort(tasksStatus, tasksStatus + nb, sortById); + for (uint8_t i = 0; i < nb; i++) { + + lv_table_set_cell_value(infoTask, i + 1, 0, std::to_string(tasksStatus[i].xTaskNumber).c_str()); + lv_table_set_cell_value(infoTask, i + 1, 1, tasksStatus[i].pcTaskName); + if (tasksStatus[i].usStackHighWaterMark < 20) { + std::string str1 = std::to_string(tasksStatus[i].usStackHighWaterMark) + " low"; + lv_table_set_cell_value(infoTask, i + 1, 2, str1.c_str()); + } else { + lv_table_set_cell_value(infoTask, i + 1, 2, std::to_string(tasksStatus[i].usStackHighWaterMark).c_str()); + } + } + return std::unique_ptr<Screen>(new Screens::Label(3, 5, app, infoTask)); +} + +std::unique_ptr<Screen> Weather::CreateScreen5() { + lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_recolor(label, true); + lv_label_set_text_static(label, + "Software Licensed\n" + "under the terms of\n" + "the GNU General\n" + "Public License v3\n" + "#444444 Source code#\n" + "#FFFF00 https://github.com/#\n" + "#FFFF00 JF002/InfiniTime#"); + lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); + lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + return std::unique_ptr<Screen>(new Screens::Label(4, 5, app, label)); +} diff --git a/src/displayapp/screens/Weather.h b/src/displayapp/screens/Weather.h new file mode 100644 index 00000000..8b393ca1 --- /dev/null +++ b/src/displayapp/screens/Weather.h @@ -0,0 +1,54 @@ +#pragma once + +#include <memory> +#include "Screen.h" +#include "ScreenList.h" + +namespace Pinetime { + namespace Controllers { + class DateTime; + class Battery; + class BrightnessController; + class Ble; + } + + namespace Drivers { + class WatchdogView; + } + + namespace Applications { + class DisplayApp; + + namespace Screens { + class Weather : public Screen { + public: + explicit Weather(DisplayApp* app, + Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Battery& batteryController, + Pinetime::Controllers::BrightnessController& brightnessController, + Pinetime::Controllers::Ble& bleController, + Pinetime::Drivers::WatchdogView& watchdog); + ~Weather() override; + bool Refresh() override; + bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; + + private: + bool running = true; + + Pinetime::Controllers::DateTime& dateTimeController; + Pinetime::Controllers::Battery& batteryController; + Pinetime::Controllers::BrightnessController& brightnessController; + Pinetime::Controllers::Ble& bleController; + Pinetime::Drivers::WatchdogView& watchdog; + + ScreenList<5> screens; + std::unique_ptr<Screen> CreateScreen1(); + std::unique_ptr<Screen> CreateScreen2(); + std::unique_ptr<Screen> CreateScreen3(); + std::unique_ptr<Screen> CreateScreen4(); + std::unique_ptr<Screen> CreateScreen5(); + }; + } + } +}
\ No newline at end of file |