Merge pull request #25 from AlexFullmoon/main

Added OpenWeatherMap widget.
pull/34/head
Ben Phelps 2 years ago committed by GitHub
commit dc6b172df9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,8 +1,10 @@
import Weather from "components/widgets/weather/weather";
import OpenWeatherMap from "components/widgets/openweathermap/weather";
import Resources from "components/widgets/resources/resources";
const widgetMappings = {
weather: Weather,
openweathermap: OpenWeatherMap,
resources: Resources,
};

@ -0,0 +1,7 @@
import mapIcon from "utils/owm-condition-map";
export default function Icon({ condition, timeOfDay }) {
const Icon = mapIcon(condition, timeOfDay);
return <Icon className="w-10 h-10 text-theme-800 dark:text-theme-200"></Icon>;
}

@ -0,0 +1,41 @@
import useSWR from "swr";
import { BiError } from "react-icons/bi";
import Icon from "./icon";
export default function OpenWeatherMap({ options }) {
const { data, error } = useSWR(
`/api/widgets/openweathermap?lat=${options.latitude}&lon=${options.longitude}&apiKey=${options.apiKey}&duration=${options.cache}&units=${options.units}`
);
if (error) {
return (
<div className="order-last grow flex-none flex flex-row items-center justify-end">
<BiError className="w-8 h-8 text-theme-800 dark:text-theme-200" />
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-sm">API</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">Error</span>
</div>
</div>
);
}
if (!data) {
return <div className="order-last grow flex-none flex flex-row items-center justify-end"></div>;
}
if (data.error) {
return <div className="order-last grow flex-none flex flex-row items-center justify-end"></div>;
}
return (
<div className="order-last grow flex-none flex flex-row items-center justify-end">
<Icon condition={data.weather[0].id} timeOfDay={(data.dt > data.sys.sunrise) && (data.dt < data.sys.sundown) ? "day" : "night"} />
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-sm">
{data.main.temp.toFixed(1)}&deg;
</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">{data.weather[0].description.charAt(0).toUpperCase() + data.weather[0].description.slice(1)}</span>
</div>
</div>
);
}

