LoginSignup
16
17

More than 5 years have passed since last update.

ESP8266 (ESP-WROOM-02) でバスの到着を知る「バスどこメーター」を作る(前編)

Last updated at Posted at 2016-02-11

概要

ESP8266 (ESP-WROOM-02) でバスの到着を知ることができる装置を作る

はじめに

以前、Qiitaで「cloudBitとIFTTTで「おとうさんいまどこメーター」を作る」という記事を読んだ。素晴らしい着想だ。

当時は全く、手も足も出なかったが、今ならできる気がする。そう、WROOM02 なら。

アイデアをそのまま繰り返しても面白くないので、自分なりに考えた。

そうだ、朝の慌ただしい時間帯に、最寄りのバス停に、あとどれ位でバスが来るかをサクッと確認できるメーターを作ろう!
スマフォから「東急バスナビ」で確認できるが、いちいち見てられないので。

「東急バスナビ」は、東急バスが提供する、このようなサービスです。→ 東急バスナビ

機械的なサービスの利用について事前に問合せたのですが、そういったサービスは無いそうです。

担当部署へこの件に関しまして確認いたしましたところ、一般的なブラウザによる閲覧を想定しており、
それ以外の用途による質問についてはお答えしかねます。との回答がございました。

今回は営利目的ではない個人的な利用なので、ちょっとグレーですが、使わせてもらうことにします。(自己責任で)
もし問題あれば連絡ください。

アーキテクチャ

全体のアーキテクチャは以下のようになります。
ここは得意の AWS で、サーバレス な構成にします。

スクリーンショット 2016-02-11 20.40.07.png

サーバサイド

AWS APIGateway + Lambda をつかって、サーバサイドの処理を実装します。

  • バス会社からの「バスなび」情報(HTML)をパースして、必要な部分だけをjsonにして返すフィルタの役割になります。
  • Lambda は、リクエストがあるときだけ起動する、サーバレスなアーキテクチャ。

  • APIGateway と Lambda については、「AWS Lambda を使って Slack ボット (命名: Lambot [ランボー]) を低予算で作ろうじゃないか」を参照して下さい。

  • WROOM02 からの https通信では TLSv1.1 しかできませんが、APIGateway が TLSv1.2 を強要するため、しかたなく CloudFront を被せます。
    しかし、WROOM02 で SSL (WiFiClientSecure) がうまく動かなかったため、結局、CloudFront で HTTP <-> HTTPS の変換をして、WROOM02 は HTTP で通信するようにします。

  • npm ライブラリ ( request、cheerio ) を使用している。Lambda に登録するには node_modules にインストール後、全体を zip でまとめてアップロードする必要があります。

Lambda

Lambda 関数は以下。

var request = require("request");
var cheerio = require("cheerio");

exports.handler = function (event, context) {

  var options = {
    uri: 'http://tokyu.bus-location.jp/blsys/navis',
    form: {
      VID: "rsc",
      EID: "rd",
      SCT: 2,
      DSMK: event.DSMK,
      ASMK: event.ASMK
    }
  };

  function trim(node) {
    return node.text().replace(/[\r\n\t]/g, "");
  }

  request.post(options,
    function (error, response, body) {
      if (event.test) {
        body = require('fs').readFileSync('check.html', 'utf-8');
      }
      var $ = cheerio.load(body);
      var pos = [];
      $(".approach tbody tr").each(function () {
        var tr = $(this);
        if (tr.hasClass("stopline")) {
          pos.push([]);
        }
        if (tr.hasClass("busline") && pos.length) {
          tr.children(".colmsg").each(function () {
            $(this).children("div").each(function () {
              var waittm = $(this).children(".waittm").remove();
              var item = {
                route: trim($(this)),
                wait: parseInt(trim(waittm))
              };
              pos[pos.length - 1].push(item);
            });
          });
        }
      });
      pos.shift(); // 先頭 (arrstopline) は不要
      //console.log(pos);
      var now = new Date();
      context.done(null, {
        time_t: ~~(now.getTime() / 1000),
        position: pos
      });
    }
  );
};

Githubにアップしておきます。
https://github.com/exabugs/BusNavi

CloudFront

CloudFront の設定は以下。
注意なのは赤丸の Origin の設定部分。なんと APIGateway がリストから選択できないですが、慌てないでAPIGatewayのエンドポイントのURLを直接コピペすると良いです。

スクリーンショット_2016-02-11_19_40_39.png

あとは、デフォルトでいい。

動作確認

サーバサイドが正常に動作しているか、以下で確認できる。

<h3>AWS Cloudfront</h3>
<form action="http://d33zr06jat9rdj.cloudfront.net/tokyu_bus-location" method="POST">
  <table>
    <tr><td>DSMK</td><td><input type="text" name="DSMK" value="3020" /></td></tr>
    <tr><td>ASMK</td><td><input type="text" name="ASMK" value="3633" /></td></tr>
  </table>
  <input type="submit" />
</form>

上記の実験ページを、S3 にアップロードしてホスティングしておきます。
(APIGateway も上げておきますので、適当に実験してもらっていいです。)
http://tokyu.exabugs.s3-website-ap-northeast-1.amazonaws.com/

ここで、パラメータは以下となる。

パラメータ
DSMK 乗車バス停 ID
ASMK 降車バス停 ID

バス停のIDは、以下で調べることができます。
http ://tokyu.bus-location.jp/blsys/navis?VID=top&EID=spn&PRM=&RID=&SCT=

テストコードでは

  • DSMK 3020 鷺沼駅 (田園都市線)
  • ASMK 3633 北山田駅 (横浜市営地下鉄線)

を示しています。

以下のようなjsonがレスポンスされます。

  • time は、現在時刻 time_t です。
  • item 配列の [0] は乗車バス停を指します。[1] は一つ前のバス停。
    6つ前のバス停まで、情報を返します。
  • 例では、二つ前のバス停までバスが来ていて、あと 3分 で到着するということ。
{
  "time": 1455186143,
  "DSMK": 3020,
  "ASMK": 3633,
  "item": [
    [],
    [],
    [
      {
        "wait": 3,
        "route": "鷺01 終)(折)東営行"
      }
    ],
    [],
    [],
    [],
    []
  ]
}

このjsonを WROOM02 で処理する予定。

まとめ

16
17
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
16
17