diff --git a/src/panel/wifi.cpp b/src/panel/wifi.cpp index 5a26497..5338870 100644 --- a/src/panel/wifi.cpp +++ b/src/panel/wifi.cpp @@ -19,13 +19,21 @@ wifi::wifi(){ std::cerr << "WIFI CONSTRUCTOR\n"; _texture = nullptr; _time_on_screen = WIFI_DEFAULT_TIME_ON_SCREEN; + _update_interval = std::chrono::milliseconds{WIFI_UPDATE_INTERVAL}; _title = WIFI_TITLE; + + api_curl = curl_easy_init(); + curl_easy_setopt(api_curl, CURLOPT_WRITEFUNCTION, + dashboard::panel::wifi::curl_callback); + curl_easy_setopt(api_curl, CURLOPT_WRITEDATA, &json_string); } wifi::~wifi(){ std::cerr << "WIFI DECONSTRUCTOR\n"; if(_texture != nullptr) SDL_DestroyTexture(_texture); + if(api_curl != nullptr) + curl_easy_cleanup(api_curl); } /////////////////////////////////////////////////////////////////////////////// @@ -40,6 +48,14 @@ void wifi::draw(){ update_texture(); } + //check if its time to update + if((std::chrono::high_resolution_clock::now() - _last_update) + > _update_interval){ + update(); + + update_texture(); + } + SDL_RenderCopy(board::getRenderer(), _texture, NULL, NULL); } @@ -51,12 +67,91 @@ void wifi::draw(){ // Update the information of wifi // This DOES NOT update the display void wifi::update() { - //this shows static info on the wifi network, which does need to change - //therefore, no update + std::cerr << "WIFI::UPDATE\n"; + _last_update = std::chrono::high_resolution_clock::now(); + + if(WIFI_HOMEASSISTANT){ + curl_easy_setopt(api_curl, CURLOPT_URL, + WIFI_HOMEASSISTANT_URL); + std::string api_string = "Authorization: Bearer "; + api_string += WIFI_HOMEASSISTANT_APIKEY; + + struct curl_slist *headers; + headers = NULL; + headers = curl_slist_append(headers, api_string.c_str()); + headers = curl_slist_append(headers, "Content-Type: application/json"); + + curl_easy_setopt(api_curl, CURLOPT_HTTPHEADER, headers); + + api_string.clear(); + + //perform request + curl_easy_perform(api_curl); + + //parse the result + json_doc.Parse(json_string.c_str()); + + //update internal state + for(rapidjson::SizeType i = 0; i < json_doc.Size(); i++){ + //if router external IP + if(strcmp(json_doc[i]["entity_id"].GetString(), + WIFI_HOMEASSISTANT_ROUTER_EXTERNAL_IP) == 0 + && WIFI_SHOW_PUBLIC_IP){ + //store it in public IP field + public_ip = "WAN IP: "; + public_ip += json_doc[i]["state"].GetString(); + } //if router WAN status + else if (strcmp(json_doc[i]["entity_id"].GetString(), + WIFI_HOMEASSISTANT_ROUTER_WAN_STATUS) == 0){ + if(strcmp(json_doc[i]["state"].GetString(), "Connected") == 0) + wan_status = true; + else + wan_status = false; + } //speedtest up + else if (strcmp(json_doc[i]["entity_id"].GetString(), + WIFI_HOMEASSISTANT_SPEEDTEST_UP) == 0 + && WIFI_HOMEASSISTANT_SPEEDTEST){ + speedtest_up = "Upload: "; + speedtest_up += json_doc[i]["state"].GetString(); + speedtest_up += "MBps"; + } //speedtest down + else if (strcmp(json_doc[i]["entity_id"].GetString(), + WIFI_HOMEASSISTANT_SPEEDTEST_DOWN) == 0 + && WIFI_HOMEASSISTANT_SPEEDTEST){ + speedtest_down = "Download: "; + speedtest_down += json_doc[i]["state"].GetString(); + speedtest_down += "MBps"; + } //speedtest ping + else if (strcmp(json_doc[i]["entity_id"].GetString(), + WIFI_HOMEASSISTANT_SPEEDTEST_PING) == 0 + && WIFI_HOMEASSISTANT_SPEEDTEST){ + speedtest_ping = "Ping: "; + speedtest_ping += json_doc[i]["state"].GetString(); + speedtest_ping += "ms"; + } + } + } + + //if not using home assistant, grab it via normal method + if(WIFI_SHOW_PUBLIC_IP){ + //get the string from normal url + if(!WIFI_HOMEASSISTANT){ + public_ip = "WAN IP: "; + curl_easy_setopt(api_curl, CURLOPT_URL, + WIFI_PUBLIC_IP_URL); + + //peform request + curl_easy_perform(api_curl); + + //parse the result + public_ip += json_string; + } + //the public IP should have already been grabbed above + } } /////////////////////////////////////// -// Update the texture that is being +// Update the texture that is being // displayed. Due to the nature of what // is being displayed, this will only // ever be called once, as the wifi @@ -110,24 +205,15 @@ void wifi::update_texture(){ board::getString(password_string.c_str(), { "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt); + tgt.y += tgt.h + 25; + TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), + wan_status ? "Internet is up" : "Internet is down; reconnecting", &tgt.w, &tgt.h); + SDL_RenderCopy(board::getRenderer(), + board::getString(wan_status ? "Internet is up" : "Internet is down; reconnecting", + { "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt); + //Get public ip address and display it if(WIFI_SHOW_PUBLIC_IP){ - std::string public_ip = "WAN IP: "; - CURL* curl; - curl = curl_easy_init(); - - if(curl){ - CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, WIFI_PUBLIC_IP_URL); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, - dashboard::panel::wifi::curl_callback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &public_ip); - res = curl_easy_perform(curl); - curl_easy_cleanup(curl); - } else { - public_ip += "Unkown"; - } - tgt.y += tgt.h + 25; TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), public_ip.c_str(), &tgt.w, &tgt.h); @@ -136,6 +222,29 @@ void wifi::update_texture(){ { "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt); } + //TODO display speedtest info + tgt.y += tgt.h + 25; + TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), + speedtest_ping.c_str(), &tgt.w, &tgt.h); + SDL_RenderCopy(board::getRenderer(), + board::getString(speedtest_ping.c_str(), + { "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt); + + tgt.y += tgt.h + 25; + TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), + speedtest_up.c_str(), &tgt.w, &tgt.h); + SDL_RenderCopy(board::getRenderer(), + board::getString(speedtest_up.c_str(), + { "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt); + + tgt.y += tgt.h + 25; + TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), + speedtest_down.c_str(), &tgt.w, &tgt.h); + SDL_RenderCopy(board::getRenderer(), + board::getString(speedtest_down.c_str(), + { "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt); + + SDL_SetRenderTarget(board::getRenderer(), NULL); } @@ -148,8 +257,8 @@ void wifi::initTexture(){ std::cerr << "WIFI INIT TEXTURE\n"; if(_texture == nullptr){ _texture = SDL_CreateTexture(board::getRenderer(), - SDL_PIXELFORMAT_RGBA8888, - SDL_TEXTUREACCESS_TARGET, + SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT); SDL_SetTextureBlendMode(_texture, SDL_BLENDMODE_BLEND); @@ -158,7 +267,7 @@ void wifi::initTexture(){ /////////////////////////////////////// // Curl callback function -size_t dashboard::panel::wifi::curl_callback(void* contents, size_t size, +size_t dashboard::panel::wifi::curl_callback(void* contents, size_t size, size_t nmemb, void* userp){ ((std::string*)userp)->append((char*)contents, size * nmemb); return size * nmemb; diff --git a/src/panel/wifi.hpp b/src/panel/wifi.hpp index 0bd0e37..e2a09b4 100644 --- a/src/panel/wifi.hpp +++ b/src/panel/wifi.hpp @@ -13,8 +13,10 @@ #include #include +#include "../util/rapidjson/document.h" #include +#include namespace dashboard::panel { class wifi : public panel { @@ -29,6 +31,19 @@ namespace dashboard::panel { void update(); void update_texture(); void initTexture(); + + std::string public_ip; + bool wan_status; + std::string speedtest_up; + std::string speedtest_down; + std::string speedtest_ping; + + CURL* api_curl; + std::string json_string; + rapidjson::Document json_doc; + + std::chrono::time_point _last_update; + std::chrono::milliseconds _update_interval; }; } diff --git a/src/panel/wifi_config.hpp b/src/panel/wifi_config.hpp index c028208..4c2afcc 100644 --- a/src/panel/wifi_config.hpp +++ b/src/panel/wifi_config.hpp @@ -16,11 +16,11 @@ namespace dashboard::panel { constexpr size_t WIFI_DEFAULT_TIME_ON_SCREEN = 15000; //How long should we wait between updates? in ms - //Due to the nature of this panel, this value is ignored + //Default 60s constexpr size_t WIFI_UPDATE_INTERVAL = 60000; //Set to true to have your public IP be shown on the wifi page - //Will make a curl request to WIFI_PUBLIC_IP_URL when the frame + //Will make a curl request to WIFI_PUBLIC_IP_URL when the frame //is rendered. This this is a privacy concern disable this option constexpr bool WIFI_SHOW_PUBLIC_IP = true; constexpr char WIFI_PUBLIC_IP_URL[] = "http://ipinfo.io/ip"; @@ -31,4 +31,36 @@ namespace dashboard::panel { constexpr char WIFI_NETWORK_NAME[] = "MyNetwork"; constexpr char WIFI_NETWORK_PASS[] = "MyPassword"; + // Set to true if you have home assistant on your network + // If you do, you can do alot more with it, including showing number of + // clients, network speed, etc + constexpr bool WIFI_HOMEASSISTANT = true; + + //API and URL for home assistant. If using the home assistant panel, this + //should be the same + constexpr char WIFI_HOMEASSISTANT_APIKEY[] = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIxYTNhNDhhYTBlZDM0MjkyOTk5OWZhNGVjZGRjMGUwMCIsImlhdCI6MTY0MjE4NDU0MCwiZXhwIjoxOTU3NTQ0NTQwfQ.Zdy7-ZwX0HuwhmUGeLhF5XCluotsKmpDqmi5o-hQZCc"; + constexpr char WIFI_HOMEASSISTANT_URL[] = "http://192.168.1.104:8123/api/states"; + + //Name of the external IP sensor entry in home assistant + //If your router integrates with it, then you should be able to find it in + //integrations + constexpr char WIFI_HOMEASSISTANT_ROUTER_EXTERNAL_IP[] = "sensor.r7000p_gateway_external_ip"; + + //Name of WAN status sensor in home assistant + constexpr char WIFI_HOMEASSISTANT_ROUTER_WAN_STATUS[] = "sensor.r7000p_gateway_wan_status"; + + //Enable this if you have the ookla speedtest module on home assistant + constexpr bool WIFI_HOMEASSISTANT_SPEEDTEST = true; + + //Name of the entity id string used by the speedtest upload sensor in home + //assistant + constexpr char WIFI_HOMEASSISTANT_SPEEDTEST_UP[] = "sensor.speedtest_upload"; + + //Name of the entity id string used by the speedtest download sensor in home + //assistant + constexpr char WIFI_HOMEASSISTANT_SPEEDTEST_DOWN[] = "sensor.speedtest_download"; + + //Name of the entity id string used by the speedtest ping sensor in home + //assistant + constexpr char WIFI_HOMEASSISTANT_SPEEDTEST_PING[] = "sensor.speedtest_ping"; }