Raspberry Piでダッシュボードを作る(5) -温度・湿度(センサ)-
Raspberry Piとミニディスプレイ,各種センサを使ってダッシュボードを作ります.
- Raspberry Piでダッシュボードを作る(1) -準備-
- Raspberry Piでダッシュボードを作る(2) -真っ白ダッシュボード-
- Raspberry Piでダッシュボードを作る(3) -デザイン-
- Raspberry Piでダッシュボードを作る(4) -天気予報-
- Raspberry Piでダッシュボードを作る(5) -温度・湿度(センサ)- ←イマココ
今回のゴール
- 室内の温度・湿度を表示する.
センサの調達
Raspberry Pi本体にセンサはありませんが,GPIO(General Purpose Input/Output: 汎用入出力)用のピンが40ピン*1配置されています.このピンを使って,センサ類に電源を供給したり,通信したりすることが可能です.というわけで,センサを調達します.
(余談… これまでソフトウェアにしか縁がなく,センサなどの電子部品を扱うのは難しいと思っていました.が,やってみると案外難しくありませんし,「Raspberry PiでXXをやってみた」系の記事もたくさん見つかります.特に今回は工具不要で刺すだけ繋ぐだけです.心配はいりません!)
材料
(リンクはすべて秋月電子通商にジャンプします)
温湿度センサ 温湿度を測定するためのものです.I2Cという通信方式に対応していて,読み取りが比較的容易です.
ブレッドボード 電子部品の実験用パーツです.たくさん穴が空いていて,一定のルールで電気的に繋がっています.ここに部品やケーブルを繋いで,回路を組み立てます.
ジャンプワイヤ 電子部品どうしを繋ぐケーブルです.今回はRaspberry Piとブレッドボードを繋ぐために使用します.
配線
Raspberry Piの電源を切っておきます.Raspberry Piのピン配置図やAM2320のデータシート(秋月のページにPDFへのリンクあり)を参照しつつ,配線します.
I2C有効化
標準でI2Cが無効になっているため,まずは有効にします.設定はGUI/CUIいずれでも可能です.設定が終わったら,念のため再起動しておきましょう.
参考: 最近の Raspberry Pi で I2C を有効化 - Rabbit Note
読み取り
温度と湿度を読み取ります.I2Cは,複数の電子部品(デバイス)と通信できるように,「デバイスのアドレス」と「データ」をセットで通信します.データ(バイト列)の内容はデバイスによって様々です.
本当はデータシートをじっくり眺めるべきところですが,幸いAM2320は接続例が多数あります.そうした情報を活用しましょう.
参考: 温湿度センサAM2320をRaspberry Pi 3で使用する|wizqro.net
Pythonの登場
今回はRubyではなくPythonというプログラミング言語が登場します.Python 3系が新しいので,こちらをインストールしましょう.
$ sudo apt-get install python3 python3-smbus $ python3 (Python 3.x系が起動する.quit()またはCtrl+Dキーで終了)
参考ページのスクリプトをファイルに書き込み,実行してみましょう.
(read_temphumid.pyとして作った場合) $ python3 read_temphumid.py 59.0 20.8
1行目が湿度,2行目が温度です.読み取れました.
ダッシュボードへの追加
ダッシュボードはRubyスクリプト,温湿度の読み取りはPythonスクリプト.
ここはちょっと無理矢理ですが,RubyスクリプトからPythonスクリプトを実行することで,温湿度をダッシュボード上に表示していきます.
先ほどのread_temphumid.py
は,ダッシュボードのapp.rb
と同じディレクトリに置いておきます.そして,views/index.erb
を編集します.
<div class="card"> <h4 class="card-header text-white bg-success">温湿度</h4> <div class="card-body"> <% data = `python3 read_temphumid.py`.split(/\n/) humidity = data[0] temperature = data[1] %> <p class="card-text"> 気温: <%= temperature %>℃<br> 湿度: <%= humidity %>% </p> </div> </div>
ダッシュボードを表示しましょう.温度・湿度が表示されました.
今回はここまで.
*1:古いモデルは26ピン
Raspberry Piでダッシュボードを作る(4) -天気予報-
Raspberry Piとミニディスプレイ,各種センサを使ってダッシュボードを作ります.
- Raspberry Piでダッシュボードを作る(1) -準備-
- Raspberry Piでダッシュボードを作る(2) -真っ白ダッシュボード-
- Raspberry Piでダッシュボードを作る(3) -デザイン-
- Raspberry Piでダッシュボードを作る(4) -天気予報- ←イマココ
今回のゴール
- 天気予報を表示させる.
体調を崩して少し間が空いてしまいました.デザインが出来たところで天気予報を表示させていきます.
livedoor Weather Hacks
livedoorが,Weather Hacksと題して天気予報などのデータを提供しています.商用利用はできませんが,事例のところで九州の方言が楽しめるばい(方言).
ここでは,そのうちのお天気Webサービスを使います.レスポンスがJSON形式で返却されるため,取り扱いが非常に簡単です.
URLやパラメタの確認
URLやパラメタの地域(city)IDについては,お天気Webサービスのページに記述がありますのでよく読みましょう.例えば東京のidは130010です.
http://weather.livedoor.com/forecast/webservice/json/v1?city=130010
PCのブラウザで開くと,JSONと呼ばれる形式でデータが確認できます.
※スマートフォンのブラウザ等ではJSONハイジャック防止のため表示できない場合があります.
irb(Interactive Ruby)でデータを解析
では,ダッシュボードへ表示する準備です.
いきなりダッシュボードに載せる前に,rubyを対話型実行できるirb
を使って,データを解析してみましょう.
$ irb irb(main):001:0>
irb
を起動すると,入力待ちの状態になります.1行ごとに入力した内容が実行され,結果が分かるという優れものです(exitで終了します).
irb(main):001:0> require 'uri' => true
require 'uri'
と入力して実行すると,true
という結果が返却されました.
このままじゃんじゃん入力します.
irb(main):002:0> require 'net/http' => true irb(main):003:0> require 'yaml' => true irb(main):004:0> data = Net::HTTP.get(URI.parse("http://weather.livedoor.com/forecast/webservice/json/v1?city=130010")) => "{\"pinpointLocations\":[{\"link\":\"http://weather.livedoor.com/area/forecast/1310100\",\"name\":\"\\u5343\\u4ee3\\u7530\\u533a\"}, (省略) irb(main):005:0> json = YAML.load(data) => {"pinpointLocations"=>[{"link"=>"http://weather.livedoor.com/area/forecast/1310100", "name"=>"千代田区"}, (省略)
お天気WebサービスのJSONを解釈するところまで進めました.なんだか読めるモノが出てきたと思います.
引き続きお天気Webサービスの仕様を見ていると,forecasts
というプロパティに天気予報が入っていることが分かります.ちょっと見てみます.
irb(main):006:0> json["forecasts"] => [{"dateLabel"=>"今日", "telop"=>"曇時々晴", "date"=>"2017-10-31", "temperature"=>{"min"=>nil, "max"=>nil}, "image"=>{"width"=>50, "url"=>"http://weather.livedoor.com/img/icon/9.gif", "title"=>"曇時々晴", "height"=>31}}, (省略)
おっ,天気予報です.date
が日付,telop
が予報,temperature
が予想気温(夜に取得したのでその日の予想情報は無い)のようです.
だいたい取得方法がわかったので,ダッシュボードに載せていきましょう.
いざダッシュボードへ
ダッシュボードアプリの views/index.erb
を編集します.前回のデザインでカードを4個置いたので,そのうち1個を使いましょう.
<div class="card"> <h4 class="card-header">天気予報</h4> <div class="card-body"> <% # 天気予報取得処理 require 'uri' require 'net/http' require 'yaml' data = Net::HTTP.get(URI.parse("http://weather.livedoor.com/forecast/webservice/json/v1?city=130010")) json = YAML.load(data) # 今日と明日の天気 today = json["forecasts"][0]["telop"] tomorrow = json["forecasts"][1]["telop"] %> <p class="card-text"> <strong>今日</strong>: <%= today %><br> <strong>明日</strong>: <%= tomorrow %> </p> </div> </div>
補足 erb(embedded Ruby)テンプレートでは,<% ~ %>
の間にRubyスクリプトを記述したり,<%= ~ %>
の間にページに出力したい変数や式を記述することで,出力内容を柔軟に変えることができます.それ以外の部分は,そのまま出力されます.
すかさず http://localhost:4567/ にアクセスします.天気予報が表示されました.
もうちょっと,ダッシュボードへ
物足りないのでちょっと表示を良くしましょう.スクリプトの細かい説明は省きます.
<div class="card"> <h4 class="card-header">天気予報</h4> <div class="card-body"> <% # 天気予報取得処理 require 'uri' require 'net/http' require 'yaml' data = Net::HTTP.get(URI.parse("http://weather.livedoor.com/forecast/webservice/json/v1?city=130010")) json = YAML.load(data) # 今日と明日の天気 today = json["forecasts"][0]["telop"] tomorrow = json["forecasts"][1]["telop"] %> <p class="card-text"> <% json["forecasts"].each { |forecast| %> <strong><%= forecast["dateLabel"] %></strong>: <%= forecast["telop"] %> <% if forecast["temperature"]["min"] %> <span class="text-info">最低<%= forecast["temperature"]["min"]["celsius"] %>℃</span> <% end %> <% if forecast["temperature"]["max"] %> <span class="text-danger">最高<%= forecast["temperature"]["max"]["celsius"] %>℃</span> <% end %> <br> <% } %> </p> </div> </div>
気温も表示されるようになったと思います.
ページを表示するたびにお天気Webサービスへアクセスするので,更新しすぎに注意しましょう.
今回はここまで.
Raspberry Piでダッシュボードを作る(3) -デザイン-
Raspberry Piとミニディスプレイ,各種センサを使ってダッシュボードを作ります.
- Raspberry Piでダッシュボードを作る(1) -準備-
- Raspberry Piでダッシュボードを作る(2) -真っ白ダッシュボード-
- Raspberry Piでダッシュボードを作る(3) -デザイン- ←イマココ
今回のゴール
- デザインを決める.
デザイン
雰囲気や「それっぽさ」は大事です.真っ白では味気ないので,見栄えをよくしましょう.
ここでもフレームワークが登場します.Bootstrapです.CDNで提供されており,カスタマイズせず使う場合はインストール不要です.
まずは,app.rb
に手を入れます.
#!/usr/bin/env ruby require 'sinatra' get '/' do erb :index # この行を書き換え end
前回'こんにちは'
とした箇所をerb :index
に変更しました.簡単に言えば『views/index.erb
というファイルをERBテンプレートエンジンで表示して』という記述です.もっと詳しく知りたい方は,GitHub: sinatra/sinatraの"Views / Templates"セクション,あるいはその日本語訳をご覧ください.
というわけで,viewsディレクトリを作ってviews/index.erb
ファイルを作成します.
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Dashboard</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous"> <meta http-equiv="refresh" content="600"> </head> <body> <div class="container-fluid"> <div class="row"> <!-- 左列 --> <div class="col"> <div class="card"> <h4 class="card-header">タイトル1</h4> <div class="card-body"> <p class="card-text">本文1</p> </div> </div> <div class="card"> <h4 class="card-header text-white bg-success">タイトル2</h4> <div class="card-body"> <p class="card-text">本文2</p> </div> </div> </div> <!-- 右列 --> <div class="col"> <div class="card"> <h4 class="card-header text-white bg-danger">タイトル3</h4> <div class="card-body"> <p class="card-text">本文3</p> </div> </div> <div class="card text-white bg-dark"> <h4 class="card-header">タイトル4</h4> <div class="card-body"> <p class="card-text">本文4</p> </div> </div> </div> </div> </div> </body> </html>
長くなりました.まずは,この状態で表示させてみましょう.
表示してみる
(既にapp.rbを起動済みの場合は,一度Ctrl+Cキーで停止させておく.) $ ./app.rb
前回と同じく http://localhost:4567/にアクセスします.表示されましたか?
(黒っぽいデザインにしたいときは…)
- Bootswatchから,Darklyテーマのbootstrap.min.cssをダウンロードする.
- publicディレクトリを作り,
public/bootstrap.min.css
に配置する. views/index.erb
の記述を一部変更して,リフレッシュする.
<link rel="stylesheet" href="bootstrap.min.css">
ちょっと説明
さて,index.erbの説明を少しします.コードを見れば分かる,という方は今回はここまでです.
Bootstrapのデザイン
グリッドシステム … Bootstrapでは,横を12等分したGrid systemでデザインします.横2列作ると,12等分されたグリッドが6個ずつ自動で割り当てられます.手動で個数を指定したり,スマートフォンやPCなど画面の大きさによって異なる個数を指定する,といったことも可能です.
カード … Bootstrapにはデザインのための様々なコンポーネントがありますが,ここではCardを使いました.スクリーンショットで色の異なるカードが登場しているように,class属性の指定を変えることで背景・文字色をカスタマイズすることも可能です(Card: Card styles)
その他の表示スタイル
更新頻度 … 古典的なmetaタグを使い,ページは600秒(10分)ごとに更新されるようにしています.
全画面表示,キオスクモード … F11キーを押して全画面表示にしましょう.ダッシュボードっぽさが増します.なお,Chromium(Chrome)には「キオスクモード」が用意されており,起動時点から全画面で表示させることも出来ます.気になる方は調べてみてください.
今回はここまで.
Raspberry Piでダッシュボードを作る(2) -真っ白ダッシュボード-
Raspberry Piとミニディスプレイ,各種センサを使ってダッシュボードを作ります.
- Raspberry Piでダッシュボードを作る(1) -準備-
- Raspberry Piでダッシュボードを作る(2) -真っ白ダッシュボード- ←イマココ
今回のゴール
- 「こんにちは」と表示する真っ白なダッシュボードを作る.
Webアプリケーションとして作る
準備ばかりでは退屈なので,「こんにちは」と表示するダッシュボードを作って動かしましょう.
ダッシュボードは,スクリプト言語Rubyと軽量フレームワークSinatraを使って,Webアプリケーションとして作っていきます.とても簡単に作ることができます.
rubyインストール
$ sudo apt-get install ruby
以上.簡単です.
あるいは,rbenv*1を使うことも出来ます.ただし,rubyをビルドする時間が長いためあまりおすすめはしません(私はそれでもrbenvを使いましたが).興味があれば Raspberry Pi rbenv などで検索してみてください.
Sinatraインストール
Ruby on Railsが有名どころですが,ダッシュボードにはちょっと豪華すぎます.そこで,Sinatraという軽量なフレームワークを使います.
$ sudo gem install sinatra
インストールはこれだけです.
Rubyは,ライブラリが"gem(ジェム)"という形で用意されていて,パッケージ管理システムRubyGemsで簡単にインストール出来るようになっています.
そのRubyGemsがgemコマンドです.「RubyGemsなんてインストールしてないぞ?」と思うかもしれませんが,rubyパッケージに含まれています.
真っ白ダッシュボードの作成
いよいよ真っ白な「こんにちは」だけのダッシュボードを作ります.
app.rb というファイルを作り,下記のコードを記述します.
#!/usr/bin/env ruby require 'sinatra' get '/' do 'こんにちは' end
空行を含めてもたった6行ですが,これで準備が整いました.
ダッシュボードの起動と表示
早速起動します.chmodコマンドで実行権限を与え,app.rbを実行します.
$ chmod +x ./app.rb $ ./app.rb == Sinatra (v1.4.8) has taken the stage on 4567 for development with backup from Thin Thin web server (v1.6.4 codename Gob Bluth) Maximum connections set to 1024 Listening on localhost:4567, CTRL+C to stop
Webサーバが起動して,アクセス待ちの状態になりました(停止するときは Ctrl+C キー).
Raspberry Piでブラウザ(例えばChromium)を起動して, http://localhost:4567/ にアクセスしましょう.
「こんにちは」が表示されましたか? あっという間にWebサービスが出来上がりました.
※注: app.rb内のメッセージを書き換えても,起動し直さないと反映されません.注意してください.
今回はここまで.次回以降は,デザインを整えて,ダッシュボードの部品を作っていきます.
*1:Rubyのバージョン管理システム.最新版の導入やバージョンの使い分けが簡単になる
Raspberry Piでダッシュボードを作る(1) -準備-
Raspberry Piとミニディスプレイ,各種センサを使ってダッシュボードを作ります.
準備
まずは基本的な準備から始めます.
必要なもの
- Raspberry Pi 3 Model B (HDMI,USB,LANが使えれば旧モデルでも構いません)
- HDMI接続のミニディスプレイ
- インターネット接続
- センサなどの電子部品 (使うときに紹介します)
ミニディスプレイは何でも良いです.写真ではElecrowの5インチディスプレイを使用し,USB,HDMIともRaspberry Piに繋げています.SPI接続でタッチパネルも使用可能となる仕様ですが,センサ類が繋げなくなるので諦めました.
環境構築
サクサクとGUI環境を整えていきます.
- Raspbianをインストール (Download Raspbian for Raspberry Pi)
- 詳しくはGoogle先生をあたってください.
- HDMIでディスプレイ接続
- ディスプレイによって設定がまちまちですが,Elecrow 5インチディスプレイでは
/boot/config.txt
に下記を記述することで表示ができました.
- ディスプレイによって設定がまちまちですが,Elecrow 5インチディスプレイでは
hdmi_group=2 hdmi_mode=1 hdmi_mode=87 hdmi_cvt 800 480 60 6 0 0 0
今日はここまで.