NetatmoのAPIを利用してSlackに通知する
#!/usr/bin/env ruby | |
require 'net/https' | |
require 'json' | |
require 'uri' | |
require 'pp' | |
@netatmo_config = { | |
client_id: 'XXXXXXXXXXXXXXXXXXXXXXXXX', | |
client_secret: 'XXXXXXXXXXXXXXXXXXXXXXXXX', | |
username: 'XXXXXXXXXXXXXXXXXXXXXXXXX', | |
password: 'XXXXXXXXXXXXXXXXXXXXXXXXX' | |
} | |
@slack_config = { | |
token: 'xoxb-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', | |
name: 'BOT_NAME', | |
icon: 'SLACK_ICON', | |
channel: 'SLACK_CHANNE', | |
} | |
# Ref: http://www.mhlw.go.jp/bunya/kenkou/seikatsu-eisei10/ | |
# 厚生労働省 建築物環境衛生管理基準について | |
@low_temp = 17.0 | |
@high_temp = 28.0 | |
@high_hum = 70.0 | |
@low_hum = 40.0 | |
@low_co2 = 700 | |
@high_co2 = 1000 | |
@attention_low_temp = 15.0 # アラートとしては未使用 | |
@attention_high_temp = 30.0 | |
@attention_high_hum = 80.0 | |
@attention_low_hum = 30.0 | |
@attention_high_co2 = 1200 | |
# アクセスするためのtokenを取得する | |
def access_token | |
netatmo_auth_url = URI('https://api.netatmo.com/oauth2/token') | |
res = Net::HTTP.post_form(netatmo_auth_url, | |
grant_type: 'password', | |
client_id: @netatmo_config[:client_id], | |
client_secret: @netatmo_config[:client_secret], | |
username: @netatmo_config[:username], | |
password: @netatmo_config[:password], | |
scope: 'read_station' | |
) | |
auth = JSON.parse(res.body) | |
token = auth['access_token'] | |
token | |
end | |
# tokenを渡してNetatmoのデータを取得する | |
def netatmo_data(netatmo_token) | |
netatmo_url = 'https://api.netatmo.com/api/getstationsdata' | |
uri = URI.parse(netatmo_url) | |
http = Net::HTTP.new(uri.host, uri.port) | |
http.use_ssl = true | |
req = Net::HTTP::Post.new(uri.path) | |
req.set_form_data({access_token: netatmo_token}) | |
res = http.request(req) | |
data = JSON.parse(res.body) | |
data['body']['devices'][0]['dashboard_data'] | |
end | |
# Slackへの通知メッセージを生成する | |
def alert_message(data) | |
message = '' | |
# 室温 | |
if data['Temperature'].to_i > @attention_high_temp.to_i | |
temp_diff = data['Temperature'] - @high_temp | |
temp_diff_message = "室温が高いです :hotsprings:\n室温を *#{temp_diff.to_i}度* 下げましょう :pray: " | |
message = "#{temp_diff_message}" | |
end | |
# 湿度 | |
if data['Humidity'] > @attention_high_hum | |
hum_diff = data['Humidity'] - @attention_high_hum | |
hum_diff_message = "*湿度が高いです* :umbrella_with_rain_drops:\nどなたか、除湿機をつけて湿度を *#{hum_diff}%* 下げてください :sob: " | |
message = message + "\n#{hum_diff_message}" | |
elsif @attention_low_hum > data['Humidity'] | |
hum_diff = @low_hum - data['Humidity'] | |
hum_diff_message = "*湿度が低いです* :innocent:\nどなたか、加湿器をつけて湿度を *#{hum_diff}%* 上げてください :sob: " | |
message = message + "\n#{hum_diff_message}" | |
end | |
# 二酸化炭素濃度 | |
if data['CO2'] > @attention_high_co2 | |
co2_diff = data['CO2'] - @high_co2 | |
co2_diff_message = "*二酸化炭素濃度が高いです* :cold_sweat:\nどなたか、換気をして二酸化炭素を *#{co2_diff}ppm* 下げてください :sob:" | |
message = message + "\n#{co2_diff_message}" | |
end | |
message | |
end | |
# アラートを通知する | |
def notify_alert(current_data) | |
data = current_data | |
state_data = "現在のオフィスの状況は\n室温 : *#{data['Temperature']}度* :wind_chime:\n湿度 : *#{data['Humidity']}%* :bath:\n二酸化炭素濃度 : *#{data['CO2']}ppm* :lips: \n気圧: *#{data['Pressure']}hPa* :airplane: \nです \n" | |
desirable_data = "\n快適な状態は\n室温 : #{@low_temp}〜#{@high_temp}度 :wind_chime:\n湿度 : #{@low_hum}〜#{@high_hum}% :bath:\n二酸化炭素濃度 : #{@low_co2}~#{@high_co2}ppm :lips:" | |
alert_message = alert_message(data) | |
post_message = "#{state_data}\n#{desirable_data}\n#{alert_message}" | |
puts post_message | |
# TODO: slack-ruby-client とか使ってもいいんだけどね | |
`curl -s https://slack.com/api/chat.postMessage -X POST -d "channel=#{@slack_config[:channel]}" -d "text=#{post_message}" -d 'username=#{@slack_config[:name]}' -d 'icon_emoji=#{@slack_config[:icon]}' -d "token=#{@slack_config[:token]}"` | |
end | |
# 今のNetatmoのデータを取ってきて | |
current_data = netatmo_data(access_token) | |
# 閾値を超えていたらSlackに通知する | |
notify_alert(current_data) if alert_message(current_data) != '' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment