Public
HTTP (deprecated)
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Readme

Big Weather Display

Displays the current day's weather information BIG so you can see it from far away.

Screenshot 2024-06-01 at 13.24.37@2x.png

Currently it's hardcoded for:

  • prospect heights, brooklyn
  • charts of the temp and % change of precipitation

Probably easiest for you to fork it and change it to suit your needs vs making it customizable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/** @jsxImportSource https://esm.sh/react */
import React from "https://esm.sh/react";
import { renderToString } from "https://esm.sh/react-dom/server";
import { DateTime } from "https://esm.sh/luxon";
const BROOKLYN_HOURLY_FORECAST = "https://api.weather.gov/gridpoints/OKX/35,34/forecast/hourly";
async function getHourlyWeather(day: DateTime): Promise<any[]> {
const response = await fetch(BROOKLYN_HOURLY_FORECAST);
const { properties: { periods } } = await response.json();
return periods.filter((x) =>
DateTime.fromISO(x.startTime) >= day.startOf('day') &&
DateTime.fromISO(x.startTime) < day.endOf('day')
);
}
function WeatherChart({ periods }) {
const width = 300;
const height = 150;
const maxTemp = Math.max(...periods.map(p => p.temperature));
const minTemp = Math.min(...periods.map(p => p.temperature));
return (
<svg viewBox={`0 0 ${width} ${height}`} width="100%">
{periods.map((period, i) => {
const x = (i / (periods.length - 1)) * width;
const y = height - ((period.temperature - minTemp) / (maxTemp - minTemp)) * height;
return (
<React.Fragment key={i}>
<circle cx={x} cy={y} r="3" fill="orange" />
{i % 4 === 0 && (
<text x={x} y={height - 5} textAnchor="middle" fontSize="10">
{period.startTime.slice(11, 16)}
</text>
)}
</React.Fragment>
);
})}
</svg>
);
}
async function server(req: Request): Promise<Response> {
const now = DateTime.now().setZone("America/New_York");
const periods = await getHourlyWeather(now);
return new Response(
renderToString(
<html>
<head>
<title>Brooklyn Weather</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>{`
body { font-family: sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; }
`}</style>
</head>
<body>
<h1>Brooklyn Weather Forecast</h1>
<WeatherChart periods={periods} />
<p>Data from <a href="https://www.weather.gov/">National Weather Service</a></p>
<p><a href={import.meta.url.replace("esm.town", "val.town")}>View source</a></p>
</body>
</html>
),
{
headers: { "Content-Type": "text/html" },
}
);
}
export default server;
stevekrouse-causalcyanflea.web.val.run
August 31, 2024