Skip to content

Instantly share code, notes, and snippets.

@kenjiskywalker
Last active June 27, 2017 07:58
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save kenjiskywalker/4d5fcb9a9edf6dd754c6594d830351a4 to your computer and use it in GitHub Desktop.
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