From 861f9af1f9a9d011376bcb0805666a5485eb04c2 Mon Sep 17 00:00:00 2001 From: Martin Brodbeck Date: Mon, 2 Jan 2023 17:24:58 +0100 Subject: [PATCH] More on retrieving and parsing dates. --- .vscode/settings.json | 7 +++- src/abfall.cpp | 13 ++++++- src/http_client.cpp | 17 ++++++---- src/utils.cpp | 79 +++++++++++++++++++++++++++++++++++++++++++ src/utils.h | 20 ++++++++++- 5 files changed, 127 insertions(+), 9 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 3a54357..dd70b93 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,6 +17,11 @@ "cmake.generator": "Unix Makefiles", "cortex-debug.openocdPath": "${env:HOME}/pico/openocd/src/openocd", "files.associations": { - "string": "cpp" + "string": "cpp", + "string_view": "cpp", + "deque": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "chrono": "cpp" }, } \ No newline at end of file diff --git a/src/abfall.cpp b/src/abfall.cpp index a3c189b..dc4923c 100644 --- a/src/abfall.cpp +++ b/src/abfall.cpp @@ -34,18 +34,29 @@ int main() { printf("Attempt %d for retrieving data.\n", i); csv = client.retrieveWasteDatesAsCsv(); if (csv.length() > 0) { + printf("Data received!\n"); break; } } - printf("%s\n", csv.c_str()); + + if (csv.length() == 0) { + printf("Error getting data. Exiting!"); + cyw43_arch_deinit(); + return 1; + } char datetime_buf[256]; char *datetime_str = &datetime_buf[0]; datetime_t dt; + auto dates = parseCsv(csv); + printf("Number of Dates: %d\n", dates.size()); + while (true) { rtc_get_datetime(&dt); + + datetime_to_str(datetime_str, sizeof(datetime_buf), &dt); // printf("DateTime: %s\n", datetime_str); led.switchColor(Color::OFF); diff --git a/src/http_client.cpp b/src/http_client.cpp index 4591435..8f9ece8 100644 --- a/src/http_client.cpp +++ b/src/http_client.cpp @@ -22,11 +22,10 @@ err_t headers_callback(httpc_state_t *connection, void *arg, struct pbuf *hdr, u err_t body_callback(void *arg, struct altcp_pcb *conn, struct pbuf *p, err_t err) { bool *test = (bool *)arg; - printf("..."); + //printf("..."); pbuf_copy_partial(p, myBuffer, p->tot_len, 0); // printf("%s", myBuffer); - // TODO: Parse CSV *test = true; return ERR_OK; @@ -45,15 +44,21 @@ std::string HttpClient::retrieveWasteDatesAsCsv() { err_t err = httpc_get_file_dns("beenas.brodbeck-online.de", port, "/abfall/abfall.csv", &m_settings, body_callback, &m_received, nullptr); - // printf("Status %d\n", err); + //printf("Status %d\n", err); - printf("Waiting for waste dates "); + //printf("Waiting for waste dates "); + uint wait_count = 0; while (m_received == false) { - sleep_ms(100); + ++wait_count; + //printf("."); + if (wait_count >= 10) { + return test; + } + sleep_ms(1000); } - printf(" received.\n"); + //printf(" received.\n"); test.append(myBuffer); diff --git a/src/utils.cpp b/src/utils.cpp index 8214d1c..b3d9947 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,6 +1,85 @@ #include "utils.h" +#include +#include +#include + +using std::istringstream; using std::string; +using namespace std::chrono; + +std::vector parseCsv(const std::string &csv) { + istringstream stream(csv); + string line; + std::vector dates; + + // Get rid of the first line + std::getline(stream, line); + + while (std::getline(stream, line)) { + string delimiter = ";"; + size_t pos = 0; + string token; + uint tokenPos = 0; + while ((pos = line.find(delimiter)) != std::string::npos) { + token = line.substr(0, pos); + // std::cout << token << std::endl; + + if (token.length() > 0) { + istringstream liness(token); + string day_str, month_str, year_str; + getline(liness, day_str, '.'); + getline(liness, month_str, '.'); + getline(liness, year_str, '.'); + int day = atoi(day_str.c_str()); + int month = atoi(month_str.c_str()); + int year = atoi(year_str.c_str()); + year_month_day date{std::chrono::year{year}, std::chrono::month{(uint)month}, + std::chrono::day{(uint)day}}; + + std::vector::iterator it; + WasteDate wd; + it = std::find_if(dates.begin(), dates.end(), + [&date](const WasteDate &x) { return date == x.date; }); + if (it == dates.end()) { + wd.date = date; + dates.push_back(wd); + wd = dates.back(); + } else { + wd = *it; + } + + switch (tokenPos) { + case 0: + printf("Gelber Sack: %s\n", token.c_str()); + wd.wasteTypes.push_back(Waste::GelberSack); + break; + case 1: + printf("Papiertonne: %s\n", token.c_str()); + wd.wasteTypes.push_back(Waste::Papiertonne); + break; + case 2: + printf("Biotonne: %s\n", token.c_str()); + wd.wasteTypes.push_back(Waste::Biotonne); + break; + case 3: + printf("Restmüll: %s\n", token.c_str()); + wd.wasteTypes.push_back(Waste::Restmuell); + break; + case 4: + printf("Problemstoffmobil: %s\n", token.c_str()); + wd.wasteTypes.push_back(Waste::Problemstoffmobil); + break; + } + } + + line.erase(0, pos + delimiter.length()); + ++tokenPos; + } + } + + return dates; +} int wifi_setup_impl(uint32_t country, const string &ssid, const string &pw, bool firstTry) { if (firstTry) { diff --git a/src/utils.h b/src/utils.h index acbe558..44e3ecb 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,8 +1,26 @@ #pragma once +#include #include +#include #include "pico/cyw43_arch.h" -static int wifi_setup_impl(uint32_t country, const std::string &ssid, const std::string &pw, bool firstTry = true); +enum class Waste { + Restmuell, + GelberSack, + Papiertonne, + Biotonne, + Problemstoffmobil, +}; + +struct WasteDate { + std::chrono::year_month_day date; + std::vector wasteTypes; +}; + +std::vector parseCsv(const std::string& csv); + +static int wifi_setup_impl(uint32_t country, const std::string &ssid, const std::string &pw, + bool firstTry = true); void wifi_setup(); \ No newline at end of file