Last active
November 25, 2017 09:27
-
-
Save krcummings1/d12585ca5d5e981f6e9c22d57af60ce1 to your computer and use it in GitHub Desktop.
AWS Lambda function to stream Wunderground data to Initial State
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
let https = require('https'), | |
http = require('http'); | |
const ISBucketKey = 'YOUR-BUCKET-KEY', | |
WundergroundApiKey = 'WUNDERGROUND-API-KEY', | |
WundergroundCity = 'Nashville', | |
WundergroundState = 'TN'; | |
const ISAccessKey = 'YOUR-ACCESS-KEY'; | |
exports.handler = (event, context, callback) => { | |
getWeatherData(WundergroundCity, WundergroundState, (error, data) => { | |
if (error) { | |
context.fail(); | |
} else if (!data.current_observation.observation_epoch || data.current_observation.observation_epoch < 1451606400) { | |
/* 1451606400 = January 1, 2016 */ | |
console.log("Failed due to missing epoch or epoch dated before January 1, 2016"); | |
context.fail(); | |
} else { | |
let isRequestBody = [ | |
{ | |
'key': 'Temperature (F)', | |
'value': data.current_observation.temp_f, | |
'epoch': data.current_observation.observation_epoch | |
}, | |
{ | |
'key': 'Dew Point (F)', | |
'value': data.current_observation.dewpoint_f, | |
'epoch': data.current_observation.observation_epoch | |
}, | |
{ | |
'key': 'Feels Like (F)', | |
'value': data.current_observation.feelslike_f, | |
'epoch': data.current_observation.observation_epoch | |
}, | |
{ | |
'key': 'UV', | |
'value': data.current_observation.UV, | |
'epoch': data.current_observation.observation_epoch | |
}, | |
// The next section of code is for future forecasted weather. | |
// Uncomment them if you'd like to add that data to your weather app. | |
// If you do, either keep the START and END lines commented or just delete them entirely. | |
// *** FUTURE FORECASTED WEATHER START *** | |
// { | |
// 'key': '3rd Day Forecast Max Temp (F)', | |
// 'value': data.forecast.simpleforecast.forecastday[2].high.fahrenheit, | |
// 'epoch': data.forecast.simpleforecast.forecastday[2].date.epoch | |
// }, | |
// { | |
// 'key': '3rd Day Forecast Min Temp (F)', | |
// 'value': data.forecast.simpleforecast.forecastday[2].low.fahrenheit, | |
// 'epoch': data.forecast.simpleforecast.forecastday[2].date.epoch | |
// }, | |
// { | |
// 'key': '5th Day Forecast Max Temp (F)', | |
// 'value': data.forecast.simpleforecast.forecastday[4].high.fahrenheit, | |
// 'epoch': data.forecast.simpleforecast.forecastday[4].date.epoch | |
// }, | |
// { | |
// 'key': '5th Day Forecast Min Temp (F)', | |
// 'value': data.forecast.simpleforecast.forecastday[4].low.fahrenheit, | |
// 'epoch': data.forecast.simpleforecast.forecastday[4].date.epoch | |
// }, | |
// { | |
// 'key': '10th Day Forecast Max Temp (F)', | |
// 'value': data.forecast.simpleforecast.forecastday[9].high.fahrenheit, | |
// 'epoch': data.forecast.simpleforecast.forecastday[9].date.epoch | |
// }, | |
// { | |
// 'key': '10th Day Forecast Min Temp (F)', | |
// 'value': data.forecast.simpleforecast.forecastday[9].low.fahrenheit, | |
// 'epoch': data.forecast.simpleforecast.forecastday[9].date.epoch | |
// }, | |
// *** FUTURE FORECASTED WEATHER END *** | |
{ | |
'key': 'Relative Humidity', | |
'value': data.current_observation.relative_humidity, | |
'epoch': data.current_observation.observation_epoch | |
}, | |
{ | |
'key': 'Wind Degrees', | |
'value': data.current_observation.wind_degrees, | |
'epoch': data.current_observation.observation_epoch | |
}, | |
{ | |
'key': 'Wind Direction', | |
'value': data.current_observation.wind_dir, | |
'epoch': data.current_observation.observation_epoch | |
}, | |
{ | |
'key': 'Wind Speed (MPH)', | |
'value': data.current_observation.wind_mph, | |
'epoch': data.current_observation.observation_epoch | |
}, | |
{ | |
'key': 'Wind Gust (MPH)', | |
'value': data.current_observation.wind_gust_mph, | |
'epoch': data.current_observation.observation_epoch | |
}, | |
{ | |
'key': 'Precipitation Today (in)', | |
'value': data.current_observation.precip_today_in, | |
'epoch': data.current_observation.observation_epoch | |
}, | |
{ | |
'key': 'Conditions', | |
'value': convertConditionToEmojiToken(data.current_observation.icon), | |
'epoch': data.current_observation.observation_epoch | |
}, | |
{ | |
'key': 'Heat Index (F)', | |
'value': data.current_observation.heat_index_f, | |
'epoch': data.current_observation.observation_epoch | |
}, | |
{ | |
'key': 'Moon Phase', | |
'value': convertMoonPhaseToEmojiToken(data.moon_phase.phaseofMoon), | |
"epoch": data.current_observation.observation_epoch | |
}, | |
{ | |
'key': 'Moon Illumination (%)', | |
'value': data.moon_phase.percentIlluminated, | |
"epoch": data.current_observation.observation_epoch | |
}, | |
{ | |
'key': 'Sunrise', | |
'value': data.sun_phase.sunrise.hour + ':' + data.sun_phase.sunrise.minute | |
}, | |
{ | |
'key': 'Sunset', | |
'value': data.sun_phase.sunset.hour + ':' + data.sun_phase.sunset.minute | |
} | |
]; | |
sendToInitialState(ISAccessKey, isRequestBody, callback); | |
} | |
}); | |
}; | |
function convertConditionToEmojiToken(condition) { | |
condition = condition.toLowerCase(); | |
const conditionMap = { | |
'clear' : ':sun_with_face:', | |
'cloudy' : ':cloud:', | |
'flurries' : ':snowflake:', | |
'fog' : ':foggy:', | |
'hazy' : ':foggy:', | |
'mostlycloudy' : ':cloud:', | |
'mostlysunny' : ':sun_with_face:', | |
'partlycloudy' : ':partly_sunny:', | |
'partlysunny' : ':partly_sunny:', | |
'sleet' : ':sweat_drops: :snowflake:', | |
'rain' : ':umbrella:', | |
'snow' : ':snowflake:', | |
'sunny' : ':sun_with_face:', | |
'tstorms' : ':zap: :umbrella:' | |
}; | |
if (condition in conditionMap) { | |
return conditionMap[condition]; | |
} else { | |
return ':grey_question:'; | |
} | |
} | |
function convertMoonPhaseToEmojiToken(moonPhase) { | |
moonPhase = moonPhase.toLowerCase(); | |
const moonPhaseMap = { | |
'new moon' : ':new_moon:', | |
'waxing crescent' : ':waxing_crescent_moon:', | |
'first quarter' : ':first_quarter_moon:', | |
'waxing gibbous' : ':waxing_gibbous_moon:', | |
'full moon' : ':full_moon:', | |
'full' : ':full_moon:', | |
'waning gibbous' : ':waning_gibbous_moon:', | |
'last quarter' : ':last_quarter_moon:', | |
'waning crescent' : ':waning_crescent_moon:' | |
}; | |
if (moonPhase in moonPhaseMap) { | |
return moonPhaseMap[moonPhase]; | |
} else { | |
return ':grey_question:'; | |
} | |
} | |
function getWeatherData(city, state, callback) { | |
const req = http.request({ | |
hostname: 'api.wunderground.com', | |
port: '80', | |
path: '/api/'+WundergroundApiKey+'/astronomy/conditions/forecast10day/q/'+state+'/'+city+'.json', | |
method: 'GET' | |
}, (res) => { | |
let body = ''; | |
console.log('Status:', res.statusCode); | |
console.log('Headers:', JSON.stringify(res.headers)); | |
res.setEncoding('utf8'); | |
res.on('data', (chunk) => body += chunk); | |
res.on('end', () => { | |
console.log('Successfully finished processing HTTP response'); | |
body = JSON.parse(body); | |
callback(null, body); | |
}); | |
}); | |
req.on('error', callback); | |
req.end(); | |
} | |
function sendToInitialState(accessKey, data, callback) { | |
const req = https.request({ | |
hostname: 'groker.initialstate.com', | |
port: '443', | |
path: '/api/events', | |
method: 'POST', | |
headers: { | |
'X-IS-AccessKey': accessKey, | |
'X-IS-BucketKey': ISBucketKey, | |
'Content-Type': 'application/json', | |
'Accept-Version': '~0' | |
} | |
}, (res) => { | |
let body = ''; | |
console.log('Status:', res.statusCode); | |
console.log('Headers:', JSON.stringify(res.headers)); | |
res.setEncoding('utf8'); | |
res.on('data', (chunk) => body += chunk); | |
res.on('end', () => { | |
console.log('Successfully processed HTTPS response'); | |
if (res.headers['content-type'] === 'application/json' && body && body.length > 0) { | |
body = JSON.parse(body); | |
} | |
callback(null, body); | |
}); | |
}); | |
req.on('error', callback); | |
req.end(JSON.stringify(data)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment