From 4a83118557f94dddb50cc534b5d724eea93f06fc Mon Sep 17 00:00:00 2001 From: Totoo Date: Tue, 19 Nov 2024 17:39:30 +0100 Subject: [PATCH] Weather csv log (#2369) --- .../application/apps/ui_weatherstation.cpp | 31 +++++++++++++++++++ .../application/apps/ui_weatherstation.hpp | 29 +++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/firmware/application/apps/ui_weatherstation.cpp b/firmware/application/apps/ui_weatherstation.cpp index 21fd5911..2eae1607 100644 --- a/firmware/application/apps/ui_weatherstation.cpp +++ b/firmware/application/apps/ui_weatherstation.cpp @@ -25,6 +25,7 @@ #include "audio.hpp" #include "baseband_api.hpp" #include "string_format.hpp" +#include "file_path.hpp" #include "portapack_persistent_memory.hpp" #include "../baseband/fprotos/fprotogeneral.hpp" @@ -35,6 +36,21 @@ namespace pmem = portapack::persistent_memory; namespace ui { +std::string WeatherRecentEntry::to_csv() { + std::string csv = ";"; + csv += WeatherView::getWeatherSensorTypeName((FPROTO_WEATHER_SENSOR)sensorType); + csv += ";" + to_string_dec_uint(id) + ";"; + csv += to_string_decimal(temp, 2) + ";"; + csv += to_string_dec_uint(humidity) + ";"; + csv += to_string_dec_uint(channel) + ";"; + csv += to_string_dec_uint(battery_low); + return csv; +} + +void WeatherLogger::log_data(WeatherRecentEntry& data) { + log_file.write_entry(data.to_csv()); +} + void WeatherRecentEntryDetailView::update_data() { // set text elements text_type.set(WeatherView::getWeatherSensorTypeName((FPROTO_WEATHER_SENSOR)entry_.sensorType)); @@ -98,8 +114,11 @@ WeatherView::WeatherView(NavigationView& nav) &field_frequency, &options_temperature, &button_clear_list, + &check_log, &recent_entries_view}); + logger = std::make_unique(); + baseband::run_image(portapack::spi_flash::image_tag_weather); button_clear_list.on_select = [this](Button&) { @@ -114,6 +133,15 @@ WeatherView::WeatherView(NavigationView& nav) }; options_temperature.set_selected_index(weather_units_fahr, false); + check_log.on_select = [this](Checkbox&, bool v) { + logging = v; + if (logger && logging) { + logger->append(logs_dir.string() + "/WEATHERLOG_" + to_string_timestamp(rtc_time::now()) + ".CSV"); + logger->write_header(); + } + }; + check_log.set_value(logging); + const Rect content_rect{0, header_height, screen_width, screen_height - header_height}; recent_entries_view.set_parent_rect(content_rect); recent_entries_view.on_select = [this](const WeatherRecentEntry& entry) { @@ -140,6 +168,9 @@ void WeatherView::on_tick_second() { void WeatherView::on_data(const WeatherDataMessage* data) { WeatherRecentEntry key = process_data(data); + if (logger && logging) { + logger->log_data(key); + } // WeatherRecentEntry key{data->sensorType, data->id, data->temp, data->humidity, data->channel, data->battery_low}; auto matching_recent = find(recent, key.key()); if (matching_recent != std::end(recent)) { diff --git a/firmware/application/apps/ui_weatherstation.hpp b/firmware/application/apps/ui_weatherstation.hpp index d1dfd563..6c265e51 100644 --- a/firmware/application/apps/ui_weatherstation.hpp +++ b/firmware/application/apps/ui_weatherstation.hpp @@ -30,6 +30,7 @@ #include "app_settings.hpp" #include "radio_state.hpp" #include "utility.hpp" +#include "log_file.hpp" #include "recent_entries.hpp" #include "../baseband/fprotos/weathertypes.hpp" @@ -78,7 +79,25 @@ struct WeatherRecentEntry { void reset_age() { age = 0; } + + std::string to_csv(); }; + +class WeatherLogger { + public: + Optional append(const std::filesystem::path& filename) { + return log_file.append(filename); + } + + void log_data(WeatherRecentEntry& data); + void write_header() { + log_file.write_entry(";Type; id; Temp; Hum; CH; Batt"); + } + + private: + LogFile log_file{}; +}; + using WeatherRecentEntries = RecentEntries; using WeatherRecentEntriesView = RecentEntriesView; @@ -103,11 +122,13 @@ class WeatherView : public View { 1'750'000 /* bandwidth */, 2'000'000 /* sampling rate */, ReceiverModel::Mode::AMAudio}; + bool logging = false; app_settings::SettingsManager settings_{ "rx_weather", app_settings::Mode::RX, { {"units_fahr"sv, &weather_units_fahr}, + {"log"sv, &logging}, }}; WeatherRecentEntries recent{}; @@ -140,8 +161,16 @@ class WeatherView : public View { {0, 16, 7 * 8, 32}, "Clear"}; + Checkbox check_log{ + {10 * 8, 18}, + 3, + "Log", + true}; + static constexpr auto header_height = 3 * 16; + std::unique_ptr logger{}; + const RecentEntriesColumns columns{{ {"Type", 10}, {"Temp", 5},