にゃみかんてっくろぐ

猫か百合を見守る壁になりたい

Raspberry Piでダッシュボードを作る(6) -鉄道遅延情報-

f:id:no_clock:20171016214958j:plain

Raspberry Piとミニディスプレイ,各種センサを使ってダッシュボードを作ります.


今回のゴール

  • 通勤に使っている路線の遅延情報を表示させる.

"鉄道遅延情報のjson"

今回は,鉄道遅延情報のjsonというサイトを利用します.このサイトでは,Tetsudo.com(鉄道コム)が提供する運行情報のRSSフィードJSON形式で返してくれます.

f:id:no_clock:20171112102424p:plain

JSON第4回の天気予報でも扱いましたが,Rubyから簡単に読み取ることが出来ます.

まずはirbで解析

まずはirbを使って,対話型でデータを解析しましょう.

$ irb
irb(main):001:0> require 'uri'
=> true
irb(main):002:0> require 'net/http'
r=> true
irb(main):003:0> require 'yaml'
=> true
irb(main):004:0> data = Net::HTTP.get(URI.parse("https://tetsudo.rti-giken.jp/free/delay.json"))
=> "[{\"name\":\"\xE4\xB9\x85\xE5\xA4\xA7\xE6\x9C\xAC\xE7\xB7\x9A\",\"company\":\"JR\xE4\xB9\x9D\xE5\xB7\x9E\",\"lastupdate_gmt\":1510449602,\"source\":\"\xE9\x89\x84\xE9\x81\x93com RSS\"},
(省略)
irb(main):005:0> json = YAML.load(data)
=> [{"name"=>"久大本線", "company"=>"JR九州", "lastupdate_gmt"=>1510449602, "source"=>"鉄道com RSS"}, {"name"=>"豊肥本線", "company"=>"JR九州", "lastupdate_gmt"=>1510449602, "source"=>"鉄道com RSS"}, 
(省略)

第4回の天気予報と同じやり方で,JSONを解釈しました.companyに会社,nameに路線が入っています.

そのままダッシュボードに載せると不要な情報も入ってしまうため,欲しい路線だけに絞り込みます.Enumerableモジュールのselectメソッドを使うと,条件にマッチする要素だけに絞り込めます.

irb(main):006:0> json.select { |item| item["company"] == "JR東日本" }
=> [{"name"=>"東北本線", "company"=>"JR東日本", "lastupdate_gmt"=>1510449902, "source"=>"鉄道com RSS"}, {"name"=>"羽越本線", "company"=>"JR東日本", "lastupdate_gmt"=>1510449902, "source"=>"鉄道com RSS"}, {"name"=>"白新線", "company"=>"JR東日本", "lastupdate_gmt"=>1510449902, "source"=>"鉄道com RSS"}]
irb(main):007:0> json.select { |item| item["name"] =~ /京浜東北線|山手線/ }
=> []

最初に「会社: JR東日本」,次に「路線: 京浜東北線か山手線(※正規表現を使用)」で絞り込んでみました.何もマッチするものがなければ,空っぽの配列が返ってきます.

データの操作がイメージ出来たところで,ダッシュボードに載せましょう.

ダッシュボードへ

views/index.erbのカードを編集しましょう.ざっとこんな感じです.

<div class="card">
  <%
    require 'uri'
    require 'net/http'
    require 'yaml'
    data = Net::HTTP.get(URI.parse("https://tetsudo.rti-giken.jp/free/delay.json"))
    json = YAML.load(data)

    json = json.select { |item| item["name"] =~ /京浜東北線|山手線/ }
    output_message = json.map { |item| item["name"] }.join("<br>")
  %>
  <h4 class="card-header text-white bg-danger">電車遅延情報</h4>
  <div class="card-body">
    <p class="card-text"><%= output_message %></p>
  </div>
</div>

f:id:no_clock:20171112102425p:plain

表示ができました.

遅延がないときの表示をいい感じにする

表示はできましたが,このままですと,遅延情報がないときの表示が残念なことになります.

f:id:no_clock:20171112102426p:plain

そこで,遅延情報がないときは「タイトルを赤くしない」「『遅延はありません』と表示する」としてみます.

(省略)
    json = json.select { |item| item["name"] =~ /京浜東北線|山手線/ }
    output_message = "遅延情報はありません。"
    output_class   = ""
    if !json.empty?
      output_message = json.map { |item| item["name"] }.join("<br>")
      output_class   = "text-white bg-danger"
    end
  %>
  <h4 class="card-header <%= output_class %>">電車遅延情報</h4>
  <div class="card-body">
    <p class="card-text"><%= output_message %></p>
  </div>

f:id:no_clock:20171112102427p:plain

視覚的にわかりやすくなりました. 

今回はここまで.