Ruby初心者がラズパイに書く換気扇制御プログラム -出口編-

Ruby初心者がラズパイに書く換気扇制御プログラム -出口編-

前回ラズパイについたボタンを押して換気扇を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になっちゃうのは今後の課題という事で。

なんだか最近めっきり涼しくなった気もしますが、とりあえずは換気扇の自動制御は完了です。あとはちゃんと冷えて欲しいところ。

コメントを残す