Raspberry Pi RubyでAtd7410の測定値をグラフ表示する
構成
1.Webフレームワーク sinatra
2.データベース sqlite3
動作
1.ATD7410で測定した温度をhttp postにてサーバーへ通知します。
通知情報 uid:識別コード latitude:緯度(予約) longitude:経度(予約) value:測定値 created_at:測定時間
測定値は10分間隔で通知します。
2.postされた情報はsqlite3に書き込みます。
3.ブラウザーからraspberry pi をアクセスるとグラフが表示されます。
gruff gemを使用しました。
ディレクトリ構成
tsv/
+- main.rb sinatra
post.rb 温度測定 & post
tsv.db データベース
rasp_i2c.so
views
+- index.erb
layout.erb
public
+-img
+-temp.png グラフ画像
main.rb
#! ruby # -*- coding:utf-8 -*- require 'sinatra/base' require 'logger' require 'gruff' require 'json' require 'pp' require 'kconv' require 'sqlite3' $db_file = File.dirname(File.expand_path(__FILE__)) + "/tsv.db" log_file = File.dirname(File.expand_path(__FILE__)) + "/post.log" $log = Logger.new(log_file) $log.level= Logger::INFO # # DB access Class # class Cdb def initialize(db_file) begin @dbh = SQLite3::Database.new(db_file) rescue => ex puts "class: #{ex.to_s}" end end def connect err_times=0 begin yield @dbh # yield(@dbh) rescue SQLite3::BusyException => ex puts "sql error #{ex.to_s}" if err_times < 3 err_times +=1 sleep(2) retry else @dbh.rollback end rescue => ex puts "sql error #{ex.to_s}" ensure @dbh.close end end end def create_table() sql =<<SQL create table temperature ( id integer primary key autoincrement, uid text NOT NULL, value real, latitude real, longitude real, created_at text ); SQL db =Cdb.new($db_file) db.connect do |dbh| dbh.execute("drop table if exists temperature;") dbh.execute(sql) end end # -- temperatuer table create -- # create_table() # exit def take_tempe() res = [] db =Cdb.new($db_file) db.connect do |dbh| res = dbh.execute("select * from(select * from temperature order by created_at desc limit 10) order by created_at asc;") end val=[] tim=[] res.each do |arry| val << arry[2] tim << arry[5] end p val h_tim= Hash[tim.map.with_index{ |daytime, i| [i, daytime.scan(/\d+:\d+/)[0]] }] p h_tim g = Gruff::Line.new g.title= " room temperature" g.data("living", val) g.labels = h_tim g.write("public/img/temp.png") end class MainApp < Sinatra::Base # 本番環境 :production 開発環境 :development localhostからのアクセスのみ許可 set :environment, :production get '/' do # graph("== TEMPERATUR ==") @graph_image="img/temp.png" # erb :index take_tempe() erb :index end post '/temp' do # pp params db =Cdb.new($db_file) sql = "insert into temperature values (?,?,?,?,?,?);" # id:auto increment db.connect do |dbh| dbh.execute(sql,nil,params[:uid],params[:value],params[:latitude],params[:longitude],params[:created_at]) end "OK" end end MainApp.run! :port => 80
post.rb
#! ruby # require 'net/http' require 'url' require './rasp_i2c' class Atd7410 < RaspI2c CONF_REG=0x03 attr_reader :temp def initialize(addr, bit) @bit = bit @temp = 0 super(addr) # class RaspI2c の initialize を実行 if @bit == 16 write_reg_b(CONF_REG, 0x80) # 16bit mode end end def read @temp = read_w(0x00) if @bit == 16 @temp -= 65536 if @temp >= 65536 @temp /= 128.0 else @temp >>= 3 @temp -= 8192 if @temp >= 4096 @temp /= 16.0 end puts "温度:%3.4f"%@temp return @temp end end def server_post(uid,latitude,longitude,value,created_at) uri="http://localhost/temp" res=Net::HTTP.post_form(URI.parse(uri), {uid:uid,latitude:latitude,longitude:longitude,value:value,created_at:created_at}) puts res.body end def main atd= Atd7410.new(0x48, 13) # address 13bit uid = "4567" while true p ondo = atd.read server_post(uid, 0 ,0 , ondo, Time.now) sleep 600 end end main
layout.erb
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title> ONDO </title> <script type="text/javascript" src="js/js-class.js"></script> <script type="text/javascript" src="js/excanvas.js"></script> <script type="text/javascript" src="js/bluff-src.js"></script> </head> <body> <%= yield %> </body> </html>
index.erb
<h1>--TEMPERATURE--</h1> <img src=<%= @graph_image %>