OpenWeather Forecast

I made a weather widget using the OpenWeather API.

I was using Weather Line for my weather widget, but I saw that you need a subscription to get a “pure black” theme so I decided to make one myself, and while doing it I noticed that the weather line predictions were inaccurate at my location, so that’s a plus.

Features: it displays the weather in a graph like WeatherLine, It can be tweaked (colors, element positions, how many temps to show)

Documentation is in the script itself, but if you have a problem you can ask me directly.
You will need an OpenWeather API Key, you can get one for free at: (account needed).

One thing to note, you need to know the size in pixels that widgets have on your screen (at least the medium one, since the small one is an square) I made this on an iPhone SE (2016), so the default config is made to fit this size.

If for some reason there is something broken (I modified the file for the documentation so maybe I deleted or modified where I’m weren’t supposed to (but i don’t think really)), tell me please.
Sorry if the comments have typo’s (English is not my main language).

Thanks for such great app! :ok_hand:

PS: I made a calendar widget too (as shown in the images) and I will publish it too, but I need to document that code.

Some images:


Very nice job!
There’s a little bug in your widget param Elvis operator. You have to escape all ’ " ’ characters in the provided default json (using a backslash), otherwise the script throws an exception.

const widgetParams = JSON.parse((args.widgetParameter != null) ? args.widgetParameter : "{ \"LAT\" : \"37.32\" , \"LON\" : \"-122.03\" , \"LOC_NAME\" : \"Cupertino, US\" }")

Another minor thing: you should present the medium size option in the code, not the small one (widget.presentMedium()).

It looks perfectly fine on an iPhone 11 Pro.

I had same issue, I put a single quote round it to resolve this as another option:

const widgetParams = JSON.parse((args.widgetParameter != null) ? args.widgetParameter : '{ "LAT" : "37.32" , "LON" : "-122.03" , "LOC_NAME" : "Cupertino, US" }')

Oh Right! I forgot to scape the widget params, working on it.
Also the widget was originally made to be only 2x2 that’s why it presents in small :sweat_smile:.

You could do it this way so you don’t have to worry about escaping

const widgetParams = (args.widgetParameter != null) ? JSON.parse(args.widgetParameter) : { "LAT" : 37.32 , "LON" : -122.03 , "LOC_NAME" : "Cupertino, US" }

What would I make the Widget string look like, this:

{ “LAT” : 37.32 , “LON” : -122.03 , “LOC_NAME” : “Cupertino, US” }

ie the string you put in on the back of the widget!

1 Like

You enter it exactly as is:
{ “LAT” : 37.32 , “LON” : -122.03 , “LOC_NAME” : “Cupertino, US” }

Cool script and widget.
Is it possible to modify so the hours are shown in 24 hour format?

1 Like

Thanks for that, much appreciated.

Totally possible, Just delete the line 139:
hour = (hour > 12 ? hour - 12 : (hour == 0 ? "12a" : ((hour == 12) ? "12p" : hour)))
Midnight will be shown as “0” tho.

I will make it a boolean setting.

1 Like

It may be a good idea to add a boolean for the ability to hide the clock (I just commented out the line), since there’s a clock on every home screen anyway.

Yep, you can cut it off if you want, but it’s not intented to be a clock to show the current time, it shows the last time when the weather got updated. For example if for some reason you have no internet for a few hours, when looking it, at least you know it’s not “the current weather”, in case it starts raining outside without any warning or previous indication.

that makes sense! thank you!

I wish we could have an AQI number in there too (maybe instead of the last update time)? I don’t think AQI is available through OpenWeatherMap, but can we merge @jsnell’s AQI widget script created here?


I have no doubt that’s possible, but to be honest I don’t have intentions to do it, I like it clean and simple as it is, and using only the OpenWeather API. :thinking:

In addition to being a different API, it would be a configuration hassle because there’s no way I can find to get a purpleair station ID from lat/long. That said, you could definitely Frankenstein these two projects together if you wanted!

Hi for the cache issue you can try this:

Insert this:

await fm.downloadFileFromiCloud(fm.joinPath(cachePath, imgName))

Before this :

return Image.fromData(Data.fromFile(fm.joinPath(cachePath, imgName)))

Around line 140

(Posted on tweeter but don’t know if you see it)


Yep I saw it on twitter, I have thinking arround that, but I haven’t tested it (because I can’t :sweat_smile:), but if you are sure that works, I’ll update it.

It works I’ve tested before posting, you should also considerer the 24h patch that @bmichotte put on git, it have one line mistake, the correct one is this:

// show24Hours : true|false > false. Allow to hour 24 hour format
const show24Hours = true
// …
if (!show24Hours) {
hour = (hour > 12 ? hour - 12 : (hour == 0 ? “12a” : ((hour == 12) ? “12p” : hour)))


Thanks, I’ve updated my comment… copy-paste, I’m sure you know it :wink: