ESP32でGoogleカレンダーの予定を表示

 

みなさんは、今日の予定をスマホのGoogleカレンダーで確認していませんか。
私も、そんなにスケジュールが在るわけではないのですが、ちょっとした予定をGoogleカレンダーに入れています。

ただ、毎回スマホを開いて予定を確認するのは、面倒だなーと思っていました。

そこで、今回はESP32 Wroom32とST7789ディスプレイを使って今日の予定を表示するようなツールを作成しましたので
紹介したいと思います。
Googleカレンダーは日本語表示なのでESP32も日本語表示できるようにします。




【使用材料】



・ESP32WROOM32
・ST7789 1.54インチディスプレイ
・ジャンパーコード
・ブレッドボード

【接続図】


今回紹介する内容は、
1.Googleカレンダーを使用するためのスクリプトの作成方法
2.デプロイURLの作成方法
3.ESP32の各ライブラリのインストール方法
  ・JSON型データを取得するArduinoJsonライブラリ のインストール
  ・日本語表示用のLovyanGFXライブラリのインストール
4.ESP32のプログラム紹介
5.ArduinoIDEでのコンパイルとESP32への書込み方法

 

 

【Googleカレンダーを使用するスクリプト作成】
Googleカレンダーの予定を表示するためには、Google APIを使用する方法とGoogle Apps Scriptを使用する方法がありますが、私のような初心者でも簡単に使えるGoogle Apps Script(GAS)を使用します。

では、まずGASの作成方法を紹介します。

Googleクロームを開いてその中の[Googleアプリ →Google Apps Script ]この画面でスクリプトを作成します。

 

【Google Chrome】


【GAS入力画面】

 

 

【Googleカレンダー用スクリプト】

 

function doGet() {
  // 表示したいカレンダーIDを配列に入れる(自分の、共有A、共有B...)
  const calendarIds = [
    '自分のメールアドレス,            //xxxx@gmail.com
    '共有しているカレンダーID'        //共有があればカレンダーID
  ];

  const now = new Date();
  const start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);
  const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59);
  
  let allEvents = [];

  calendarIds.forEach(id => {
    try {
      const calendar = CalendarApp.getCalendarById(id);
      if (calendar) {
        const events = calendar.getEvents(start, end);
        events.forEach(event => {
          allEvents.push({
            title: event.getTitle(),
            startTime: event.getStartTime(), // ソート用
            start: Utilities.formatDate(event.getStartTime(), "JST", "HH:mm"),
            end: Utilities.formatDate(event.getEndTime(), "JST", "HH:mm")
          });
        });
      }
    } catch (e) {
      console.log('Error access calendar: ' + id);
    }
  });

  // 複数のカレンダーの予定を時間の早い順に並べ替え
  allEvents.sort((a, b) => a.startTime - b.startTime);

  const days = ['日', '月', '火', '水', '木', '金', '土'];
  const result = {
    today: (now.getMonth() + 1) + "月" + now.getDate() + "日(" + days[now.getDay()] + ")",
    events: allEvents.map(e => ({title: e.title, start: e.start, end: e.end}))
  };

  return ContentService.createTextOutput(JSON.stringify(result)).setMimeType(ContentService.MimeType.JSON);
}


ーーーーーーここまでーーーーーーー
データは、JSON型データで送信します。

 


JSON(JavaScript Object Notation)は、JavaScriptのオブジェクト表記を基にした、テキストベースのデータ交換フォーマットです。
キーと値のペア{"key": "value"}で構成されシステム間のデータの受け渡しが可能です。


【デプロイURLの作成】
GASの入力が終わったらデプロイのURLを作成します。

この画面で「新しいデプロイ」をクリックしてデプロイのURLを作成していきます。


【ウエブアプリ画面】

この画面からウェブアプリを選択してウェブアプリのURLを作成します。
画面の遷移に沿って進みます。(詳しくは動画を参照ください)

【新しいデプロイ】

ウェブアプリのURLを作成してコピーしておきます。このURLはESP32側で使用します。(詳細は動画を参照してください)

作成したスクリプトは、Googleドライブに保存されます。

 

 




ESP32の各ライブラリのインストール方法


【Arduinojsonライブラリのインストール】

ArduinoIDEで左側のライブラリメニューからArduiojsonと入力するとライブラリが表示されるのでインストールします。
このライブラリは、GASから送信されたJSON形式のデータをESP32側に取り込むライブラリです。

 

LovyanGFXライブラリ のインストール

LovyanGFXライブラリこちらもインストールします。

こちらのライブラリは、ST7789ディスプレイに日本語を表示させるためのライブラリです。


【ESP32のプログラム】

ESP32のプログラムです。

このプログラムは、Google Apps Scriptから取得した1日分の予定データをST7789に日本語で表示するプログラムです。


/*****************************************
*概要 ESP32 WROOM32とST7789ディスプレイを使用して
*   Googleカレンダーの当日の予定を表示する
*   ディスプレイ表示は日本語表示とする。
*********************************************/
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <LovyanGFX.hpp>

const char* ssid = "XXXXXXX";                  //自宅のWiFiのSSID
const char* password = "XXXXXXXXX";            //自宅のWiFiパスワード
// GASのウェブアプリURL(https://google.com)
const String gas_url = "https://script.google.com/macros/XXXXXXXXXXXX";    //デプロイで作成したウェブアプリのURLをコピー

int cnt = 20; // 表示開始位置(グローバルなどで定義)

