abfall/src/utils.cpp

173 lines
5 KiB
C++
Raw Normal View History

2023-01-02 14:54:46 +01:00
#include "utils.h"
2023-01-02 17:24:58 +01:00
#include <algorithm>
#include <iostream>
#include <sstream>
using std::istringstream;
2023-01-02 14:54:46 +01:00
using std::string;
2023-01-02 17:24:58 +01:00
using namespace std::chrono;
2023-01-03 17:03:51 +01:00
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;
}
2023-01-02 17:24:58 +01:00
std::vector<WasteDate> parseCsv(const std::string &csv) {
istringstream stream(csv);
2023-01-03 17:03:51 +01:00
string line{""};
2023-01-02 17:24:58 +01:00
std::vector<WasteDate> dates;
2023-01-03 12:07:19 +01:00
// Get rid of the first line (header)
2023-01-02 17:24:58 +01:00
std::getline(stream, line);
while (std::getline(stream, line)) {
string delimiter = ";";
size_t pos = 0;
string token;
uint tokenPos = 0;
2023-01-03 17:03:51 +01:00
while ((pos = line.find_first_of(delimiter)) != std::string::npos) {
2023-01-02 17:24:58 +01:00
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<WasteDate>::iterator it;
2023-01-03 12:07:19 +01:00
2023-01-02 17:24:58 +01:00
it = std::find_if(dates.begin(), dates.end(),
[&date](const WasteDate &x) { return date == x.date; });
if (it == dates.end()) {
2023-01-03 12:07:19 +01:00
WasteDate wd;
2023-01-02 17:24:58 +01:00
wd.date = date;
dates.push_back(wd);
2023-01-03 12:07:19 +01:00
it = std::prev(dates.end());
2023-01-02 17:24:58 +01:00
}
switch (tokenPos) {
case 0:
2023-01-03 12:07:19 +01:00
it->wasteTypes.push_back(Waste::GelberSack);
2023-01-02 17:24:58 +01:00
break;
case 1:
2023-01-03 12:07:19 +01:00
it->wasteTypes.push_back(Waste::Papiertonne);
2023-01-02 17:24:58 +01:00
break;
case 2:
2023-01-03 12:07:19 +01:00
it->wasteTypes.push_back(Waste::Biotonne);
2023-01-02 17:24:58 +01:00
break;
case 3:
2023-01-03 12:07:19 +01:00
it->wasteTypes.push_back(Waste::Restmuell);
2023-01-02 17:24:58 +01:00
break;
case 4:
2023-01-03 12:07:19 +01:00
it->wasteTypes.push_back(Waste::Problemstoffmobil);
2023-01-02 17:24:58 +01:00
break;
2023-01-03 08:57:39 +01:00
default:
#ifdef DEBUG
printf("Unknown waste token detected.\n");
#endif
break;
2023-01-02 17:24:58 +01:00
}
}
line.erase(0, pos + delimiter.length());
++tokenPos;
}
2023-01-03 17:03:51 +01:00
// std::cout << "Size left: " << line.size() << " - " << line << std::endl;
2023-01-02 17:24:58 +01:00
}
return dates;
}
2023-01-02 14:54:46 +01:00
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);
2023-01-03 08:57:39 +01:00
#ifdef DEBUG
2023-01-02 14:54:46 +01:00
printf("IP: %s\n", ip4addr_ntoa(netif_ip_addr4(netif_default)));
2023-01-03 08:57:39 +01:00
#endif
2023-01-02 14:54:46 +01:00
}
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 {
2023-01-03 08:57:39 +01:00
#ifdef DEBUG
2023-01-02 14:54:46 +01:00
printf("Setting up connection failed. Trying again after 5 sec...\n");
2023-01-03 08:57:39 +01:00
#endif
2023-01-02 14:54:46 +01:00
sleep_ms(5000);
res = wifi_setup_impl(country, ssid, pw, false);
}
} while (res != CYW43_LINK_UP);
}