agentic-os/interface/hq-dashboard/app/api/weather/route.js

78 lines
2.5 KiB
JavaScript

import { NextResponse } from 'next/server';
const ZIP = process.env.WEATHER_ZIP || '16046';
export async function GET(request) {
const { searchParams } = new URL(request.url);
const location = searchParams.get('location') || ZIP;
try {
const res = await fetch(`https://wttr.in/${encodeURIComponent(location)}?format=j1`, {
headers: { 'User-Agent': 'HQ-Dashboard/1.0' },
next: { revalidate: 900 } // cache 15 min
});
if (!res.ok) throw new Error(`wttr.in returned ${res.status}`);
const data = await res.json();
const current = data.current_condition[0];
const area = data.nearest_area[0];
const today = data.weather[0];
const tomorrow = data.weather[1];
const city = area.areaName[0].value;
const state = area.region[0].value;
// Hourly forecast for today (3 slots: morning, afternoon, evening)
const hourly = (today.hourly || []).filter((_, i) => [2, 4, 6].includes(i)).map(h => ({
time: formatHour(h.time),
tempF: h.tempF,
desc: h.weatherDesc[0].value,
chanceRain: h.chanceofrain,
}));
return NextResponse.json({
location: `${city}, ${state}`,
zip: location,
current: {
tempF: current.temp_F,
feelsLikeF: current.FeelsLikeF,
humidity: current.humidity,
windMph: current.windspeedMiles,
windDir: current.winddir16Point,
visibility: current.visibility,
uvIndex: current.uvIndex,
desc: current.weatherDesc[0].value,
cloudcover: current.cloudcover,
pressure: current.pressure,
},
today: {
maxF: today.maxtempF,
minF: today.mintempF,
sunrise: today.astronomy[0].sunrise,
sunset: today.astronomy[0].sunset,
desc: today.hourly[4]?.weatherDesc[0]?.value || '',
chanceRain: today.hourly[4]?.chanceofrain || '0',
chanceSnow: today.hourly[4]?.chanceofsnow || '0',
},
tomorrow: tomorrow ? {
maxF: tomorrow.maxtempF,
minF: tomorrow.mintempF,
desc: tomorrow.hourly[4]?.weatherDesc[0]?.value || '',
chanceRain: tomorrow.hourly[4]?.chanceofrain || '0',
} : null,
hourly,
});
} catch (err) {
return NextResponse.json({ error: err.message }, { status: 500 });
}
}
function formatHour(time) {
const h = parseInt(time) / 100;
if (h === 0) return '12 AM';
if (h < 12) return `${h} AM`;
if (h === 12) return '12 PM';
return `${h - 12} PM`;
}