前回ラズパイについたボタンを押して換気扇をOFF/ONする所までは作成しました。今回は簡単な温度制御を入れます。
気温をWebからruby+JSONで取る
無料の天気(含む気温)データを提供してくれるOpenWeatherMap current weather and forecast- OpenWeatherMapを利用しました。Webでもデータが見れますが、会員登録をするとAPIによる温度取得ができます。無料のfreeプランでは1時間に60回までの取得が可能。
apiの出力結果はJSONで受け取れるようなので、以下のページを参考に取得してみます。
当初q=sapporoとだけ指定していたら何度やってもヘルシンキの温度がくるので悩みました。正しくはq=sapporo.jpとやらないと認識されないので注意が必要。
openweather.rb
require 'open-uri' require 'json' response = open('http://api.openweathermap.org/data/2.5/weather?q=sapporo.jp&lat=43.058&units=metric&APPID=myAPINumber') data = response.read json = JSON.parse(data) puts json['main']['temp']
無事に取得できました。
# ruby openweather.rb 22.68
ただOpenweatherの提供データは国内複数の「現在の気温」データを平均しても1.5℃程低いですね。もうちょっと観察して必要時はかさ増しして利用しようかと思います。
あとはこれを/dev/shm/outer_temp.datというファイルに書き出し。
require 'open-uri' require 'json' response = open('http://api.openweathermap.org/data/2.5/weather?lon=141.35&lat=43.058&units=metric&APPID=myAPINumber') data = response.read json = JSON.parse(data) File.write '/dev/shm/outer_temp.dat', json['main']['temp']
排他制御を必要としないならFile.writeメソッドでズバッと書けてしまうそうです。便利です。
スクリプト完成
上記のスクリプトとCで書いてあるDHT11tempをcronへ登録します。
*/7 * * * * /usr/sbin/DHT11/dht11temp > /dev/shm/inner_temp.dat */15 * * * * ruby /usr/sbin/WEATHER/openweather.rb
dht11tempが7分おきなのは10分ごとに動く他のプログラムとコンフリクトしないようにという事で適当に素数・・・
あとはこの定期的に更新される室内温度、外気温度を比較してファンの動作を決定させます。前回のスクリプトから追加したのが下記。
/usr/sbin/IO/2Froomfan_manage.rb
require 'wiringpi' require 'fileutils' #init io = WiringPi::GPIO.new do |gpio| gpio.pin_mode(3, WiringPi::OUTPUT) gpio.pin_mode(7, WiringPi::OUTPUT) gpio.pin_mode(0, WiringPi::INPUT) end io.digital_write(3, WiringPi::LOW) io.digital_write(7, WiringPi::LOW) f_chk_code = "ON" switch_st = 0 File.write('/dev/shm/flag_file.dat', 'OFF') # FLAG READ def flag_read flag_file = "/dev/shm/flag_file.dat" File.open(flag_file, "r:UTF-8") do |f| f_chk = f.gets return f_chk.chomp! end end # FLAG WRITE def flag_write(fw) flag_file = "/dev/shm/flag_file.dat" File.open(flag_file, "w:UTF-8") do |f| if f.flock(File::LOCK_EX|File::LOCK_NB) if fw >= 1 then f.puts("ON") else f.puts("OFF") end return 0 else return 1 end end end # Check temp deff def temp_comp inner = File.read('/dev/shm/inner_temp.dat') outer = File.read('/dev/shm/outer_temp.dat') inner.chomp! outer.chomp! if inner == "" || outer == "" then return 2 end diff = inner.to_i - outer.to_i if inner.to_i >= 27 && diff > 3 then return 1 else return 0 end end # Main loop loop do now = flag_read diff_res = temp_comp #button check buttom_state = io.digital_read(0) if buttom_state == 1 then sleep(0.4) buttom_state = io.digital_read(0) if buttom_state == 1 then if now == f_chk_code flag_write(0) switch_st = 0 else flag_write(1) switch_st = 1 end end end #temp check if diff_res == 1 && switch_st == 0 then flag_write(1) elsif diff_res == 0 && switch_st == 0 then flag_write(0) end #Relay Switch if now == f_chk_code then io.digital_write(3, WiringPi::HIGH) io.digital_write(7, WiringPi::HIGH) else io.digital_write(3, WiringPi::LOW) io.digital_write(7, WiringPi::LOW) end sleep(0.5) end
68行目で呼び出されるtemp_compメソッドでは2つの温度を読みだした後、「室温が25℃以上かつ、内外の温度差が3℃以上」の場合にフラグファイルを”ON”にする様に値を返します。読み込んだファイルは文字列として扱われる為、四則演算する場合はto_fメソッドで数値として扱うよう変換が必要。to_iにすると整数でto_fが浮動小数点。
タクトスイッチによる手動操作によってONにされている時(switch_st = 1)はたとえ室温が下がってもフラグファイルを書き換えない様にしてあります。手動でOFFにしても外の条件が整うとONになっちゃうのは今後の課題という事で。
なんだか最近めっきり涼しくなった気もしますが、とりあえずは換気扇の自動制御は完了です。あとはちゃんと冷えて欲しいところ。