@ -0,0 +1,9 @@
import cachedFetch from "utils/cached-fetch";
export default async function handler(req, res) {
const { lat, lon, apiKey, duration, units } = req.query;
const api_url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${apiKey}&units=${units}`;
res.send(await cachedFetch(api_url, duration));
}

@ -5,6 +5,13 @@
apiKey: weather_api_key # get from https://www.weatherapi.com/
cache: 5 # cache time in minutes
- openweathermap:
latitude: 51.5072 # widget configuration
longitude: 0.1275
units: metric
apiKey: openweathermap_api_key # get from https://openweathermap.org/api
cache: 10 # cache time in minutes
- resources:
cpu: true
memory: true

@ -0,0 +1,413 @@
import * as Icons from "react-icons/wi";
const conditions = [
{
code: 200,
icon: {
day: Icons.WiDayStormShowers,
night: Icons.WiNightAltStormShowers,
},
},
{
code: 201,
icon: {
day: Icons.WiDayThunderstorm,
night: Icons.WiNightAltThunderstorm,
},
},
{
code: 202,
icon: {
day: Icons.WiDayThunderstorm,
night: Icons.WiNightAltThunderstorm,
},
},
{
code: 210,
icon: {
day: Icons.WiDayStormShowers,
night: Icons.WiNightAltStormShowers,
},
},
{
code: 211,
icon: {
day: Icons.WiDayThunderstorm,
night: Icons.WiNightAltThunderstorm,
},
},
{
code: 212,
icon: {
day: Icons.WiDayThunderstorm,
night: Icons.WiNightAltThunderstorm,
},
},
{
code: 221,
icon: {
day: Icons.WiDayThunderstorm,
night: Icons.WiNightAltThunderstorm,
},
},
{
code: 230,
icon: {
day: Icons.WiDayStormShowers,
night: Icons.WiNightAltStormShowers,
},
},
{
code: 231,
icon: {
day: Icons.WiDayStormShowers,
night: Icons.WiNightAltStormShowers,
},
},
{
code: 232,
icon: {
day: Icons.WiDayThunderstorm,
night: Icons.WiNightAltThunderstorm,
},
},
{
code: 300,
icon: {
day: Icons.WiDaySprinkle,
night: Icons.WiNightAltSprinkle,
},
},
{
code: 301,
icon: {
day: Icons.WiDaySprinkle,
night: Icons.WiNightAltSprinkle,
},
},
{
code: 302,
icon: {
day: Icons.WiDayRain,
night: Icons.WiNightAltRain,
},
},
{
code: 310,
icon: {
day: Icons.WiDaySprinkle,
night: Icons.WiNightAltSprinkle,
},
},
{
code: 311,
icon: {
day: Icons.WiDayRain,
night: Icons.WiNightAltRain,
},
},
{
code: 312,
icon: {
day: Icons.WiDayRain,
night: Icons.WiNightAltRain,
},
},
{
code: 313,
icon: {
day: Icons.WiDayShowers,
night: Icons.WiNightAltShowers,
},
},
{
code: 314,
icon: {
day: Icons.WiDayShowers,
night: Icons.WiNightAltShowers,
},
},
{
code: 321,
icon: {
day: Icons.WiDayShowers,
night: Icons.WiNightAltShowers,
},
},
{
code: 500,
icon: {
day: Icons.WiDayRain,
night: Icons.WiNightAltRain,
},
},
{
code: 501,
icon: {
day: Icons.WiDayRain,
night: Icons.WiNightAltRain,
},
},
{
code: 502,
icon: {
day: Icons.WiDayRain,
night: Icons.WiNightAltRain,
},
},
{
code: 503,
icon: {
day: Icons.WiDayRain,
night: Icons.WiNightAltRain,
},
},
{
code: 504,
icon: {
day: Icons.WiDayRain,
night: Icons.WiNightAltRain,
},
},
{
code: 511,
icon: {
day: Icons.WiDaySleet,
night: Icons.WiNightAltSleet,
},
},
{
code: 520,
icon: {
day: Icons.WiDayShowers,
night: Icons.WiNightAltShowers,
},
},
{
code: 521,
icon: {
day: Icons.WiDayShowers,
night: Icons.WiNightAltShowers,
},
},
{
code: 522,
icon: {
day: Icons.WiDayShowers,
night: Icons.WiNightAltShowers,
},
},
{
code: 531,
icon: {
day: Icons.WiDayShowers,
night: Icons.WiNightAltShowers,
},
},
{
code: 600,
icon: {
day: Icons.WiDaySnow,
night: Icons.WiNightAltSnow,
},
},
{
code: 601,
icon: {
day: Icons.WiDaySnow,
night: Icons.WiNightAltSnow,
},
},
{
code: 602,
icon: {
day: Icons.WiDaySnow,
night: Icons.WiNightAltSnow,
},
},
{
code: 611,
icon: {
day: Icons.WiDaySleet,
night: Icons.WiNightAltSleet,
},
},
{
code: 612,
icon: {
day: Icons.WiDaySleet,
night: Icons.WiNightAltSleet,
},
},
{
code: 613,
icon: {
day: Icons.WiDaySleet,
night: Icons.WiNightAltSleet,
},
},
{
code: 615,
icon: {
day: Icons.WiDayRainMix,
night: Icons.WiNightAltRainMix,
},
},
{
code: 616,
icon: {
day: Icons.WiDayRainMix,
night: Icons.WiNightAltRainMix,
},
},
{
code: 620,
icon: {
day: Icons.WiDaySnow,
night: Icons.WiNightAltSnow,
},
},
{
code: 621,
icon: {
day: Icons.WiDaySnow,
night: Icons.WiNightAltSnow,
},
},
{
code: 622,
icon: {
day: Icons.WiDaySnow,
night: Icons.WiNightAltSnow,
},
},
{
code: 701,
icon: {
day: Icons.WiDayFog,
night: Icons.WiNightFog,
},
},
{
code: 711,
icon: {
day: Icons.WiSmoke,
night: Icons.WiSmoke,
},
},
{
code: 721,
icon: {
day: Icons.WiDayHaze,
night: Icons.WiWindy,
},
},
{
code: 731,
icon: {
day: Icons.WiDust,
night: Icons.WiDust,
},
},
{
code: 741,
icon: {
day: Icons.WiDayFog,
night: Icons.WiNightFog,
},
},
{
code: 751,
icon: {
day: Icons.WiDust,
night: Icons.WiDust,
},
},
{
code: 761,
icon: {
day: Icons.WiSandstorm,
night: Icons.WiSandstorm,
},
},
{
code: 762,
icon: {
day: Icons.WiDust,
night: Icons.WiDust,
},
},
{
code: 771,
icon: {
day: Icons.WiStrongWind,
night: Icons.WiStrongWind,
},
},
{
code: 781,
icon: {
day: Icons.WiTornado,
night: Icons.WiTornado,
},
},
{
code: 800,
icon: {
day: Icons.WiDaySunny,
night: Icons.WiNightClear,
},
},
{
code: 801,
icon: {
day: Icons.WiDayCloudy,
night: Icons.WiNightAltCloudy,
},
},
{
code: 802,
icon: {
day: Icons.WiDayCloudy,
night: Icons.WiNightAltCloudy,
},
},
{
code: 803,
icon: {
day: Icons.WiDayCloudy,
night: Icons.WiNightAltCloudy,
},
},
{
code: 804,
icon: {
day: Icons.WiCloudy,
night: Icons.WiCloudy,
},
},
];
export default function mapIcon(weatherStatusCode, timeOfDay) {
const mapping = conditions.find(
(condition) => condition.code === weatherStatusCode
);
if (mapping) {
if (timeOfDay === "day") {
return mapping.icon.day;
} else if (timeOfDay === "night") {
return mapping.icon.night;
}
}
return Icons.WiDaySunny;
}
Loading…
Cancel
Save