Skip to content

Instantly share code, notes, and snippets.

@joshfarrant
Last active October 4, 2018 14:35
Show Gist options
  • Save joshfarrant/0b2721b20a80334cca1eca1c916a1812 to your computer and use it in GitHub Desktop.
Save joshfarrant/0b2721b20a80334cca1eca1c916a1812 to your computer and use it in GitHub Desktop.
Scriptable - Parse Forecast API data
const params = URLScheme.allParameters();
const baseUrl = params['x-success'];
const data = JSON.parse(params.data);
const maxInt = Number.MAX_SAFE_INTEGER;
// Rough precipitation descriptions
const precipDescriptions = [
{
mmPerHour: 0.05,
description: 'very light',
}, {
mmPerHour: 0.43,
description: 'light',
}, {
mmPerHour: 2.54,
description: 'moderate',
}, {
mmPerHour: 10.16,
description: 'heavy',
}, {
mmPerHour: 20.00,
description: 'very heavy',
}, {
mmPerHour: maxInt,
description: 'extremely heavy (like seriously dude you need to start building a fucking ark)',
},
];
// Rough cloud cover descriptions
const cloudCoverDescriptions = [
{
coverage: 0.1,
description: 'clear',
}, {
coverage: 0.4,
description: 'a little cloudy',
}, {
coverage: 0.7,
description: 'quite cloudy',
}, {
coverage: 0.9,
description: 'very cloudy',
}, {
coverage: 1,
description: 'overcast',
},
];
// Based on Beaufort Scale
const windSpeedDescriptions = [
{
metresPerSecond: 0.5,
number: 0,
description: 'no wind',
}, {
metresPerSecond: 1.5,
number: 1,
description: 'light air',
}, {
metresPerSecond: 3.3,
number: 2,
description: 'a light breeze',
}, {
metresPerSecond: 5.5,
number: 3,
description: 'a gentle breeze',
}, {
metresPerSecond: 7.9,
number: 4,
description: 'a moderate breeze',
}, {
metresPerSecond: 10.7,
number: 5,
description: 'a fresh breeze',
}, {
metresPerSecond: 13.8,
number: 6,
description: 'a strong breeze',
}, {
metresPerSecond: 17.1,
number: 7,
description: 'near gale-force winds',
}, {
metresPerSecond: 20.7,
number: 8,
description: 'gale-force winds',
}, {
metresPerSecond: 24.4,
number: 9,
description: 'strong gale-force winds',
}, {
metresPerSecond: 28.4,
number: 10,
description: 'storm-force winds',
}, {
metresPerSecond: 32.6,
number: 11,
description: 'violent storm-force winds',
}, {
metresPerSecond: maxInt,
number: 12,
description: 'hurricane-force winds',
},
];
// Map bearing to Cardinal direction
const windBearings = [
{
bearingStart: 337.5,
bearingEnd: 22.5,
description: 'North'
}, {
bearingStart: 22.5,
bearingEnd: 67.5,
description: 'North-East'
}, {
bearingStart: 67.5,
bearingEnd: 112.5,
description: 'East'
}, {
bearingStart: 112.5,
bearingEnd: 157.5,
description: 'South-East'
}, {
bearingStart: 157.5,
bearingEnd: 202.5,
description: 'South'
}, {
bearingStart: 202.5,
bearingEnd: 247.5,
description: 'South-West'
}, {
bearingStart: 247.5,
bearingEnd: 292.5,
description: 'West'
}, {
bearingStart: 292.5,
bearingEnd: 337.5,
description: 'North-West'
},
];
const {
apparentTemperature,
cloudCover,
precipIntensity,
precipProbability,
precipType,
windBearing,
windSpeed,
windGust,
} = data.currently;
const roundedTemperature = Math.round(apparentTemperature);
// Start our response with the temperature
let response = `${roundedTemperature} degrees`;
// If it's going to precipitate
if (precipProbability > 0) {
// Calculate the percantage chance of precipitation
const precipPercent = precipProbability * 100;
// Find the appropriate description for this rate of precipitation
const precipDescription = precipDescriptions.find(({ mmPerHour }) => (
precipIntensity < mmPerHour
)).description;
// Append to our response
response += `, with a ${precipPercent}% chance of ${precipDescription} ${precipType}`;
} else {
// No precipitation forecast, let's get some cloud info instead.
const cloudCoverDescription = cloudCoverDescriptions.find(({ coverage }) => (
cloudCover < coverage
)).description;
response += ` and ${cloudCoverDescription}`;
}
response += '. ';
// Find the wind speed description object
const windSpeedObj = windSpeedDescriptions.find(({ metresPerSecond }) => (
windSpeed < metresPerSecond
));
// Find the wind gust description object
const windGustObj = windSpeedDescriptions.find(({ metresPerSecond }) => (
windGust < metresPerSecond
));
// Find the wind bearing description object
const windBearingObj = windBearings.find(({
bearingStart,
bearingEnd,
}) => {
// If we're near North
if (bearingStart > bearingEnd) {
return (
(windBearing >= 0 && windBearing <= bearingEnd)
|| (windBearing <= 360 && windBearing >= bearingStart)
);
} else {
return (
windBearing >= bearingStart
&& windBearing <= bearingEnd
);
}
});
// Add our wind info
response += `There's ${windSpeedObj.description} from the ${windBearingObj.description}`;
// If there's a notable gust
if (
windGustObj.number > windSpeedObj.number
&& windGustObj.number >= 6
) {
response += `, gusting to ${windGustObj.description}`;
}
response += '.';
response = encodeURI(response);
const callbackUrl = `${params['x-success']}?text=${response}`;
Safari.open(callbackUrl)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment