use http json api for weather
This commit is contained in:
parent
6946031f5c
commit
55cd63dff2
@ -47,8 +47,26 @@ size_t FONT_LOCATIONS_LENGTH = sizeof(FONT_LOCATIONS)/sizeof(FONT_LOCATIONS[0]);
|
||||
// const FONT_SIZE _font_size;
|
||||
//};
|
||||
const FONT_SIZE_STRING CONST_STRINGS[] = {
|
||||
//Weather strings
|
||||
//Overlay strings
|
||||
{ "Weather", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Wireless", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
|
||||
//Weather strings
|
||||
{ "Clear Skies", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Slightly cloudy", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Moderately cloudy", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Very cloudy", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Very humid", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Light rain", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Rain", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Overcast with showers", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Moderate showers", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Light snow", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Moderate snow", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Rain and snow", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Currently,", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Tommorow,", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
{ "Day after,", { "Roboto_Mono/RobotoMono-Medium.ttf", 50 } },
|
||||
|
||||
};
|
||||
size_t CONST_STRINGS_LENGTH = sizeof(CONST_STRINGS)/sizeof(CONST_STRINGS[0]);
|
||||
|
@ -19,8 +19,32 @@ weather::weather(){
|
||||
_update_interval = std::chrono::milliseconds{WEATHER_UPDATE_INTERVAL};
|
||||
_texture = nullptr;
|
||||
_title = WEATHER_TITLE;
|
||||
//let set to default, will make it so it updates the texture ASAP
|
||||
//_last_update;
|
||||
api_curl = nullptr;
|
||||
|
||||
weather_string["clearday"] = WEATHER_CLEAR_DAY;
|
||||
weather_string["clearnight"] = WEATHER_CLEAR_NIGHT;
|
||||
weather_string["pcloudyday"] = WEATHER_PCLOUDY_DAY;
|
||||
weather_string["pcloudynight"] = WEATHER_PCLOUDY_NIGHT;
|
||||
weather_string["mcloudyday"] = WEATHER_MCLOUDY_DAY;
|
||||
weather_string["mcloudynight"] = WEATHER_MCLOUDY_NIGHT;
|
||||
weather_string["cloudyday"] = WEATHER_CLOUDY_DAY;
|
||||
weather_string["cloudynight"] = WEATHER_CLOUDY_NIGHT;
|
||||
weather_string["humidday"] = WEATHER_HUMID_DAY;
|
||||
weather_string["humidnight"] = WEATHER_HUMID_NIGHT;
|
||||
weather_string["lightrainday"] = WEATHER_LRAIN_DAY;
|
||||
weather_string["lightrainnight"] = WEATHER_LRAIN_NIGHT;
|
||||
weather_string["rainday"] = WEATHER_RAIN_DAY;
|
||||
weather_string["rainnight"] = WEATHER_RAIN_NIGHT;
|
||||
weather_string["oshowerday"] = WEATHER_OSHOWER_DAY;
|
||||
weather_string["oshowernight"] = WEATHER_OSHOWER_NIGHT;
|
||||
weather_string["ishowerday"] = WEATHER_ISHOWER_DAY;
|
||||
weather_string["ishowernight"] = WEATHER_ISHOWER_NIGHT;
|
||||
weather_string["lightsnowday"] = WEATHER_LSNOW_DAY;
|
||||
weather_string["lightsnownight"] = WEATHER_LSNOW_NIGHT;
|
||||
weather_string["snowday"] = WEATHER_SNOW_DAY;
|
||||
weather_string["snownight"] = WEATHER_SNOW_NIGHT;
|
||||
weather_string["rainsnowday"] = WEATHER_RAINSNOW_DAY;
|
||||
weather_string["rainsnownight"] = WEATHER_RAINSNOW_NIGHT;
|
||||
}
|
||||
|
||||
weather::~weather(){
|
||||
@ -65,19 +89,49 @@ void weather::update() {
|
||||
_last_update = std::chrono::high_resolution_clock::now();
|
||||
|
||||
//fetch updates
|
||||
//do curl setup and cleanup
|
||||
//We cleanup after each operation to save on memory.
|
||||
//This is because by default we only fetch every hour
|
||||
if(api_curl == nullptr){
|
||||
std::cerr << "GRABING WEATHER DATA\n";
|
||||
api_curl = curl_easy_init();
|
||||
curl_easy_setopt(api_curl, CURLOPT_URL, WEATHER_URL_SOURCE);
|
||||
curl_easy_setopt(api_curl, CURLOPT_WRITEFUNCTION,
|
||||
dashboard::panel::weather::curl_callback);
|
||||
curl_easy_setopt(api_curl, CURLOPT_WRITEDATA, &json_string);
|
||||
CURLcode res = curl_easy_perform(api_curl);
|
||||
curl_easy_cleanup(api_curl);
|
||||
api_curl = nullptr;
|
||||
}
|
||||
|
||||
//prase the response
|
||||
json_doc.Parse(json_string.c_str());
|
||||
|
||||
//update internal state
|
||||
current_desc = "CURRENT DESC PLACEHOLDER";
|
||||
tommorow_desc = "TOMMOROW DESC PLACEHOLDER";
|
||||
const rapidjson::Value& curr_entry = json_doc["dataseries"];
|
||||
//get all entries
|
||||
weather_today = &weather_string.at(curr_entry[0]["weather"].GetString());
|
||||
weather_tommorow = &weather_string.at(curr_entry[7]["weather"].GetString());
|
||||
weather_day_after = &weather_string.at(curr_entry[15]["weather"].GetString());
|
||||
temp_today = curr_entry[0]["temp2m"].GetInt();
|
||||
temp_tommorow = curr_entry[7]["temp2m"].GetInt();
|
||||
temp_day_after = curr_entry[15]["temp2m"].GetInt();
|
||||
|
||||
|
||||
if(!WEATHER_METRIC){
|
||||
temp_today = (temp_today * 1.8) + 32;
|
||||
temp_tommorow = (temp_tommorow * 1.8) + 32;
|
||||
temp_day_after = (temp_day_after * 1.8) + 32;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Update the texture that is being
|
||||
// displayed, based on data in
|
||||
// _rss
|
||||
// displayed, based on data in the json feed
|
||||
void weather::update_texture(){
|
||||
std::cerr << "WEATHER::UPDATE_TEXTURE\n";
|
||||
SDL_Rect tgt;
|
||||
std::string temp;
|
||||
|
||||
SDL_SetRenderTarget(board::getRenderer(), _texture);
|
||||
SDL_RenderClear(board::getRenderer());
|
||||
@ -87,24 +141,100 @@ void weather::update_texture(){
|
||||
board::getImage("sky.png"), NULL, NULL);
|
||||
|
||||
//current weather
|
||||
tgt.y = 50;
|
||||
TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }),
|
||||
current_desc.c_str(),
|
||||
"Currently,",
|
||||
&tgt.w, &tgt.h);
|
||||
tgt.x = SCREEN_WIDTH / 2 - (tgt.w / 2);
|
||||
tgt.y = SCREEN_HEIGHT / 2 - (tgt.h / 2);
|
||||
tgt.x = (SCREEN_WIDTH / 2) - (tgt.w / 2);
|
||||
SDL_RenderCopy(board::getRenderer(),
|
||||
board::getString(current_desc.c_str(),
|
||||
board::getString("Currently,",
|
||||
{ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt);
|
||||
tgt.y += tgt.h;
|
||||
TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }),
|
||||
weather_today->first.c_str(),
|
||||
&tgt.w, &tgt.h);
|
||||
tgt.x = (SCREEN_WIDTH / 2) - (tgt.w / 2);
|
||||
SDL_RenderCopy(board::getRenderer(),
|
||||
board::getString(weather_today->first.c_str(),
|
||||
{ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt);
|
||||
tgt.y += tgt.h;
|
||||
temp = std::to_string(temp_today);
|
||||
if(WEATHER_METRIC)
|
||||
temp += "*C";
|
||||
else
|
||||
temp += "*F";
|
||||
TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }),
|
||||
temp.c_str(),
|
||||
&tgt.w, &tgt.h);
|
||||
tgt.x = (SCREEN_WIDTH / 2) - (tgt.w / 2);
|
||||
SDL_RenderCopy(board::getRenderer(),
|
||||
board::getString(temp.c_str(),
|
||||
{ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt);
|
||||
|
||||
|
||||
//tommorow's weather
|
||||
TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }),
|
||||
tommorow_desc.c_str(),
|
||||
"Tommorow,",
|
||||
&tgt.w, &tgt.h);
|
||||
tgt.x = SCREEN_WIDTH / 2 - (tgt.w / 2);
|
||||
tgt.y = SCREEN_HEIGHT / 2 - (tgt.h / 2) + 50;
|
||||
tgt.y = (3*SCREEN_HEIGHT / 4) - (tgt.h / 2);
|
||||
tgt.x = (SCREEN_WIDTH / 6) - (tgt.w / 2);
|
||||
SDL_RenderCopy(board::getRenderer(),
|
||||
board::getString(tommorow_desc.c_str(),
|
||||
board::getString("Tommorow,",
|
||||
{ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt);
|
||||
tgt.y += tgt.h;
|
||||
TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }),
|
||||
weather_tommorow->first.c_str(),
|
||||
&tgt.w, &tgt.h);
|
||||
tgt.x = (SCREEN_WIDTH / 6) - (tgt.w / 2);
|
||||
SDL_RenderCopy(board::getRenderer(),
|
||||
board::getString(weather_tommorow->first.c_str(),
|
||||
{ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt);
|
||||
tgt.y += tgt.h;
|
||||
temp = std::to_string(temp_tommorow);
|
||||
if(WEATHER_METRIC)
|
||||
temp += "*C";
|
||||
else
|
||||
temp += "*F";
|
||||
TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }),
|
||||
temp.c_str(),
|
||||
&tgt.w, &tgt.h);
|
||||
tgt.x = (SCREEN_WIDTH / 6) - (tgt.w / 2);
|
||||
SDL_RenderCopy(board::getRenderer(),
|
||||
board::getString(temp.c_str(),
|
||||
{ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt);
|
||||
|
||||
//day after's weather
|
||||
TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }),
|
||||
"Day after,",
|
||||
&tgt.w, &tgt.h);
|
||||
tgt.y = (3*SCREEN_HEIGHT / 4) - (tgt.h / 2);
|
||||
tgt.x = (5*SCREEN_WIDTH / 6) - (tgt.w / 2);
|
||||
SDL_RenderCopy(board::getRenderer(),
|
||||
board::getString("Day after,",
|
||||
{ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt);
|
||||
tgt.y += tgt.h;
|
||||
TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }),
|
||||
weather_day_after->first.c_str(),
|
||||
&tgt.w, &tgt.h);
|
||||
tgt.x = (5*SCREEN_WIDTH / 6) - (tgt.w / 2);
|
||||
SDL_RenderCopy(board::getRenderer(),
|
||||
board::getString(weather_day_after->first.c_str(),
|
||||
{ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt);
|
||||
tgt.y += tgt.h;
|
||||
temp = std::to_string(temp_day_after);
|
||||
if(WEATHER_METRIC)
|
||||
temp += "*C";
|
||||
else
|
||||
temp += "*F";
|
||||
TTF_SizeText(board::getFont({ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }),
|
||||
temp.c_str(),
|
||||
&tgt.w, &tgt.h);
|
||||
tgt.x = (5*SCREEN_WIDTH / 6) - (tgt.w / 2);
|
||||
SDL_RenderCopy(board::getRenderer(),
|
||||
board::getString(temp.c_str(),
|
||||
{ "Roboto_Mono/RobotoMono-Medium.ttf", 50 }), NULL, &tgt);
|
||||
|
||||
|
||||
|
||||
SDL_SetRenderTarget(board::getRenderer(), NULL);
|
||||
}
|
||||
@ -123,3 +253,11 @@ void weather::initTexture(){
|
||||
SDL_SetTextureBlendMode(_texture, SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Curl callback function
|
||||
size_t dashboard::panel::weather::curl_callback(void* contents, size_t size,
|
||||
size_t nmemb, void* userp){
|
||||
((std::string*)userp)->append((char*)contents, size * nmemb);
|
||||
return size * nmemb;
|
||||
}
|
||||
|
@ -14,8 +14,13 @@
|
||||
#include <SDL2/SDL_image.h>
|
||||
#include <SDL2/SDL_ttf.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include "../util/rapidjson/document.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
namespace dashboard::panel {
|
||||
class weather : public panel {
|
||||
@ -23,16 +28,30 @@ namespace dashboard::panel {
|
||||
weather();
|
||||
~weather();
|
||||
|
||||
void draw();
|
||||
static size_t curl_callback(void*, size_t, size_t, void*);
|
||||
|
||||
void draw();
|
||||
private:
|
||||
void update();
|
||||
void update_texture();
|
||||
void initTexture();
|
||||
|
||||
std::string current_desc;
|
||||
std::string tommorow_desc;
|
||||
static constexpr bool TODAY = true;
|
||||
static constexpr bool TOMMOROW = false;
|
||||
|
||||
std::unordered_map<std::string,
|
||||
std::pair<std::string, std::string>> weather_string;
|
||||
|
||||
std::pair<std::string, std::string>* weather_today;
|
||||
std::pair<std::string, std::string>* weather_tommorow;
|
||||
std::pair<std::string, std::string>* weather_day_after;
|
||||
short temp_today;
|
||||
short temp_tommorow;
|
||||
short temp_day_after;
|
||||
|
||||
CURL* api_curl;
|
||||
std::string json_string;
|
||||
rapidjson::Document json_doc;
|
||||
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> _last_update;
|
||||
std::chrono::milliseconds _update_interval;
|
||||
|
@ -6,13 +6,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <string>
|
||||
|
||||
namespace dashboard::panel {
|
||||
//This will be displayed at the top left on the status bar. Set to a blank
|
||||
//string to not show anything
|
||||
constexpr char WEATHER_TITLE[] = "Weather";
|
||||
|
||||
//New York RSS feed
|
||||
static const char* WEATHER_URL_SOURCE = "http://rss.accuweather.com/rss/liveweather_rss.asp?locCode=10007";
|
||||
static const char* WEATHER_URL_SOURCE = "https://www.7timer.info/bin/civil.php?lon=41.13&lat=-81.48&unit=british&output=json&tzshift=0";
|
||||
|
||||
//Default time the slide is shown on screen, in ms
|
||||
//Default 5s
|
||||
@ -22,4 +25,73 @@ namespace dashboard::panel {
|
||||
//Default 1 hour
|
||||
constexpr size_t WEATHER_UPDATE_INTERVAL = 3600000;
|
||||
|
||||
//Display temperatures in metric?
|
||||
//Default false
|
||||
constexpr bool WEATHER_METRIC = false;
|
||||
|
||||
//The following are all of the strings that will be shown for each state of
|
||||
//weather, along with the image that will be shown
|
||||
//The struct is of form {WEATHER_STRING, WEATHER_IMAGE}
|
||||
//with weather string being the string shown on screen, and weather image
|
||||
//being the name of the preloaded image file to be shown. It is best that
|
||||
//these images be square.
|
||||
const std::pair<std::string, std::string> WEATHER_CLEAR_DAY =
|
||||
{"Clear skies", "clearday.png"};
|
||||
const std::pair<std::string, std::string> WEATHER_CLEAR_NIGHT =
|
||||
{"Clear skies", "clearnight.png"};
|
||||
|
||||
const std::pair<std::string, std::string> WEATHER_PCLOUDY_DAY =
|
||||
{"Slightly cloudy", "pcloudyday.png"};
|
||||
const std::pair<std::string, std::string> WEATHER_PCLOUDY_NIGHT =
|
||||
{"Slightly cloudy", "pcloudynight.png"};
|
||||
|
||||
const std::pair<std::string, std::string> WEATHER_MCLOUDY_DAY =
|
||||
{"Moderately cloudy", "mcloudyday.png"};
|
||||
const std::pair<std::string, std::string> WEATHER_MCLOUDY_NIGHT =
|
||||
{"Moderately cloudy", "mcloudynight.png"};
|
||||
|
||||
const std::pair<std::string, std::string> WEATHER_CLOUDY_DAY =
|
||||
{"Very cloudy", "cloudyday.png"};
|
||||
const std::pair<std::string, std::string> WEATHER_CLOUDY_NIGHT =
|
||||
{"Very cloudy", "cloudynight.png"};
|
||||
|
||||
const std::pair<std::string, std::string> WEATHER_HUMID_DAY =
|
||||
{"Very humid", "humidday.png"};
|
||||
const std::pair<std::string, std::string> WEATHER_HUMID_NIGHT =
|
||||
{"Very humid", "humidnight.png"};
|
||||
|
||||
const std::pair<std::string, std::string> WEATHER_LRAIN_DAY =
|
||||
{"Light rain", "lrainday.png"};
|
||||
const std::pair<std::string, std::string> WEATHER_LRAIN_NIGHT =
|
||||
{"Light rain", "lrainnight.png"};
|
||||
|
||||
const std::pair<std::string, std::string> WEATHER_RAIN_DAY =
|
||||
{"Rain", "rainday.png"};
|
||||
const std::pair<std::string, std::string> WEATHER_RAIN_NIGHT =
|
||||
{"Rain", "rainnight.png"};
|
||||
|
||||
const std::pair<std::string, std::string> WEATHER_OSHOWER_DAY =
|
||||
{"Overcast with showers", "oshowerday.png"};
|
||||
const std::pair<std::string, std::string> WEATHER_OSHOWER_NIGHT =
|
||||
{"Overcast with showers", "oshowernight.png"};
|
||||
|
||||
const std::pair<std::string, std::string> WEATHER_ISHOWER_DAY =
|
||||
{"Moderate showers", "ishowerday.png"};
|
||||
const std::pair<std::string, std::string> WEATHER_ISHOWER_NIGHT =
|
||||
{"Moderate showers", "ishowernight.png"};
|
||||
|
||||
const std::pair<std::string, std::string> WEATHER_LSNOW_DAY =
|
||||
{"Light snow", "lsnowday.png"};
|
||||
const std::pair<std::string, std::string> WEATHER_LSNOW_NIGHT =
|
||||
{"Light snow", "lsnownight.png"};
|
||||
|
||||
const std::pair<std::string, std::string> WEATHER_SNOW_DAY =
|
||||
{"Moderate snow", "snowday.png"};
|
||||
const std::pair<std::string, std::string> WEATHER_SNOW_NIGHT =
|
||||
{"Moderate snow", "snownight.png"};
|
||||
|
||||
const std::pair<std::string, std::string> WEATHER_RAINSNOW_DAY =
|
||||
{"Rain and snow", "rainsnowday.png"};
|
||||
const std::pair<std::string, std::string> WEATHER_RAINSNOW_NIGHT =
|
||||
{"Rain and snow", "rainsnownight.png"};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user