前回ラズパイについたボタンを押して換気扇を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)
end68行目で呼び出されるtemp_compメソッドでは2つの温度を読みだした後、「室温が25℃以上かつ、内外の温度差が3℃以上」の場合にフラグファイルを”ON”にする様に値を返します。読み込んだファイルは文字列として扱われる為、四則演算する場合はto_fメソッドで数値として扱うよう変換が必要。to_iにすると整数でto_fが浮動小数点。
タクトスイッチによる手動操作によってONにされている時(switch_st = 1)はたとえ室温が下がってもフラグファイルを書き換えない様にしてあります。手動でOFFにしても外の条件が整うとONになっちゃうのは今後の課題という事で。
なんだか最近めっきり涼しくなった気もしますが、とりあえずは換気扇の自動制御は完了です。あとはちゃんと冷えて欲しいところ。



