Skip to content

Instantly share code, notes, and snippets.

@krcummings1
Last active November 25, 2017 09:27
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save krcummings1/d12585ca5d5e981f6e9c22d57af60ce1 to your computer and use it in GitHub Desktop.
Save krcummings1/d12585ca5d5e981f6e9c22d57af60ce1 to your computer and use it in GitHub Desktop.
AWS Lambda function to stream Wunderground data to Initial State
'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