diff --git a/main/dnsannounce.cpp b/main/dnsannounce.cpp new file mode 100644 index 0000000..7b88648 --- /dev/null +++ b/main/dnsannounce.cpp @@ -0,0 +1,99 @@ +// 3rd party +#include +#include +#include + +// local +#include "dnsannounce.h" +#include "espwifistack.h" +#include "cpputils.h" +#include "lwip/dns.h" +#include "globals.h" + +void handle_dns_announce() +{ + const auto staStatus = wifi_stack::get_sta_status(); + const auto randDNSName = cpputils::randomNumber(espcpputils::esp_random_device{}); + if (staStatus == wifi_stack::WiFiStaStatus::CONNECTED) + { + EVERY_N_SECONDS ( 2 ) { + // Get IPv4 + if (const auto result = wifi_stack::get_ip_info(TCPIP_ADAPTER_IF_STA); result) + { + std::string curIpAddress = wifi_stack::toString(result->ip); + if (curIpAddress == "0.0.0.0") goto lookupIPv6; + if (dns_lastIpAddress_v4 != curIpAddress) + { + dns_lastIpAddress_v4 = curIpAddress; + ip_addr_t tmpIpResolved; + std::string toLookup = fmt::format("{}__{}.{}.announce.bobbycar.cloud", randDNSName, curIpAddress, OTA_USERNAME); + ESP_LOGI("BOBBY", "Trying to look up %s", toLookup.c_str()); + if (const auto err = dns_gethostbyname(toLookup.c_str(), &tmpIpResolved, NULL, NULL); err != ERR_OK && err != ERR_INPROGRESS) + { + ESP_LOGW("BOBBY", "There is a error in the matrix (dns ipv4 lookup failed) -> %d", err); + dns_lastIpAddress_v4 = "-"; + dns_lastIpAddress_v6 = "-"; + dns_lastIpAddress_v6_global = "-"; + } + } + } + else + { + ESP_LOGW("BOBBY", "get_ip_info() failed with %.*s", result.error().size(), result.error().data()); + } + lookupIPv6: + esp_ip6_addr_t tmpv6addr; + if (const auto result = esp_netif_get_ip6_linklocal(wifi_stack::esp_netifs[ESP_IF_WIFI_STA], &tmpv6addr); result == ESP_OK) + { + std::string curIpV6Address = wifi_stack::toString(tmpv6addr); + std::replace(curIpV6Address.begin(), curIpV6Address.end(), ':', '-'); + if (dns_lastIpAddress_v6 != curIpV6Address) + { + dns_lastIpAddress_v6 = curIpV6Address; + ip_addr_t tmpIpResolved; + std::string toLookup = fmt::format("{}__{}.{}.announce6.bobbycar.cloud", randDNSName, curIpV6Address, OTA_USERNAME); + ESP_LOGI("BOBBY", "Trying to look up %s", toLookup.c_str()); + if (const auto err = dns_gethostbyname(toLookup.c_str(), &tmpIpResolved, NULL, NULL); err != ERR_OK && err != ERR_INPROGRESS) + { + ESP_LOGW("BOBBY", "There is a error in the matrix (dns ipv6 local lookup failed) -> %d", err); + dns_lastIpAddress_v4 = "-"; + dns_lastIpAddress_v6 = "-"; + dns_lastIpAddress_v6_global = "-"; + } + } + } + + if (const auto result = esp_netif_get_ip6_global(wifi_stack::esp_netifs[ESP_IF_WIFI_STA], &tmpv6addr); result == ESP_OK) + { + std::string curIpV6Address = wifi_stack::toString(tmpv6addr); + if (dns_lastIpAddress_v6_global != curIpV6Address) + { + dns_lastIpAddress_v6_global = curIpV6Address; + std::replace(curIpV6Address.begin(), curIpV6Address.end(), ':', '-'); + ip_addr_t tmpIpResolved; + std::string toLookup = fmt::format("{}global__{}.{}.announce6.bobbycar.cloud", randDNSName, curIpV6Address, OTA_USERNAME); + ESP_LOGI("BOBBY", "Trying to look up %s", toLookup.c_str()); + if (const auto err = dns_gethostbyname(toLookup.c_str(), &tmpIpResolved, NULL, NULL); err != ERR_OK && err != ERR_INPROGRESS) + { + ESP_LOGW("BOBBY", "There is a error in the matrix (dns ipv6 global lookup failed) -> %d", err); + dns_lastIpAddress_v4 = "-"; + dns_lastIpAddress_v6 = "-"; + dns_lastIpAddress_v6_global = "-"; + } + } + } + } + + EVERY_N_SECONDS( 120 ) { + dns_lastIpAddress_v4 = "-"; + dns_lastIpAddress_v6 = "-"; + dns_lastIpAddress_v6_global = "-"; + } + } + else + { + dns_lastIpAddress_v4 = "-"; + dns_lastIpAddress_v6 = "-"; + dns_lastIpAddress_v6_global = "-"; + } +} diff --git a/main/dnsannounce.h b/main/dnsannounce.h new file mode 100644 index 0000000..e9da219 --- /dev/null +++ b/main/dnsannounce.h @@ -0,0 +1,2 @@ +#pragma once +void handle_dns_announce(); diff --git a/main/drivingstatistics.cpp b/main/drivingstatistics.cpp new file mode 100644 index 0000000..4852217 --- /dev/null +++ b/main/drivingstatistics.cpp @@ -0,0 +1,163 @@ +#include "drivingstatistics.h" + +// 3rd party +#include +#include "TFT_eSPI.h" + +// Local +#include "globals.h" +#include "battery.h" +#include "utils.h" + +float getAvgWhPerKm() +{ + return drivingStatistics.wh_used / (drivingStatistics.meters_driven / 1000.f); +} + +std::string getEfficiencyClassString() +{ + const float avgWhPerKm = getAvgWhPerKm(); + if (avgWhPerKm <= 14) + { + return "A+++"; + } + else if (avgWhPerKm <= 16) + { + return "A++"; + } + else if (avgWhPerKm <= 18) + { + return "A+"; + } + else if (avgWhPerKm <= 20) + { + return "A"; + } + else if (avgWhPerKm <= 24) + { + return "B"; + } + else if (avgWhPerKm <= 28) + { + return "C"; + } + else if (avgWhPerKm <= 32) + { + return "D"; + } + else if (avgWhPerKm <= 36) + { + return "E"; + } + else if (avgWhPerKm <= 40) + { + return "F"; + } + else + { + return "G"; + } +} + +uint16_t getEfficiencyClassColor() +{ + const float avgWhPerKm = getAvgWhPerKm(); + if (avgWhPerKm <= 14) + { + return 0x1700; + } + else if (avgWhPerKm <= 16) + { + return 0x3640; + } + else if (avgWhPerKm <= 18) + { + return 0x5560; + } + else if (avgWhPerKm <= 20) + { + return 0x6CA0; + } + else if (avgWhPerKm <= 24) + { + return 0x83E0; + } + else if (avgWhPerKm <= 28) + { + return 0x9B20; + } + else if (avgWhPerKm <= 32) + { + return 0xB240; + } + else if (avgWhPerKm <= 36) + { + return 0xC980; + } + else if (avgWhPerKm <= 40) + { + return 0xE0C0; + } + else + { + return 0xF800; + } +} + +void calculateStatistics() +{ + EVERY_N_MILLIS( 10 ) { + static bool saveTotal = false; + + if ((settings.savedStatistics.totalCentimeters / 100.f) > drivingStatistics.totalMeters) + { + drivingStatistics.totalMeters = settings.savedStatistics.totalCentimeters / 100.f; + drivingStatistics.last_cm_written = settings.savedStatistics.totalCentimeters; + } + + static auto last_km_calculation = espchrono::millis_clock::now(); + const auto duration = espchrono::ago(last_km_calculation).count() / 1000.0f; + last_km_calculation = espchrono::millis_clock::now(); + + const float meters_driven_now = (abs(avgSpeedKmh) / 3.6) * duration; + drivingStatistics.meters_driven += meters_driven_now; + drivingStatistics.totalMeters += meters_driven_now; // Udate meters driven + + if (abs(avgSpeedKmh) > 1) + { + if (!saveTotal && abs(avgSpeedKmh) > 5) + { + saveTotal = true; + } + drivingStatistics.currentDrivingTime += duration; + + float avgVoltage = 0; + for (auto &controller : controllers) + { + avgVoltage += controller.getCalibratedVoltage(); + } + avgVoltage = avgVoltage / controllers.size(); + + auto watt = sumCurrent * avgVoltage; + const float ws_driven_now = watt * duration; + drivingStatistics.wh_used += ws_driven_now / 3600; // Wh + drivingStatistics.batteryWhEstimate -= ws_driven_now / 3600; + } + else + { + drivingStatistics.wh_used += (13 * duration) / 3600; // Wh + drivingStatistics.batteryWhEstimate = getRemainingWattHours(); + } + + if ((drivingStatistics.totalMeters > ((drivingStatistics.last_cm_written / 100.f) + 100)) || (saveTotal && abs(avgSpeedKmh) < 0.5)) + { + if (saveTotal) + { + saveTotal = false; + } + drivingStatistics.last_cm_written = drivingStatistics.totalMeters * 100; // Save total Meters + settings.savedStatistics.totalCentimeters = drivingStatistics.last_cm_written; + saveSettings(); + } + } +} diff --git a/main/drivingstatistics.h b/main/drivingstatistics.h new file mode 100644 index 0000000..bd1fd08 --- /dev/null +++ b/main/drivingstatistics.h @@ -0,0 +1,7 @@ +#pragma once +#include + +void calculateStatistics(); +float getAvgWhPerKm(); +std::string getEfficiencyClassString(); +uint16_t getEfficiencyClassColor();