Raspberry Piでストーブ番
最近はやりのRaspberryPiでストーブをつけたい!
条件!
- RaspberryPiで外出先からストーブをつけたい
- 外出先から部屋の温度を見たい
- 携帯で操作可能、かつ簡単なタップ操作がいい
- プログラムは素人に毛が生えた程度
以上のことを前提に、先人たちの実績を探しました。
温度取得についてはこちらがよさそうです。湿度も一緒に測れます。
肝心の外出先からRaspberryPiを操作する方法ですが、ストーブの制御をWebに公開するのは心配。そもそもWebアプリなんて作ったことがないので、完成にどれだけ時間がかかるかわからない。冬はもうすぐ、とにかく動かしてみたいんじゃー。
ということで、Gmailのアカウントを作って特定のメールアドレスからメールを受信したらストーブをオンにする、というプログラムを書くことに。
温度・湿度取得の参考元がRubyを使っていたので、という理由でRubyで書きましたが、使ったことのあるシェルスクリプトで十分だったと思います。Rubyの特定の文法がよく分からず躓きました。
RubyにはGemという便利なライブラリがあるようで、Raspberry PiのGIOPを操作するPinPiper、Gmailの制御ができるgmail、ping確認のnet/ping、ログをcsvに書き出すcsvを使用しました。
プログラム初心者でもこれらを組み合わせることで何とか動くものは作れそうですね。
ストーブのスイッチはパソコンのスイッチと同じで単に短絡したらスイッチオンという構造のようです。ただし電圧が15Vほどあって、直流のためリレー回路はアナログのほうがよさそうです。
中国製のリレー回路が売っていたのでこれを使います。
(ebayで1chが100円ぐらいで売っていたのでそっちで買いました)
さて、肝心のプログラムと表示部分です。
RubyにはRuby on Railsというなにやら素晴らしいWebアプリのフレームワークがあるそうですが、私は中学生のころ黒歴史なイラストサイトをタグうちで作ったぐらいしかしたことがないWebアプリ素人です。ですのでできるだけ簡単にと考えた結果、
Gmailのチェック→メールが来る→ストーブをつけると同時にHTMLを直接書き換え
とすることにしました。
簡単ですね。
一応完成したプログラムを下に載せておきます。
もっとクラス?などを使ってわかりやすく書いたほうがいいのでしょうが、まだオブジェクト指向を理解し切れてないのでごちゃごちゃしてます。
あとはこれをcronで定期実行すれば、
OFFのボタンはただのメールリンクになっていて、タップするとメーラーが起動します。
メールを送るとONになりますがcronの実行タイミングの関係で最大1分ラグがあります。
#coding: utf-8
require 'gmail'
require 'pi_piper'
require 'net/ping'
require 'csv'
LOCKFILE = "/home/pi/www/stove.lock"
LOGFILE = "/home/pi/www/stove.log"
STATUSFILE = "/home/pi/www/csv/status.txt"
ON_MASSAGE = "<a href=mailto:"ラズパイのメルアド"?subject=ストーブ消して data-ajax=false class=ui-btn> ON </a>";
OFF_MASSAGE = "<a href=mailto:"ラズパイのメルアド"?subject=ストーブつけて data-ajax=false class=ui-btn> OFF </a>";
def pin17on
pin = PiPiper::Pin.new(:pin => 17, :direction => :out)
pin.on
end
def pin17off
pin = PiPiper::Pin.new(:pin => 17, :direction => :out)
pin.off
end
USERNAME= #gmailのアドレス
PASSWORD= #gmailのパスワード#ネット接続が失われたらオフにする
addr = 'google.co.jp'
pinger = Net::Ping::External.new(addr)
t = Time.now
if pinger.ping?
puts 'ping ok'
data = [t.strftime("%m%d"),t.strftime("%H:%M"),'ok']
CSV.open( "/home/pi/www/netstatus.csv", "a" ){ |csv|
csv << data }
else
open(STATUSFILE, "w") {|f| f.write OFF_MASSAGE}
pin17off
if File.exist?(LOCKFILE) then
File.delete(LOCKFILE)
end
data = [t.strftime("%m%d"),t.strftime("%H:%M"),'ng']
CSV.open( "/home/pi/www/netstatus.csv", "a" ){ |csv|
csv << data }
end
pin2 = PiPiper::Pin.new(:pin => 18, :direction => :in)
pin2.read
PINSTATUS = pin2.value
if File.exist?(LOCKFILE) then
open(STATUSFILE, "w") {|f| f.write ON_MASSAGE}
if PINSTATUS == 0 then
pin17on
end
else
open(STATUSFILE, "w") {|f| f.write OFF_MASSAGE}
if PINSTATUS == 1 then
pin17off
end
end
gmail = Gmail.new(USERNAME,PASSWORD)
mails = gmail.inbox.emails(:unread).map do |mail|
#emailsの引数には:all,:read,unreadがある
#件名、日付、From、To
#puts "Subject: #{mail.subject}"
#puts "Date: #{mail.date}"
if mail.from == ["自分のメルアド"] then
if mail.subject == "ストーブつけて" then
if PINSTATUS == 1 then
message = 'もうついてるよ'
else
message = 'ストーブつけたよ'
pin17on
end
File.open(LOCKFILE, "w"){|f|}
open(STATUSFILE, "w") {|f| f.write ON_MASSAGE}
SEND = message
Mailto = mail.from
elsif #{mail.subject} == 'ストーブ消して' then
if PINSTATUS == 1 then
pin17off
SEND = "ストーブけしたよ"
else
SEND = "ストーブ消えてたよ"
end
if File.exist?(LOCKFILE) then
File.delete(LOCKFILE)
open(STATUSFILE, "w") {|f| f.write OFF_MASSAGE}
end
Mailto = mail.from
end
else
SEND = mail.from
SEND =SEND.to_s + "からメールだよ"
Mailto = "自分のメルアド"
end
gmail.disconnect
if SEND
gmail = Gmail.new()
Timenow = Time.now.to_s
gmail.deliver do
to Mailto
subject SEND
text_part do
body Timenow
end
end
end
end
感想と課題
今IoTの分野がホットということで、とりあえず動くものができて満足。
ただしRaspberryPi自体の安定性とストーブを無人で動かす危険性から常用は無理ですね。
課題
・Webアプリを作って詳細なタイマー設定などを作る
・安全性のためWebカメラをつなげて監視?
・ストーブという時点で危険性は不可避なのでオイルヒーターを買う(new!)
まだまだ試したいことはあるので、色々いじって勉強したいと思います。