#include "SSD1306Wire.h"
#include "OLEDDisplayUi.h"
#include
#include
#include
#include
Ticker tickerWeatherUpdate;
SSD1306Wire display(0x3c, 21, 22);
OLEDDisplayUi ui( &display );
const char* ssid = "XXXXXXXXXXXXXXXXX";
const char* password = "************";
//NTP関連
struct tm timeInfo;
char date[20],hour_minute_sec[20];
int now_hour;
//天気関連
String now_weather,now_temp,tom_weather,tom_temp;
const String endpoint = "http://api.openweathermap.org/data/2.5/weather?q=takamatsu,jp&APPID=";
const String endpoint_forecast = "http://api.openweathermap.org/data/2.5/forecast?q=takamatsu,jp&APPID=";
const String key = "********************************";
//12時間後の天気を取得する関数
void get_tomorrow_weather(){
HTTPClient http;
http.begin(endpoint_forecast + key); //URLを指定
int httpCode = http.GET(); //GETリクエストを送信
if (httpCode > 0) { //返答がある場合
String payload = http.getString(); //返答(JSON形式)を取得
//jsonオブジェクトの作成
/* DynamicJsonBuffer jsonBuffer;
String json = payload;
JsonObject& weatherdata = jsonBuffer.parseObject(json);
//パースが成功したかどうかを確認
if(!weatherdata.success()){
Serial.println("parseObject() failed");
}
*/
String json = payload;
// Serial.println(json);
const size_t capacity = JSON_OBJECT_SIZE(13) + 20000;
DynamicJsonDocument doc(capacity);
// Parse JSON object
DeserializationError error = deserializeJson(doc, json);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
//抜き出すデータの番号
int data_number = now_hour/3 + 4;
//12時間後のデータを抜き出し
const char* weather = doc["list"][data_number]["weather"][0]["main"].as();
const double temp = doc["list"][data_number]["main"]["temp"].as();
//表示用変数に各要素をセット
tom_weather = weather;
tom_temp = String(temp-273.15);
}
else {
Serial.println("Error on HTTP request");
}
http.end();
}
//今日の天気を取得する関数
void get_today_weather(){
HTTPClient http;
http.begin(endpoint + key); //URLを指定
int httpCode = http.GET(); //GETリクエストを送信
if (httpCode > 0) { //返答がある場合
String payload = http.getString(); //返答(JSON形式)を取得
Serial.println(httpCode);
Serial.println(payload);
//jsonオブジェクトの作成
/* DynamicJsonBuffer jsonBuffer;
String json = payload;
JsonObject& weatherdata = jsonBuffer.parseObject(json);
//パースが成功したかどうかを確認
if(!weatherdata.success()){
Serial.println("parseObject() failed");
}
*/
String json = payload;
const size_t capacity = JSON_OBJECT_SIZE(13) + 1000;
DynamicJsonDocument doc(capacity);
// Serial.println(json);
// Parse JSON object
DeserializationError error = deserializeJson(doc, json);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
//各データを抜き出し
const char* weather = doc["weather"][0]["main"].as();
const double temp = doc["main"]["temp"].as();
//表示用変数に各要素をセット
now_weather = weather;
now_temp = String(temp-273.15);
}
else {
Serial.println("Error on HTTP request");
}
http.end(); //Free the resources
}
//ticker用の天気データまとめ関数
void get_weather_data(){
get_today_weather();
get_tomorrow_weather();
}
void get_time(){
getLocalTime(&timeInfo);//tmオブジェクトのtimeInfoに現在時刻を入れ込む
sprintf(date, " %04d/%02d/%02d ",timeInfo.tm_year + 1900, timeInfo.tm_mon + 1, timeInfo.tm_mday);//日付に変換
sprintf(hour_minute_sec, "%02d:%02d:%02d",timeInfo.tm_hour, timeInfo.tm_min, timeInfo.tm_sec);//時間に変換
now_hour = timeInfo.tm_hour;
}
void ClockOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_10);
display->drawString(25, 0, String(date) + String(hour_minute_sec));
}
void drawFrame1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
//今日の天気を表示
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_16);
display->drawString(10 + x,10 + y,"weather: " + String(now_weather));
display->setFont(ArialMT_Plain_24);
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->drawString(64 + x,25 + y,String(now_temp) + "°C");
}
void drawFrame2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
//明日の天気を表示
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(ArialMT_Plain_10);
display->drawString(0 + x,10 + y,"12 hours after");
display->setFont(ArialMT_Plain_16);
display->drawString(0+x,22+y,String(tom_weather));
display->setFont(ArialMT_Plain_24);
display->drawString(50+x,22+y,String(tom_temp) + "°C");
}
//SSD1306関連
FrameCallback frames[] = { drawFrame1, drawFrame2};
int frameCount = 2;
OverlayCallback overlays[] = { ClockOverlay };
int overlaysCount = 1;
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();
//Wi-Fi関連
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
configTime(9 * 3600L, 0, "ntp.nict.jp", "time.google.com", "ntp.jst.mfeed.ad.jp");//NTPの設定
//Tickerの設定
tickerWeatherUpdate.attach(60, get_weather_data);
get_weather_data();
//ssd1306のui設定
ui.setTargetFPS(30);
// You can change this to
// TOP, LEFT, BOTTOM, RIGHT
ui.setIndicatorPosition(BOTTOM);
// Defines where the first frame is located in the bar.
ui.setIndicatorDirection(LEFT_RIGHT);
// You can change the transition that is used
// SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN
ui.setFrameAnimation(SLIDE_LEFT);
// Add frames
ui.setFrames(frames, frameCount);
// Add overlays
ui.setOverlays(overlays, overlaysCount);
// Initialising the UI will init the display too.
ui.init();
}
void loop() {
int remainingTimeBudget = ui.update();
if (remainingTimeBudget > 0) {
delay(remainingTimeBudget);
get_time();
}
}