Display those weather stats even though the current screen is stuck for some reason gotta figure that one out

This commit is contained in:
Lani Aung
2025-06-15 07:31:00 -07:00
parent 30043f755a
commit 4247f9371f
15 changed files with 11910 additions and 138 deletions
+32 -2
View File
@@ -1,5 +1,12 @@
@font-face {
font-family: "Material Symbols Outlined";
font-style: normal;
src: url("./fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].woff2") format("woff");
}
html, html,
body { body {
font-size: 24px;
height: 100%; height: 100%;
margin: 0; margin: 0;
overflow: hidden; overflow: hidden;
@@ -12,8 +19,8 @@ body {
font-family: Verdana, sans-serif; font-family: Verdana, sans-serif;
font-weight: bold; font-weight: bold;
height: 500px; height: 500px;
left: calc(50% - 250px); left: calc(50% - 275px);
padding: 40px; padding: 25px;
position: absolute; position: absolute;
text-shadow: #000 1px 1px, text-shadow: #000 1px 1px,
#000 -1px 1px, #000 -1px 1px,
@@ -23,9 +30,32 @@ body {
width: 500px; width: 500px;
z-index: 10; z-index: 10;
.material {
font-family: "Material Symbols Outlined";
font-weight: normal;
font-style: normal;
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
vertical-align: text-bottom;
}
@supports (-webkit-text-stroke: 1px #000) { @supports (-webkit-text-stroke: 1px #000) {
-webkit-text-stroke: 1px #000; -webkit-text-stroke: 1px #000;
-webkit-text-fill-color: #fff; -webkit-text-fill-color: #fff;
} }
#time {
font-size: 3rem;
text-align: center;
}
section header {
font-size: 1.5rem;
}
} }
} }
+15 -18
View File
@@ -15,8 +15,12 @@ export default class Weather {
constructor(latitude?: number, longitude?: number) { constructor(latitude?: number, longitude?: number) {
this.options = new WeatherOptions(latitude ?? 47.61002138071677, longitude ?? -122.17906310779568) this.options = new WeatherOptions(latitude ?? 47.61002138071677, longitude ?? -122.17906310779568)
const time = document.getElementById("time")
time.textContent = new Date().toLocaleTimeString("en-US", { hour12: false, timeStyle: "short" })
setInterval(() => time.textContent = new Date().toLocaleTimeString("en-US", { hour12: false, timeStyle: "short" }), 15000)
const me = this const me = this
setInterval(() => me.fetchWeather().then(() => me.setDisplay()), 60000) setInterval(() => me.fetchWeather().then(() => me.setDisplay()), 300000)
me.fetchWeather().then(() => me.setDisplay()) me.fetchWeather().then(() => me.setDisplay())
} }
@@ -47,7 +51,7 @@ export default class Weather {
return true return true
} else { } else {
// Weather data is updated :00, :15, :30, :45 so wait at least a minute // Weather data is updated :00, :15, :30, :45 so wait at least a minute
if (me.lastFetched.current.getMinutes() % 15 < 5) { if (me.lastFetched.current.getMinutes() % 15 >= 1 && me.lastFetched.current.getMinutes() % 15 < 6) {
const now = new Date() const now = new Date()
// Make sure data is over 5 minutes old at least // Make sure data is over 5 minutes old at least
if ((now.getTime() - me.lastFetched.current.getTime()) > 300000) { if ((now.getTime() - me.lastFetched.current.getTime()) > 300000) {
@@ -138,24 +142,17 @@ export default class Weather {
} }
private setDisplay() { private setDisplay() {
let panel = document.getElementById("weather-panel") const current = document.getElementById("current")
if (!panel) { current.innerHTML = `<header title="Temperature (feels like)"><span class="material">thermostat</span>${Math.round(this.current.temperature)} (${Math.round(this.current.feelsLike)})</header>
panel = document.createElement("main") <main>
panel.id = "weather-panel" <div><span class="material">water_drop</span> ${Math.round(this.current.humidity)}%</div>
document.body.appendChild(panel) <div><span class="material">cloud</span> ${Math.round(this.current.cloudCoverage)}%</div>
<div><span class="material">weather_mix</span> ${Math.round(this.current.precipitation)}%</div>
<div><span class="material">air</span> ${Math.round(this.current.windSpeed)} (${Math.round(this.current.windGusts)}) ${this.inCardinals(this.current.windDirection)}</div>
</main>`
} }
while (panel.firstChild) panel.removeChild(panel.firstChild) private inCardinals(direction: number): string {
this.setDisplayCurrent(panel)
}
private setDisplayCurrent(panel: HTMLElement) {
const currentSection = document.createElement("section")
currentSection.id = "current-section"
panel.appendChild(currentSection)
}
private InCardinals(direction: number): string {
if (direction > 337.5 || direction <= 22.5) return "N" if (direction > 337.5 || direction <= 22.5) return "N"
if (direction > 22.5 || direction <= 67.5) return "NE" if (direction > 22.5 || direction <= 67.5) return "NE"
if (direction > 67.5 || direction <= 112.5) return "E" if (direction > 67.5 || direction <= 112.5) return "E"
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
+6
View File
@@ -6,6 +6,12 @@
<link rel="stylesheet" href="styles.css" /> <link rel="stylesheet" href="styles.css" />
</head> </head>
<body> <body>
<main id="weather-panel">
<header id="time"></header>
<section id="current"></section>
<section id="hourly"></section>
<section id="daily"></section>
</main>
<script src="main.js"></script> <script src="main.js"></script>
</body> </body>
</html> </html>
+100 -93
View File
@@ -2319,57 +2319,79 @@ var Weather = /** @class */ (function () {
this.hourly = []; this.hourly = [];
this.daily = []; this.daily = [];
this.options = new WeatherOptions(latitude !== null && latitude !== void 0 ? latitude : 47.61002138071677, longitude !== null && longitude !== void 0 ? longitude : -122.17906310779568); this.options = new WeatherOptions(latitude !== null && latitude !== void 0 ? latitude : 47.61002138071677, longitude !== null && longitude !== void 0 ? longitude : -122.17906310779568);
var time = document.getElementById("time");
time.textContent = new Date().toLocaleTimeString("en-US", { hour12: false, timeStyle: "short" });
setInterval(function () { return time.textContent = new Date().toLocaleTimeString("en-US", { hour12: false, timeStyle: "short" }); }, 15000);
var me = this; var me = this;
setInterval(function () { return me.fetchWeather().then(function () { return me.setDisplay(); }); }, 60 * 1000); setInterval(function () { return me.fetchWeather().then(function () { return me.setDisplay(); }); }, 300000);
me.fetchWeather().then(function () { return me.setDisplay(); }); me.fetchWeather().then(function () { return me.setDisplay(); });
} }
Weather.prototype.fetchWeather = function () { Weather.prototype.fetchWeather = function () {
return __awaiter(this, void 0, void 0, function () { return __awaiter(this, void 0, void 0, function () {
var me, parameters, getData, responses, _i, responses_1, response, utcOffsetSeconds, current, hourly, daily, length_1, temperatures, precipitationTotals, precipitationProbabilities, i, length_2, maxTemperatures, minTemperatures, sunrise, sunset, maxUVs, precipitationTotals, precipitationHours, maxWindSpeeds, maxWindGusts, prominentWindDirections, i; var me, parameters, responses, _i, responses_1, response, current, hourly, daily;
return __generator(this, function (_a) { return __generator(this, function (_a) {
switch (_a.label) { switch (_a.label) {
case 0: case 0:
me = this; me = this;
parameters = __assign({}, me.options); parameters = __assign({}, me.options);
getData = false; if (!me.doFetchData(parameters))
if (!me.lastFetched) {
parameters["daily"] = me.dailyVariables;
parameters["hourly"] = me.hourlyVariables;
parameters["current"] = me.currentVariables;
me.lastFetched = new LastFetched();
getData = true;
}
else {
// Reasonable-ish timers?
if (me.lastFetched.minutesSinceCurrent() > 15) {
parameters["current"] = me.currentVariables;
me.lastFetched.current = new Date();
getData = true;
}
if (me.lastFetched.hoursSinceHourly() > 3) {
parameters["hourly"] = me.hourlyVariables;
me.lastFetched.hourly = new Date();
getData = true;
}
if (me.lastFetched.hoursSinceDaily() > 8) {
parameters["daily"] = me.dailyVariables;
me.lastFetched.daily = new Date();
getData = true;
}
}
if (!getData)
return [2 /*return*/]; return [2 /*return*/];
return [4 /*yield*/, (0,openmeteo__WEBPACK_IMPORTED_MODULE_0__.fetchWeatherApi)(me.apiUrl, parameters)]; return [4 /*yield*/, (0,openmeteo__WEBPACK_IMPORTED_MODULE_0__.fetchWeatherApi)(me.apiUrl, parameters)];
case 1: case 1:
responses = _a.sent(); responses = _a.sent();
for (_i = 0, responses_1 = responses; _i < responses_1.length; _i++) { for (_i = 0, responses_1 = responses; _i < responses_1.length; _i++) {
response = responses_1[_i]; response = responses_1[_i];
utcOffsetSeconds = response.utcOffsetSeconds();
current = response.current(); current = response.current();
hourly = response.hourly(); hourly = response.hourly();
daily = response.daily(); daily = response.daily();
if (current != null) { if (current != null)
me.current = { me.setCurrentData(current);
if (hourly != null)
me.setHourlyData(hourly);
if (daily != null)
me.setDailyData(daily);
}
return [2 /*return*/];
}
});
});
};
Weather.prototype.doFetchData = function (parameters) {
var me = this;
if (!me.lastFetched) {
parameters["daily"] = me.dailyVariables;
parameters["hourly"] = me.hourlyVariables;
parameters["current"] = me.currentVariables;
me.lastFetched = new LastFetched();
return true;
}
else {
// Weather data is updated :00, :15, :30, :45 so wait at least a minute
if (me.lastFetched.current.getMinutes() % 15 >= 1 && me.lastFetched.current.getMinutes() % 15 < 6) {
var now = new Date();
// Make sure data is over 5 minutes old at least
if ((now.getTime() - me.lastFetched.current.getTime()) > 300000) {
parameters["current"] = me.currentVariables;
me.lastFetched.current = new Date();
return true;
}
}
// Reasonable-ish timers?
if (me.lastFetched.hoursSinceHourly() > 3) {
parameters["hourly"] = me.hourlyVariables;
me.lastFetched.hourly = new Date();
return true;
}
if (me.lastFetched.hoursSinceDaily() > 8) {
parameters["daily"] = me.dailyVariables;
me.lastFetched.daily = new Date();
return true;
}
}
return false;
};
Weather.prototype.setCurrentData = function (current) {
this.current = {
time: new Date(Number(current.time()) * 1000), time: new Date(Number(current.time()) * 1000),
temperature: current.variables(0).value(), temperature: current.variables(0).value(),
humidity: current.variables(1).value(), humidity: current.variables(1).value(),
@@ -2380,37 +2402,37 @@ var Weather = /** @class */ (function () {
windDirection: current.variables(6).value(), windDirection: current.variables(6).value(),
cloudCoverage: current.variables(7).value() cloudCoverage: current.variables(7).value()
}; };
} };
if (hourly != null) { Weather.prototype.setHourlyData = function (hourly) {
length_1 = Number(hourly.timeEnd() - hourly.time()) / hourly.interval(); var length = Number(hourly.timeEnd() - hourly.time()) / hourly.interval();
temperatures = hourly.variables(0).valuesArray(); var temperatures = hourly.variables(0).valuesArray();
precipitationTotals = hourly.variables(1).valuesArray(); var precipitationTotals = hourly.variables(1).valuesArray();
precipitationProbabilities = hourly.variables(2).valuesArray(); var precipitationProbabilities = hourly.variables(2).valuesArray();
me.hourly.length = 0; this.hourly.length = 0;
for (i = 0; i < length_1; i++) { for (var i = 0; i < length; i++) {
me.hourly.push({ this.hourly.push({
time: new Date((Number(hourly.time()) + i * hourly.interval() + utcOffsetSeconds) * 1000), time: new Date((Number(hourly.time()) + i * hourly.interval()) * 1000),
temperature: temperatures[i], temperature: temperatures[i],
precipitation: precipitationTotals[i], precipitation: precipitationTotals[i],
precipitationProbability: precipitationProbabilities[i] precipitationProbability: precipitationProbabilities[i]
}); });
} }
} };
if (daily != null) { Weather.prototype.setDailyData = function (daily) {
length_2 = Number(daily.timeEnd() - daily.time()) / daily.interval(); var length = Number(daily.timeEnd() - daily.time()) / daily.interval();
maxTemperatures = daily.variables(0).valuesArray(); var maxTemperatures = daily.variables(0).valuesArray();
minTemperatures = daily.variables(1).valuesArray(); var minTemperatures = daily.variables(1).valuesArray();
sunrise = daily.variables(2); var sunrise = daily.variables(2);
sunset = daily.variables(3); var sunset = daily.variables(3);
maxUVs = daily.variables(4).valuesArray(); var maxUVs = daily.variables(4).valuesArray();
precipitationTotals = daily.variables(5).valuesArray(); var precipitationTotals = daily.variables(5).valuesArray();
precipitationHours = daily.variables(6).valuesArray(); var precipitationHours = daily.variables(6).valuesArray();
maxWindSpeeds = daily.variables(7).valuesArray(); var maxWindSpeeds = daily.variables(7).valuesArray();
maxWindGusts = daily.variables(8).valuesArray(); var maxWindGusts = daily.variables(8).valuesArray();
prominentWindDirections = daily.variables(9).valuesArray(); var prominentWindDirections = daily.variables(9).valuesArray();
me.daily.length = 0; this.daily.length = 0;
for (i = 0; i < length_2; i++) { for (var i = 0; i < length; i++) {
me.daily.push({ this.daily.push({
time: new Date((Number(daily.time()) + i * daily.interval()) * 1000), time: new Date((Number(daily.time()) + i * daily.interval()) * 1000),
maxTemperature: maxTemperatures[i], maxTemperature: maxTemperatures[i],
minTemperature: minTemperatures[i], minTemperature: minTemperatures[i],
@@ -2424,41 +2446,29 @@ var Weather = /** @class */ (function () {
prominentWindDirection: prominentWindDirections[i] prominentWindDirection: prominentWindDirections[i]
}); });
} }
}
}
return [2 /*return*/];
}
});
});
}; };
Weather.prototype.setDisplay = function () { Weather.prototype.setDisplay = function () {
var panel = document.getElementById("weather-panel"); var current = document.getElementById("current");
if (!panel) { current.innerHTML = "<header title=\"Temperature (feels like)\"><span class=\"material\">thermostat</span>".concat(Math.round(this.current.temperature), " (").concat(Math.round(this.current.feelsLike), ")</header>\n<main>\n <div><span class=\"material\">water_drop</span> ").concat(Math.round(this.current.humidity), "%</div>\n <div><span class=\"material\">cloud</span> ").concat(Math.round(this.current.cloudCoverage), "%</div>\n <div><span class=\"material\">weather_mix</span> ").concat(Math.round(this.current.precipitation), "%</div>\n <div><span class=\"material\">air</span> ").concat(Math.round(this.current.windSpeed), " (").concat(Math.round(this.current.windGusts), ") ").concat(this.inCardinals(this.current.windDirection), "</div>\n</main>");
panel = document.createElement("main");
panel.id = "weather-panel";
document.body.appendChild(panel);
}
while (panel.firstChild)
panel.removeChild(panel.firstChild);
var currentSection = document.createElement("section");
currentSection.id = "current-section";
panel.appendChild(currentSection);
this.setDisplayCurrent(currentSection);
}; };
Weather.prototype.setDisplayCurrent = function (section) { Weather.prototype.inCardinals = function (direction) {
var header = document.createElement("header"); if (direction > 337.5 || direction <= 22.5)
header.textContent = "Current"; return "N";
section.appendChild(header); if (direction > 22.5 || direction <= 67.5)
var list = document.createElement("dl"); return "NE";
for (var _i = 0, _a = Object.keys(this.current); _i < _a.length; _i++) { if (direction > 67.5 || direction <= 112.5)
var key = _a[_i]; return "E";
var term = document.createElement("dt"); if (direction > 112.5 || direction <= 157.5)
term.textContent = key; return "SE";
var value = document.createElement("dd"); if (direction > 157.5 || direction <= 202.5)
value.textContent = this.current[key]; return "S";
list.append(term, value); if (direction > 202.5 || direction <= 249.5)
} return "SW";
section.appendChild(list); if (direction > 249.5 || direction <= 294.5)
return "W";
if (direction > 294.5 || direction <= 337.5)
return "NW";
return null;
}; };
return Weather; return Weather;
}()); }());
@@ -2482,9 +2492,6 @@ var LastFetched = /** @class */ (function () {
this.hourly = new Date(); this.hourly = new Date();
this.daily = new Date(); this.daily = new Date();
} }
LastFetched.prototype.minutesSinceCurrent = function () {
return (new Date().getTime() - this.current.getTime()) / 60000;
};
LastFetched.prototype.hoursSinceHourly = function () { LastFetched.prototype.hoursSinceHourly = function () {
return (new Date().getTime() - this.hourly.getTime()) / 3600000; return (new Date().getTime() - this.hourly.getTime()) / 3600000;
}; };
+1 -1
View File
File diff suppressed because one or more lines are too long
+31 -2
View File
@@ -1,5 +1,11 @@
@font-face {
font-family: "Material Symbols Outlined";
font-style: normal;
src: url("./fonts/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].woff2") format("woff");
}
html, html,
body { body {
font-size: 24px;
height: 100%; height: 100%;
margin: 0; margin: 0;
overflow: hidden; overflow: hidden;
@@ -13,14 +19,28 @@ body #weather-panel {
font-family: Verdana, sans-serif; font-family: Verdana, sans-serif;
font-weight: bold; font-weight: bold;
height: 500px; height: 500px;
left: calc(50% - 250px); left: calc(50% - 275px);
padding: 40px; padding: 25px;
position: absolute; position: absolute;
text-shadow: #000 1px 1px, #000 -1px 1px, #000 -1px -1px, #000 1px -1px; text-shadow: #000 1px 1px, #000 -1px 1px, #000 -1px -1px, #000 1px -1px;
top: calc(50% - 250px); top: calc(50% - 250px);
width: 500px; width: 500px;
z-index: 10; z-index: 10;
} }
html #weather-panel .material,
body #weather-panel .material {
font-family: "Material Symbols Outlined";
font-weight: normal;
font-style: normal;
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
vertical-align: text-bottom;
}
@supports (-webkit-text-stroke: 1px #000) { @supports (-webkit-text-stroke: 1px #000) {
html #weather-panel, html #weather-panel,
body #weather-panel { body #weather-panel {
@@ -28,3 +48,12 @@ body #weather-panel {
-webkit-text-fill-color: #fff; -webkit-text-fill-color: #fff;
} }
} }
html #weather-panel #time,
body #weather-panel #time {
font-size: 3rem;
text-align: center;
}
html #weather-panel section header,
body #weather-panel section header {
font-size: 1.5rem;
}