19
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

M5Paperでウェブサイトを表示する(Chromeキャプチャ & ImageMagickで変換)あと、日めくり作成

Last updated at Posted at 2021-02-10

完成例(こういったのが作れます)
EuFhrGpUcAA9PKx.jfif

M5Stack社のM5PaperはWi-Fiで画像取得して表示するまで完結して対応できる点が素晴らしいです!
しかも定期取得の合間にはシャットダウンして、電源消費がほぼゼロで長持ち

・・・という事はLinuxホスト側でウェブサイトを画像キャプチャしてhttpで提供すれば・・・

  • デザインの自由度が上がる(ウェブデザインが得意な人向け)日めくりとか自由自在
  • ウェブサイトを飾れる(スマホPC触れない人も見れる)

のでは?と思いやってみました!

ホスト(Linux)側でする事

google-chromeImageMagickhttpd は各パッケージマネージャ(yum,apt等)でインストール(省略します)

Chromeヘッドレスモード(コマンドラインモード)でウェブサイトをキャプチャ

google-chrome --headless --screenshot https://example.com/ --window-size=960,540

screenshot.png というファイルができるので、ImageMagickでM5Paperで読み込めるようにコンバート

convert -rotate 90 \
        -quality 88 \
        -density 120 \
        -units PixelsPerInch \
        -sampling-factor 4:2:0 \
        -colorspace sRGB \
        -strip \
        -define colorspace:auto-grayscale=false \
        -type truecolor \
        screenshot.png screenshot.jpg

試行錯誤したので要らないオプションがついていますが、これで大丈夫なはず。

  • rotate 画像回転(90度)
  • quality クォリティ(89%以下)
  • density units DPI指定(120dpi)
  • sampling-factor サブサンプリング(4:2:0)
  • colorspace カラースペース(sRGB)
  • strip その他拡張情報は邪魔なのでトル)
  • define type 自動で付与されるグレースケールは互換性ないのでOFF
  • 形式変換(png=>jpg)

(※ ImageMagickのバージョンによってはカラースペースのオプションが逆転(RGB<=>sRGB)するバグがあるので注意)

出力したjpg画像をhttpdのドキュメントパスに配置すれば完成。(httpdサービス起動からファイヤーウォールとかポート開放してM5Paperから見えるようにしてください)

上記のコマンドを cron 等に登録して、定時実行しておくと良いでしょう。

M5Paper側でする事

M5Paper側に書き込むプログラムでWi-Fiで画像取得して表示するサンプルがこちらに。
SSIDとパスワード・画像のURLは所定の物を指定してください。

定期的に取得するなら M5.shutdown([終了後、再起動する秒数]) コマンドを最後に書くだけです。
描画前に終了してしまうので、shutdown前に2秒ぐらいのディレイ delay(2000); を入れておきましょう。

(追記) 1か月運用して分かった事

  • shutdown で次回起動予定(〇秒後)をセットするのですが、MAXで3時間(10800)ぐらいまでの様です。
  • 3時間おきの1日8回更新で1か月運用した結果、充電無しで電池残量は13%減。単純計算で4,5カ月いける?

WEBページ側のデザイン

この後のソースはプロトタイプなので、見栄えの良いものではないですが...
参考にしたいと要望頂きましたので、ざっくり上げさせていただきます。
購入した有料ライセンスフォント(画像化済)も含まれますので、ソースコピー等の参考程度にしていただき、画像のコピー・二次転用はご遠慮ください。

単純に position: absolute; を使って、絶対座標指定でやってます。
「書き方が汚い!」とかは十重承知でございます・・・

APIロジック

天気やTwitterトレンド情報等のAPI接続は
PHPで取得して、中間ファイルを生成しています。
取得タイミングは即時ではなく、CRONで定時に実行するよう設定。ロリポップ等のレンタルサーバーでも簡単に使えます。

天気予報

Dark Sky さんを利用しています。リクエスト頻度の閾値を超えなければ無料というフリーミアムなAPIです。(まあ、基本はどこでもそんな感じですね・・)
https://api.rakuten.net/darkskyapis/api/dark-sky

Rakten Rapid APIさんが言語に合わせたコードを出力してくれるのでほぼやる事ないです。
書いたものを吐き出しているだけですね・・

<?php

$curl = curl_init();

