diff --git a/package.json b/package.json new file mode 100644 index 0000000..97e6df0 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "yargs": "^18.1.0" + } +} diff --git a/prototype.js b/prototype.js new file mode 100755 index 0000000..d4d2c67 --- /dev/null +++ b/prototype.js @@ -0,0 +1,70 @@ +#!/usr/bin/env node +// 2026-09-12 - Hyperling +/* Prototype mostly generated by Ask Brave from prompt: + * node.js script which has 8 location variables including name, lat, lon, and elevation. + * loops over the locations sending them to open-meteo requesting temperature min and max for 7 days, no hourly. + * uses units for USA such as fahrenheit, inches, mph. + * prints the location name and elevation with the average high and low for the week. + * */ +// Maybe AI is actually getting better than I thought. ;D + +const locations = [ + { name: "Flagstaff, AZ", lat: 35.1983, lon: -111.6513, elevation: 6903 }, + { name: "Tucson, AZ", lat: 32.2226, lon: -110.9747, elevation: 2490 }, + { name: "Prescott, AZ", lat: 34.5400, lon: -112.4685, elevation: 5374 }, + { name: "Frisco, CO", lat: 39.5744, lon: -106.0975, elevation: 9075 }, + { name: "Greer, AZ", lat: 34.0100, lon: -109.4587, elevation: 8356 }, + { name: "Sedona, AZ", lat: 34.8697, lon: -111.7610, elevation: 4350 }, + { name: "Ehrenberg, AZ", lat: 33.9897, lon: -114.3550, elevation: 333 }, +]; + +locations.sort((a, b) => a.elevation - b.elevation); + +const GREEN = "\x1b[32m"; +const RESET = "\x1b[0m"; + +function highlight(value, min, max) { + const n = parseFloat(value); + return (n >= min && n <= max) ? `${GREEN}${value}${RESET}` : value; +} + +async function getForecast(loc) { + const url = new URL("https://api.open-meteo.com/v1/forecast"); + url.searchParams.set("latitude", loc.lat); + url.searchParams.set("longitude", loc.lon); + url.searchParams.set("daily", "temperature_2m_max,temperature_2m_min"); + url.searchParams.set("temperature_unit", "fahrenheit"); + url.searchParams.set("precipitation_unit", "inch"); + url.searchParams.set("wind_speed_unit", "mph"); + url.searchParams.set("timezone", "auto"); + url.searchParams.set("forecast_days", "7"); + + const res = await fetch(url); + const data = await res.json(); + + const highs = data.daily.temperature_2m_max; + const lows = data.daily.temperature_2m_min; + + const avgHigh = (highs.reduce((a, b) => a + b, 0) / highs.length).toFixed(1); + const avgLow = (lows.reduce((a, b) => a + b, 0) / lows.length).toFixed(1); + + return { name: loc.name, elevation: loc.elevation, avgHigh, avgLow }; +} + +(async () => { + console.log("Location | Elev (ft) | Avg High (°F) | Avg Low (°F)"); + console.log("----------------------+-----------+---------------+------------"); + + for (const loc of locations) { + try { + const r = await getForecast(loc); + const hi = highlight(r.avgHigh, 60, 75); + const lo = highlight(r.avgLow, 40, 55); + console.log( + `${r.name.padEnd(20)} | ${String(r.elevation).padStart(9)} | ${hi.padStart(13)} | ${lo.padStart(12)}` + ); + } catch (e) { + console.log(`${loc.name}: error – ${e.message}`); + } + } +})();