RaspberryPi に Rest API を簡単に実装
概要
Raspberry Pi に対して情報を取得する際に HTTPを利用してこれを行いたい場合がある。
ruby のウェブフレームワークで有名なのは、Rails だが、Rails は大規模向けであるため
簡素な実装をするにも、構築時間、学習コストが見合わないことがある。
今回は ruby 初心者でも手軽に実装できる、軽量フレームワークのSinatraを導入し、Rest APIを実装してみた。
Sinatra 導入
ruby, gem 導入
このあたりで多分導入できる(はず)。
Raspberry piにRubyの最新版をインストールする - Qiita
なお、自身のRaspberryPiにはすでにインストールされていたため、実施していません。
バージョン関連の情報は以下。
$ ruby -v ruby 2.1.5p273 (2014-11-13) [arm-linux-gnueabihf] $ gem -v 2.2.2
URI、コンテンツ定義
以下のファイルをどこでもいいので、作成する。(下記を app.rb として保存する)
require 'sinatra' set :bind, '0.0.0.0' # これを書くと http://localhost:4567 以外からでもアクセス可能。 get '/' do # ルートに GET でアクセスした場合 "Top!\n" # 返却する内容 end get '/:name' do |n| # /{name} GET でアクセスした場合 "Hello #{n}\n" # {name}の部分を値として使う end
サーバ起動
$ ruby app.rb
アクセス
※ 192.168.0.30 はRaspberrypiのプライベートアドレス
http://192.168.0.30:4567/
http://192.168.0.30:4567/aaa
実装例
これだけであれば、インストール除けば5分で作成可能。
メモリとディスクのプロパティを入手する API を作ってみた。
require 'sinatra' require 'json' set :bind, '0.0.0.0' disk = Struct.new("Disk", :name, :path, :total, :used) get '/disk' do disks = `df -l | sed -e "1d"`.split("\n").inject([]) do |list, line| arr = line.split("\s") list << disk.new(arr[0], arr[5], arr[3].to_i, arr[2].to_i).to_h end JSON.generate({"disks" => disks}) end memory = Struct.new("Memory", :total, :used, :free, :shared, :buffers, :cached) get '/memory' do arr = `free | sed -n -e "2p"`.split("\s") mem = memory.new(arr[1].to_i, arr[2].to_i, arr[3].to_i, arr[4].to_i, arr[5].to_i, arr[6].to_i) JSON.generate(mem.to_h) end
Cygwin 上で curl 実行できれば、下記コマンドでいける。
$ curl http://192.168.0.30:4567/disk | jq . % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 580 100 580 0 0 3505 0 --:--:-- --:--:-- --:--:-- 3602 { "disks": [ { "name": "/dev/root", "path": "/", "total": 22113944, "used": 6837300 }, { "name": "/dev/sda1", "path": "/media/hdd1", "total": 455974524, "used": 177392 }, ] } $ curl http://192.168.0.30:4567/memory | jq . % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 91 100 91 0 0 1925 0 --:--:-- --:--:-- --:--:-- 2166 { "total": 948012, "used": 879992, "free": 68020, "shared": 28708, "buffers": 206668, "cached": 267452 }
まとめ
テンプレート利用やルーティング条件などが設定できるため、ある程度難しいこともできそうだ。
もし、バックエンドでのみ使用する API であれば、製造コスト的に選択の一つとしてはいいかもしれない。