curl_setopt_array($curl, [
	CURLOPT_URL => "https://dark-sky.p.rapidapi.com/【緯度】,【経度】?lang=en&units=auto",
	CURLOPT_RETURNTRANSFER => true,
	CURLOPT_FOLLOWLOCATION => true,
	CURLOPT_ENCODING => "",
	CURLOPT_MAXREDIRS => 10,
	CURLOPT_TIMEOUT => 30,
	CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
	CURLOPT_CUSTOMREQUEST => "GET",
	CURLOPT_HTTPHEADER => [
		"x-rapidapi-host: dark-sky.p.rapidapi.com",
		"x-rapidapi-key: 【APIキー】"
	],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

$fp = fopen('【出力jsonファイルのパス】', 'w');
fwrite($fp, $response);
fclose($fp);


利用したAPIは 「Forcast」で、緯度経度を指定したら、その地点の1時間おき1日間、1日おき1週間の天気予報情報を取得できます。
こちらの例は、1日朝7時に1回実行し

  • 0時間後(7時)
  • 5時間後(12時)
  • 11時間後(18時)

の気温(temperature)、降水確率(precipProbability)を取得して表示します。
降水確率はレシオなのでパーセントに変換(* 100)します。
気温は自動で摂氏になってたはず。(忘れました。設定あったらごめんなさい・・)

天気マークは currentlyのiconを取得しています。
clear-day / clear-night / partly-cloudy-day / partly-cloudy-night / cloudy / rain / sleet / snow / wind / fog
の文字列で来るので、それに合わせてパターン画像を用意して表示しています。

Twitter

Rakuten Rapid APIが便利すぎて TwitterのAPIもあるのですが、トレンドは取れない様で
仕方なく本件をAPIを利用しています。
(後で気づいたのですが、各SNS総なめのトレンドを取得できるAPIならあるのかも・・)
・・・
(コホン・)気を取り直して
Twitter APIの接続にはこちらのお世話になりました! 
https://syncer.jp/Web/API/Twitter/REST_API/
APIトークン類の取得方法等、手取り足取り教えて頂きました。

何を使うにも基本のPHPはこちらです。(このPHPをインクルードして使います。)

twitter.php(設定 & 共通関数)
<?php

/**
 * twitter
 *
 * @param string $endpoint (スラッシュ以降のパス)
 * @param array $params_a (パラメータ(配列)
 * @return string (応答json)
 */
function twitter($endpoint, $params_a) {

    /**********************
     設定
    **********************/
    $api_key = "【API Key】";
    $api_secret = "【API Secret】";
    $access_token = "【アクセストークン】";
    $access_token_secret = "【アクセストークンシークレット】";

    //エンドポイント
    $request_method = "GET";	//メソッド
    $request_url = "https://api.twitter.com/1.1/".$endpoint.".json";	//URL

    /**********************
     署名作成
    **********************/
    //OAuth1.0認証用のパラメータを連想配列で用意
    $params_b = array(
    "oauth_consumer_key" => $api_key,
    "oauth_token" => $access_token,
    "oauth_nonce" => microtime(),
    "oauth_signature_method" => "HMAC-SHA1",
    "oauth_timestamp" => time(),
    "oauth_version" => "1.0"
    );

    //キーを作成する
    $signature_key = rawurlencode($api_secret)."&".rawurlencode($access_token_secret);

    //オプション・パラメータ[$params_a]と認証用パラメータ[$params_b]を署名作成のため、合体させた[$params_c]を用意
    $params_c = array_merge($params_a,$params_b);

    //[$params_c]をアルファベット順に並び替える
    ksort($params_c);

    //配列[$params_c]を[キー=値&キー=値...]の文字列に変換
    $signature_params = str_replace(array("+","%7E"),array("%20","~"),http_build_query($params_c,"","&"));

    //リクエストメソッド、リクエストURL、パラメータを、URLエンコードしてから[&]で繋ぎ、データを作成する
    $signature_data = rawurlencode($request_method)."&".rawurlencode($request_url)."&".rawurlencode($signature_params);

    //キー[$signature_key]とデータ[$signature_data]をHMAC-SHA1方式のハッシュ値に変換し、base64エンコードして、署名を作成する
    $signature = base64_encode(hash_hmac("sha1",$signature_data,$signature_key,TRUE));

    /**********************
     GETリクエスト
    **********************/
    //[$params_c]に、作成した署名を加える
    $params_c["oauth_signature"] = $signature;

    //[$params_c]を[キー=値,キー=値,...]の文字列に変換する(ヘッダー用)
    $header_params = http_build_query($params_c,"",",");

    //[$params_a]を、リクエストURLの末尾に付けるクエリーに変換して付ける(GETの場合)
    //[例] ?screen_name=arayutw
    if($params_a && $request_method=="GET"){
    $request_url .= "?".http_build_query($params_a,"","&");
    }

    //TwitterにGETリクエストを送る [$json]にTwitterから返ってきたJSONが格納される
    $json = file_get_contents(
    $request_url,	//[第1引数:リクエストURL($request_url)]
    false,		//[第2引数:リクエストURLは相対パスか?(違うのでfalse)]
    stream_context_create(	//[第3引数:stream_context_create()でメソッドとヘッダーを指定]
        array(
            "http" => array(
                "method" => $request_method, //リクエストメソッド
                "header" => array(          //カスタムヘッダー
                "Authorization: OAuth ".$header_params,
                ),
            )
        )
    )
    );

    return $json;
}

そして、それを呼び出してトレンドを取得してファイル出力するだけのPHP

trends.php
<?php
include_once 'twitter.php';
$out = twitter('trends/place', array('id'=>'1110809'));
$fp = fopen('【出力jsonファイルのパス】', 'w');
fwrite($fp, $out);
fclose($fp);

ざっくり紹介しましたが、そんな感じですね。

19
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?