Last active
October 4, 2018 14:35
-
-
Save joshfarrant/0b2721b20a80334cca1eca1c916a1812 to your computer and use it in GitHub Desktop.
Scriptable - Parse Forecast API data
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
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