#include "utils.h" #include #include #include using std::istringstream; using std::string; using namespace std::chrono; bool isDST(int8_t day, int8_t month, int8_t dow) { // January, february, november and december are out. if (month < 3 || month > 10) { return false; } // April to September are in if (month > 3 && month < 10) { return true; } int previousSunday = day - dow; // In march, we are DST if our previous sunday was on or after the 25th. if (month == 3) { return previousSunday >= 25; } // In October we must be before the last sunday to be DST. // That means the previous sunday must be before the 25st. return previousSunday < 25; } std::vector parseCsv(const std::string &csv) { istringstream stream(csv); string line{""}; std::vector dates; // Get rid of the first line (header) std::getline(stream, line); while (std::getline(stream, line)) { string delimiter = ";"; size_t pos = 0; string token; uint tokenPos = 0; while ((pos = line.find_first_of(delimiter)) != std::string::npos) { token = line.substr(0, pos); 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; it = std::find_if(dates.begin(), dates.end(), [&date](const WasteDate &x) { return date == x.date; }); if (it == dates.end()) { WasteDate wd; wd.date = date; dates.push_back(wd); it = std::prev(dates.end()); } switch (tokenPos) { case 0: it->wasteTypes.push_back(Waste::GelberSack); break; case 1: it->wasteTypes.push_back(Waste::Papiertonne); break; case 2: it->wasteTypes.push_back(Waste::Biotonne); break; case 3: it->wasteTypes.push_back(Waste::Restmuell); break; case 4: it->wasteTypes.push_back(Waste::Problemstoffmobil); break; default: #ifdef DEBUG printf("Unknown waste token detected.\n"); #endif break; } } line.erase(0, pos + delimiter.length()); ++tokenPos; } // std::cout << "Size left: " << line.size() << " - " << line << std::endl; } return dates; } int wifi_setup_impl(uint32_t country, const string &ssid, const string &pw, bool firstTry) { if (firstTry) { if (cyw43_arch_init_with_country(country)) { return 1; } } cyw43_arch_enable_sta_mode(); netif_set_hostname(netif_default, "AbfallPicoW"); if (cyw43_arch_wifi_connect_async(ssid.c_str(), pw.c_str(), CYW43_AUTH_WPA2_MIXED_PSK)) { return 2; } int flashrate = 1000; int status = CYW43_LINK_UP + 1; while (status >= 0 && status != CYW43_LINK_UP) { int status_new = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA); if (status_new != status) { status = status_new; if (status < 0) { continue; } flashrate = flashrate / (status + 1); // printf("Connect status: %d %d\n", status, flashrate); } cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1); sleep_ms(flashrate); cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0); sleep_ms(flashrate); } if (status < 0) { cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0); } else { cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1); #ifdef DEBUG printf("IP: %s\n", ip4addr_ntoa(netif_ip_addr4(netif_default))); #endif } return status; } void wifi_setup() { const string ssid{"Apis cerana"}; const string pw{"2JkJEh2vptVT"}; const uint32_t country{CYW43_COUNTRY_GERMANY}; bool firstTry = true; int res = -1; do { if (firstTry) { res = wifi_setup_impl(country, ssid, pw, true); firstTry = false; } else { #ifdef DEBUG printf("Setting up connection failed. Trying again after 5 sec...\n"); #endif sleep_ms(5000); res = wifi_setup_impl(country, ssid, pw, false); } } while (res != CYW43_LINK_UP); }