//日本語表示のためのLovyanGFXのクラス定義
class LGFX : public lgfx::LGFX_Device
{
    lgfx::Panel_ST7789  _panel_instance;
    lgfx::Bus_SPI       _bus_instance;

public:
    LGFX(void)
    {
        { // SPIバスの設定
            auto cfg = _bus_instance.config();
            cfg.spi_host = VSPI_HOST; // ESP32のVSPI
            cfg.spi_mode = 0;
            cfg.freq_write = 40000000; // 40MHz
            cfg.freq_read  = 16000000;
            cfg.pin_sclk = 18;     // ESP32のSCLKピン
            cfg.pin_mosi = 23;     // ESP32のMOSIピン
            cfg.pin_miso = -1;     // ESP32のMISOピン(使用しない)
            cfg.pin_dc   = 2;         // ESP32のDCピン
            _bus_instance.config(cfg);
            _panel_instance.setBus(&_bus_instance);
        }

        { // パネル設定
            auto cfg = _panel_instance.config();
            cfg.pin_cs           =  5;      // ESP32のCSピン
            cfg.pin_rst          =  4;      // ESP32のRSTピン
            cfg.pin_busy         = -1;
            cfg.panel_width      = 240;    //displayの表示サイズ
            cfg.panel_height     = 240;    //displayの表示サイズ
            cfg.offset_x         = 0;
            cfg.offset_y         = 0;
            cfg.invert           = true;         // ST7789は反転が必要な場合が多い
            _panel_instance.config(cfg);
        }
        setPanel(&_panel_instance);
    }
};
LGFX lcd;


/**********************************
* void setup()
*********************************/
void setup() {
  Serial.begin(115200);

//WiFiの接続
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWiFi Connected");

  //ディスプレイの初期化
  lcd.init();
  lcd.setRotation(1); // 画面の向き
  lcd.fillScreen(TFT_BLACK);
}

/**********************************
* void loop()
*概要:Googleカレンダーの当日データを読込んで
*      ディスプレイに表示する処理(1時間に1回)
*********************************/
void loop() {
  getCalendarData();       //Googleカレンダーデータの読み込み処理
  delay(30000);         // 試験用で30秒に1回データを更新。実際は( 1時間(3600000)で更新するようにする)
}

/**********************************
*void getCalendarData()
*概要:自宅WiFiからGoogleカレンダーにアクセスして、
*          今日の日付とかレーダーの予定を取得する
*********************************/
void getCalendarData() {
  cnt = 20;
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
    http.begin(gas_url);

    int httpCode = http.GET();
    if (httpCode > 0) {
      String payload = http.getString();
      
      DynamicJsonDocument doc(4096); // 容量を少し増やしています
      deserializeJson(doc, payload);

      // 日付の取得と表示
      const char* today = doc["today"];
      Serial.print("【日付】: ");
      Serial.println(today);

      // 予定リストの取得と表示
      JsonArray events = doc["events"].as<JsonArray>();
      Serial.println("--- 今日の予定 ---");

      lcd.fillRect(0, 0, 239, 239, TFT_BLACK);    //画面を消去

      // 日本語フォントの設定(標準搭載フォントを使用)
      lcd.setFont(&fonts::lgfxJapanGothic_20);
      // テキストの表示
      lcd.setTextColor(TFT_WHITE);
      lcd.setCursor(0, 0);
      lcd.print(" 今日の予定 ");
      lcd.println(today);
      Serial.println(events.size());      //データが何個あるかを表示
      if (events.size() > 0 ){
        for (JsonObject obj : events) {
          const char* title = obj["title"];
          const char* start = obj["start"];
          const char* end = obj["end"];
          Serial.printf("[%s - %s] %s\n", start, end, title);
          calendar_data(start, end, title);     //ディスプレイに表示する処理
        }
      } else {                                  //今日の予定がない場合
        lcd.setFont(&fonts::lgfxJapanGothic_16);
        lcd.setTextColor(TFT_WHITE);
        lcd.setCursor(0, 40);
        lcd.print("● 今日の予定はありません!!");
      }
    }
    http.end();
  }
}

/**********************************
*void calendar_data( String starttime,String endtime,String titledata)
*概要:Googleカレンダーの予定データをディスプレイに表示する
*引数:today:今日の字付け starttime:予定開始時間  endtime:予定終了時間  titledata:予定内容
*********************************/
void calendar_data(String starttime,String endtime,String titledata){
  cnt += 20;
  lcd.setFont(&fonts::lgfxJapanGothic_16);
  lcd.setTextColor(TFT_WHITE);
  lcd.setCursor(0, cnt);
  lcd.print(starttime);
  lcd.print(" - ");
  lcd.setCursor(60, cnt);
  lcd.print(endtime);
  cnt += 20;
  lcd.drawString("●", 0, cnt);
  lcd.drawString(titledata, 20, cnt);
}
 

プログラムは以上です。


【ArduinoIDEでのコンパイルとESP32への書込み方法】


ArduinoIDEで、このプログラムをコンパイルすると容量不足と出てしまいます。
そこでArduinoIDEの「ツール → partition Scheme → Huge APP (3MB No OTA/1MB SPIFFS)」を選択します。



これでコンパイルができ、ESP32へ書込み可能になります。

 

【まとめ】

ESP32とST7789ディスプレイを使ってGoogleカレンダーの予定を表示されるためには

まず、Googleカレンダー用のスクリプトを用意する。

次にArduinoIDEでArduinojsonライブラリとST77789ディスプレイに日本語を表示できるLovyanGFXライブラリをインストールする。

ESP32用のスケッチをコンパイルする時は、 partition Scheme をHuge APP (3MB No OTA/1MB SPIFFS)に変更する。

 

今後の課題ですが、このプログラムは、スケジュールが多いと表示があふれて最後まで表示ができない点です。今後はスクロールするなどの工夫が必要ですね。