Module: PM25
- Defined in:
- lib/pm_25.rb,
lib/pm_25/version.rb
Constant Summary collapse
- API_base =
Yes, pm25.in requires a token but uses http!
'http://www.pm25.in/api/querys/'
- VERSION =
"0.0.2"
Class Method Summary collapse
-
.access_api(interface, params = {}) ⇒ Hash, Fixnum
TODO pm25.in tends to 502, need to email complaints and handle this.
-
.all_cities(token = nil) ⇒ Hash, Fixnum
Get PM 2.5 data for all cities.
-
.aqi_ranking(token = nil) ⇒ Hash, Fixnum
Get average data for all cities.
-
.available_cities(token = get_token) ⇒ Array, Fixnum
Get a list of cites providing PM 2.5 data.
-
.bing_pm25(city) ⇒ Fixnum
Get PM 2.5 from bing.com.
-
.get_config(constant_name, default_value = nil) ⇒ String
Use environment variable or the value from config at the current directory.
-
.get_default_city ⇒ String
Use environment variable PM25_IN_CITY or the value from config at the current directory.
-
.get_token ⇒ String
Use environment variable PM25_IN_TOKEN or the value from config at the current directory.
-
.just_pm25(city = get_default_city, token = nil) ⇒ Fixnum
Get PM 2.5 value for city.
-
.pm25(city = get_default_city, token = nil) ⇒ Array<Hash>
Get PM 2.5 info of all stations in the specified city.
-
.pm25_level(pm25) ⇒ Hash{Symbol: Fixnum, Symbol: String, Symbol: String, Symbol: String}
Get AQI category, meaning and action according to US standard.
Class Method Details
.access_api(interface, params = {}) ⇒ Hash, Fixnum
TODO pm25.in tends to 502, need to email complaints and handle this.
59 60 61 62 63 64 65 66 67 |
# File 'lib/pm_25.rb', line 59 def access_api(interface, params={}) params[:token] ||= get_token res = RestClient.get(API_base + interface, {params: params}) if res.code == 200 JSON.parse res.body else res.code end end |
.all_cities(token = nil) ⇒ Hash, Fixnum
Get PM 2.5 data for all cities. API frequency limit: 5 per hour.
157 158 159 |
# File 'lib/pm_25.rb', line 157 def all_cities(token=nil) access_api('all_cities.json', token: token) end |
.aqi_ranking(token = nil) ⇒ Hash, Fixnum
Get average data for all cities. (Cities are sorted by AQI.) API frequency limit: 15 per hour.
166 167 168 |
# File 'lib/pm_25.rb', line 166 def aqi_ranking(token=nil) access_api('aqi_ranking.json', token: token) end |
.available_cities(token = get_token) ⇒ Array, Fixnum
Get a list of cites providing PM 2.5 data. API frequency limit: 10 per hour.
143 144 145 146 147 148 149 150 |
# File 'lib/pm_25.rb', line 143 def available_cities(token=get_token) res = RestClient.get 'http://www.pm25.in/api/querys.json', {params: {token: token}} if res.code == 200 JSON.parse(res.body)['cities'] else res.code end end |
.bing_pm25(city) ⇒ Fixnum
Get PM 2.5 from bing.com
174 175 176 177 178 179 |
# File 'lib/pm_25.rb', line 174 def bing_pm25(city) city = URI.encode(city) bing_url = "http://cn.bing.com/search?q=#{city}+pm2.5" html = Nokogiri.parse(open(bing_url).read) html.at('#msn_pm25rt .b_xlText').content.to_i end |
.get_config(constant_name, default_value = nil) ⇒ String
Use environment variable or the value from config at the current directory. If all failed, use the default value.
22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/pm_25.rb', line 22 def get_config(constant_name, default_value=nil) if ENV[constant_name] ENV[constant_name] elsif File.exist?('config.json') open('config.json') do |f| JSON.parse(f.read)[constant_name] end else default_value end end |
.get_default_city ⇒ String
Use environment variable PM25_IN_CITY or the value from config at the current directory.
50 51 52 |
# File 'lib/pm_25.rb', line 50 def get_default_city get_config('PM25_IN_CITY') end |
.get_token ⇒ String
Use environment variable PM25_IN_TOKEN or the value from config at the current directory. If all failed, use the test token. You can apply a token at pm25.in: www.pm25.in/api_doc
41 42 43 44 |
# File 'lib/pm_25.rb', line 41 def get_token test_token= '5j1znBVAsnSf5xQyNQyq' get_config('PM25_IN_TOKEN', test_token) end |
.just_pm25(city = get_default_city, token = nil) ⇒ Fixnum
Get PM 2.5 value for city. Fallback to bing.com. Return PM 2.5 value only.
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/pm_25.rb', line 187 def just_pm25(city=get_default_city, token=nil) result = pm25(city, token) # error on pm25.in api if result.is_a? Fixnum bing_pm25(city) elsif result.include? 'error' bing_pm25(city) else publish_time = Time.parse(result[-1]['time_point']) # Data on pm25.in is too old. # According to GB 3095-2013, PM 2.5 should have hourly # average values for at least 20 hours a day. # http://hbj.shanghang.gov.cn/hjjc/gldt/201411/P020141110361645902554.pdf if Time.now - publish_time > 2.hours bing_pm25(city) else result[-1]['pm2_5'] end end end |
.pm25(city = get_default_city, token = nil) ⇒ Array<Hash>
Get PM 2.5 info of all stations in the specified city. API frequency limit: 500 per hour.
-
Chinese (e.g. 广州)
-
area code (e.g. 020)
-
Pinyin (e.g. guangzhou)
If there is ambiguity in Pinyin, use ‘shi` as postfix, for example: 泰州 is taizhoushi, and 台州 is taizhou. For more information, see www.pm25.in/ Every station includes:
-
aqi (according to CN standard)
-
area
-
pm2_5
-
pm2_5_24h (moving average)
-
position_name (station name)
-
primary_pollutant
-
quality (优、良、轻度污染、中度污染、重度污染、严重污染 according to CN standard)
-
station_code
-
time_point (publish time of air condition)
Example:
pm25('zhuhai')
[
{
"aqi"=> 82,
"area"=> "珠海",
"pm2_5"=> 31,
"pm2_5_24h"=> 60,
"position_name"=> "吉大",
"primary_pollutant"=> "颗粒物(PM2.5)",
"quality"=> "良",
"station_code"=> "1367A",
"time_point"=> "2013-03-07T19:00:00Z"
},
...
...
...
{
"aqi"=> 108,
"area"=> "珠海",
"pm2_5"=> 0,
"pm2_5_24h"=> 53,
"position_name"=> "斗门",
"primary_pollutant"=> "臭氧8小时",
"quality"=> "轻度污染",
"station_code"=> "1370A",
"time_point"=> "2013-03-07T19:00:00Z"
},
{
"aqi"=> 99,
"area"=> "珠海",
"pm2_5"=> 39,
"pm2_5_24h"=> 67,
"position_name"=> null,
"primary_pollutant"=> null,
"quality"=> "良",
"station_code"=> null,
"time_point"=> "2013-03-07T19:00:00Z"
}
]
134 135 136 |
# File 'lib/pm_25.rb', line 134 def pm25(city=get_default_city, token=nil) access_api('pm2_5.json', city: city, token: token) end |
.pm25_level(pm25) ⇒ Hash{Symbol: Fixnum, Symbol: String, Symbol: String, Symbol: String}
Get AQI category, meaning and action according to US standard.
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/pm_25.rb', line 212 def pm25_level(pm25) if pm25 <= 12 aqi_category = 'Good' aqi_meaning = 'Air quality is considered satisfactory, and air pollution poses little or no risk.' aqi_action = 'None' elsif pm25 <= 35.4 aqi_category = 'Moderate' aqi_meaning = 'Air quality is acceptable; however, for some pollutants there may be a moderate health concern for a very small number of people who are unusually sensitive to air pollution.' aqi_action = 'Unusually sensitive people should consider reducing prolonged or heavy exertion.' elsif pm25 <= 55.4 aqi_category = 'Unhealthy for sensitive Groups' aqi_meaning = 'Members of sensitive groups may experience health effects. The general public is not likely to be affected.' aqi_action = 'People with heart or lung disease, children and older adults should reduc e prolonged or heavy exertion' elsif pm25 <= 150.4 aqi_category = 'Unhealthy' aqi_meaning = 'Everyone may begin to experience health effects; members of sensitive groups may experience more serious health effects.' aqi_action = 'People with heart or lung disease, children and older adults should avoid prolonged or heavy exertion. Everyone else should reduce prolonged or heavy exertion.' elsif pm25 <= 250.4 aqi_category = 'Very Unhealthy' aqi_meaning = 'Health warnings of emergency conditions. The entire population is more likely to be affected.' aqi_action = 'People with heart or lung disease, children and older adults should avoid all physical activity outdoors. Everyone else should avoid prolonged or heavy exertion.' else aqi_category = 'Hazardous' aqi_meaning = 'Health alert: everyone may experience more serious health effects' aqi_action = 'Avoid all physical activity outdoors.' end {pm25: pm25, category: aqi_category, meaning: aqi_meaning, action: aqi_action} end |