It is currently March 29th, 2024, 11:55 am

How to display different weather icons depending on the condition?

Get help with creating, editing & fixing problems with skins
User avatar
boozlepuzzle
Posts: 9
Joined: August 22nd, 2021, 9:08 pm
Location: Uruguay

How to display different weather icons depending on the condition?

Post by boozlepuzzle »

Hey everyone, sorry if this is a noobie question, I'm new to Rainmeter and I'm finding it hard to grasp

I have a clock, date and weather skin which shows the temperature from openweatherapi, now I want it to show an icon depending on the weather condition, I already have the images (https://i.imgur.com/qh5HGwt.png), and I already figured out how to pull the condition and clouds data with regex

What I'm lacking is how to assign different icons for different conditions, for example if weather = light rain, show icon for rain, if clouds > 75 show mostly-cloudy icon, etc

This is what I've done until now

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1

[Variables]  
Color=255,255,255,255
Font=Product Sans Bold

[MeasureTime]
Measure=Time
Format=%H:%M

[MeasureDate]
Measure=Time
Format=%A, %B %d
FormatLocale=Local

[MeasureWeatherTemp]
Measure=WebParser
URL=*api URL with key*
RegExp=(?siU)\"temp\":(.*)\,
UpdateRate=1800

[MeasureWeatherCondition]
Measure=WebParser
URL=*api URL with key*
RegExp=(?siU)\"description\":\"(.*)\"
UpdateRate=1800

[MeasureWeatherClouds]
Measure=WebParser
URL=*api URL with key*
RegExp=(?siU)\"clouds\":\{\"all\":(.*)\}
UpdateRate=1800

[MeasureTemp]
Measure=Calc
Formula= MeasureWeatherTemp

[Clock]
Meter=String
MeasureName=MeasureTime
X=100
Y=75
W=500
H=300
FontSize=57
FontFace=#Font#
AntiAlias=1
FontColor=#Color#
StringAlign=CenterCenter
InlineSetting=Shadow|2|2|3|35,35,35,110
Text="%1"

[Date]
Meter=String
MeasureName=MeasureDate
X=103
Y=128
W=350
H=200
FontSize=15
FontFace=#Font#
AntiAlias=1
FontColor=#Color#
StringAlign=CenterCenter
InlineSetting=Shadow|2|2|3|35,35,35,110

[WeatherTemp]
Meter=String
MeasureName=MeasureTemp
X=103
Y=165
W=350
H=200
FontSize=15
FontFace=#Font#
AntiAlias=1
FontColor=#Color#
Text=%1 #unitText#
StringAlign=CenterCenter
InlineSetting=Shadow|2|2|3|35,35,35,110

[Icon]
Measure=?

[Meter@CurrentIcon]
Meter=Image
ImageName=#@#WeatherIcons\[Icon].png
X=130
Y=165
W=350
H=200
DynamicVariables=1
Thanks!
Last edited by SilverAzide on August 22nd, 2021, 9:42 pm, edited 1 time in total.
Reason: Please use code tags instead of snippet. It's the </> button.
User avatar
SilverAzide
Rainmeter Sage
Posts: 2588
Joined: March 23rd, 2015, 5:26 pm

Re: How to display different weather icons depending on the condition?

Post by SilverAzide »

The problem you are going to have with this approach is you have a weather condition as a string value and a cloud condition as number value. Rainmeter measures can do string matching (IfMatch) *or* numeric expressions (IfCondition), but you can't mix them together. In other words, in Rainmeter there is no way to do something like "if condition="cloudy" and clouds > 50 then icon = xyz".

For OpenWeatherMap's API, you'd be better off sticking to pure numbers, using their ID codes, i.e., grab the condition ID value. See this page for more info: https://openweathermap.org/weather-conditions.

Once you have a known condition based on the ID, you have a few options you can use to translate the ID into an icon. The simplest thing of all is simply create a set of icons that match all the OWM IDs. For example, if the condition is 501 (moderate rain), have a "501.png" icon that you can display.

Another more efficient approach is to map the code to an icon. You could do this with a calc measure and a bunch of IfCondition's. Something like:

Code: Select all

[MeasureIcon]
Measure=Calc
Formula=(<your webparser measure that gets the ID>)
IfCondition=(MeasureIcon>=200) && (MeasureIcon<=232)
IfTrueAction=[!SetOption Meter@CurrentIcon ImageName "#@#thunderstorm.png"]
IfCondition2=(MeasureIcon>=300) && (MeasureIcon<=321)
IfTrueAction2=[!SetOption Meter@CurrentIcon ImageName "#@#drizzle.png"]
...etc...
(This approach might cause an error in the log during the brief interval when the data is being retrieved, due to the webparser measure not having any value, so you'll have to handle that at some point.)

There are lots of ways to handle this, so this is just one or two options you can try.

(P.S.: I don't mean to discourage your approach, but your very best option is to ditch OWM altogether and stick with The Weather Channel, which is way more robust. See the post Weather.com - Parsing the V3 JSON. This is a template that you can use as a basis for any weather skin, and it is way more capable than OWM -- much wider coverage, more frequent updates, and much better content. Add whichever of the template's Include files you want into your project and you are essentially done, no need to deal with parsing or anything else, and no API key either.)
Gadgets Wiki GitHub More Gadgets...
User avatar
boozlepuzzle
Posts: 9
Joined: August 22nd, 2021, 9:08 pm
Location: Uruguay

Re: How to display different weather icons depending on the condition?

Post by boozlepuzzle »

SilverAzide wrote: August 22nd, 2021, 10:24 pm The problem you are going to have with this approach is you have a weather condition as a string value and a cloud condition as number value. Rainmeter measures can do string matching (IfMatch) *or* numeric expressions (IfCondition), but you can't mix them together. In other words, in Rainmeter there is no way to do something like "if condition="cloudy" and clouds > 50 then icon = xyz".

For OpenWeatherMap's API, you'd be better off sticking to pure numbers, using their ID codes, i.e., grab the condition ID value. See this page for more info: https://openweathermap.org/weather-conditions.

Once you have a known condition based on the ID, you have a few options you can use to translate the ID into an icon. The simplest thing of all is simply create a set of icons that match all the OWM IDs. For example, if the condition is 501 (moderate rain), have a "501.png" icon that you can display.

Another more efficient approach is to map the code to an icon. You could do this with a calc measure and a bunch of IfCondition's. Something like:

Code: Select all

[MeasureIcon]
Measure=Calc
Formula=(<your webparser measure that gets the ID>)
IfCondition=(MeasureIcon>=200) && (MeasureIcon<=232)
IfTrueAction=[!SetOption Meter@CurrentIcon ImageName "#@#thunderstorm.png"]
IfCondition2=(MeasureIcon>=300) && (MeasureIcon<=321)
IfTrueAction2=[!SetOption Meter@CurrentIcon ImageName "#@#drizzle.png"]
...etc...
(This approach might cause an error in the log during the brief interval when the data is being retrieved, due to the webparser measure not having any value, so you'll have to handle that at some point.)

There are lots of ways to handle this, so this is just one or two options you can try.

(P.S.: I don't mean to discourage your approach, but your very best option is to ditch OWM altogether and stick with The Weather Channel, which is way more robust. See the post Weather.com - Parsing the V3 JSON. This is a template that you can use as a basis for any weather skin, and it is way more capable than OWM -- much wider coverage, more frequent updates, and much better content. Add whichever of the template's Include files you want into your project and you are essentially done, no need to deal with parsing or anything else, and no API key either.)
I downloaded some other skin from the internet and I saw the author used numbers for their files, now I understand why, thanks a lot for your response, that code you wrote is more than enough to point me in the right direction
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: How to display different weather icons depending on the condition?

Post by Yincognito »

SilverAzide wrote: August 22nd, 2021, 10:24 pmRainmeter measures can do string matching (IfMatch) *or* numeric expressions (IfCondition), but you can't mix them together. In other words, in Rainmeter there is no way to do something like "if condition="cloudy" and clouds > 50 then icon = xyz".
As a side note, while you can't directly do the above, there are ways to do it if you either:
- create another string measure where you concatenate the string and the number using some "separator" like space for example, and you use a suited IfMatch like ^cloudy (?:[5-9]\d|\d{3,})$ to trigger the desired actions
- use the IfMatch for the 'cloudy' string measure and then in the IfMatchAction you update a negative update divider measure that subsequently tests the numerical 'clouds' value
That being said, your advice is the best, especially considering that you can retrieve purely numerical values for both, but for cases where you can't, there are still some solutions available. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
boozlepuzzle
Posts: 9
Joined: August 22nd, 2021, 9:08 pm
Location: Uruguay

Re: How to display different weather icons depending on the condition?

Post by boozlepuzzle »

I finally did it, I'll leave it here in case it's useful to anyone in the future

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1

[Variables]  
Color=255,255,255,255
Font=Product Sans Bold
IsDay=

[MeasureTime]
Measure=Time
Format=%H:%M

[MeasureDate]
Measure=Time
Format=%A, %B %d
FormatLocale=Local

[MeasureWeatherTemp]
Measure=WebParser
URL=*api URL with location coordinates and key*
RegExp=(?siU)\"temp\":(.*)\,
UpdateRate=1800

[MeasureTempUnrounded]
Measure=WebParser
URL=[MeasureWeatherTemp]
StringIndex=1

[MeasureTemp]
Measure=Calc
Formula= ROUND(MeasureTempUnrounded)

[MeasureWeatherCode]
Measure=WebParser
URL=*api URL with location coordinates and key*
RegExp=(?siU)\[\{\"id\":(.*)\,
UpdateRate=1800

[MeasureCode]
Measure=WebParser
URL=[MeasureWeatherCode]
StringIndex=1

[MeasureWeatherSun]
Measure=WebParser
URL=*api URL with location coordinates and key*
RegExp=(?siU)\"sunrise\":(.*)\,\"sunset\":(.*)\}\,
UpdateRate=1800

[MeasureSunrise]
Measure=WebParser
URL=[MeasureWeatherSun]
StringIndex=1

[MeasureSunset]
Measure=WebParser
URL=[MeasureWeatherSun]
StringIndex=2

[MeasureUnix]
Measure=WebParser
URL=https://showcase.api.linx.twenty57.net/UnixTime/tounixtimestamp?datetime=now
RegExp=(?siU)UnixTimeStamp\":\"(.*)\"\}
UpdateRate=1800

[MeasureCurrentUnix]
Measure=WebParser
URL=[MeasureUnix]
StringIndex=1
IfCondition=(MeasureSunrise < MeasureCurrentUnix) && (MeasureCurrentUnix < MeasureSunset)
IfTrueAction=[!SetVariable IsDay "1"]
IfFalseAction=[!SetVariable IsDay "0"]

[MeasureIcon]
Measure=Calc
Formula=MeasureCode
IfCondition=(MeasureCode=800) && (#IsDay# = 1)
IfTrueAction=[!SetOption Icon ImageName "#@#WeatherIcons\clear-day.png"]
IfCondition2=(MeasureCode=800) && (#IsDay# = 0)
IfTrueAction2=[!SetOption Icon ImageName "#@#WeatherIcons\clear-night.png"]
IfCondition3=(MeasureCode=801) && (#IsDay# = 1)
IfTrueAction3=[!SetOption Icon ImageName "#@#WeatherIcons\mclear-day.png"]
IfCondition4=(MeasureCode=801)  && (#IsDay# = 0)
IfTrueAction4=[!SetOption Icon ImageName "#@#WeatherIcons\mclear-night.png"]
IfCondition5=(MeasureCode=802) && (#IsDay# = 1)
IfTrueAction5=[!SetOption Icon ImageName "#@#WeatherIcons\pcloudy-day.png"]
IfCondition6=(MeasureCode=802) && (#IsDay# = 0)
IfTrueAction6=[!SetOption Icon ImageName "#@#WeatherIcons\pcloudy-night.png"]
IfCondition7=(MeasureCode=803) && (#IsDay# = 1)
IfTrueAction7=[!SetOption Icon ImageName "#@#WeatherIcons\mcloudy-day.png"]
IfCondition8=(MeasureCode=803)  && (#IsDay# = 0)
IfTrueAction8=[!SetOption Icon ImageName "#@#WeatherIcons\mcloudy-night.png"]
IfCondition9=(MeasureCode=804)
IfTrueAction9=[!SetOption Icon ImageName "#@#WeatherIcons\cloudy.png"]
IfCondition10=(MeasureCode>=300) && (MeasureCode<=321) || (MeasureCode=500)
IfTrueAction10=[!SetOption Icon ImageName "#@#WeatherIcons\drizzle.png"]
IfCondition11=(MeasureCode>=701) && (MeasureCode<=741)
IfTrueAction11=[!SetOption Icon ImageName "#@#WeatherIcons\fog.png"]
IfCondition12=(MeasureCode>=611) && (MeasureCode<=613)
IfTrueAction12=[!SetOption Icon ImageName "#@#WeatherIcons\hail.png"]
IfCondition13=(MeasureCode>=501) && (MeasureCode<=531)
IfTrueAction13=[!SetOption Icon ImageName "#@#WeatherIcons\rain.png"]
IfCondition14=(MeasureCode>=200) && (MeasureCode<=202) && (#IsDay# = 1) || (MeasureCode>=230) && (MeasureCode<=232) && (#IsDay# = 1)
IfTrueAction14=[!SetOption Icon ImageName "#@#WeatherIcons\tshower-day.png"]
IfCondition15=(MeasureCode>=200) && (MeasureCode<=202) && (#IsDay# = 0) || (MeasureCode>=230) && (MeasureCode<=232) && (#IsDay# = 0)
IfTrueAction15=[!SetOption Icon ImageName "#@#WeatherIcons\tshower-night.png"]
IfCondition16=(MeasureCode>=210) && (MeasureCode<=221)
IfTrueAction16=[!SetOption Icon ImageName "#@#WeatherIcons\tstorm.png"]
DynamicVariables=1

[Icon]
Meter=Image
ImageName=
X=105
Y=148
W=30
H=30
DynamicVariables=1
InlineSetting=Shadow|2|2|3|35,35,35,110


[Clock]
Meter=String
MeasureName=MeasureTime
X=100
Y=75
W=500
H=300
FontSize=57
FontFace=#Font#
AntiAlias=1
FontColor=#Color#
StringAlign=CenterCenter
InlineSetting=Shadow|2|2|3|35,35,35,110
Text="%1"

[Date]
Meter=String
MeasureName=MeasureDate
X=103
Y=128
W=350
H=200
FontSize=15
FontFace=#Font#
AntiAlias=1
FontColor=#Color#
StringAlign=CenterCenter
InlineSetting=Shadow|2|2|3|35,35,35,110

[WeatherTemp]
Meter=String
MeasureName=MeasureTemp
X=85
Y=165
W=350
H=200
FontSize=15
FontFace=#Font#
AntiAlias=1
FontColor=#Color#
Text=%1°
StringAlign=CenterCenter
InlineSetting=Shadow|2|2|3|35,35,35,110
DynamicVariables=1
(If anyone wants to use it take into account the codes and regex are made for OpenWeatherAPI, and I didn't include any Snow codes because it doesn't snow here in Uruguay)

Thanks a lot to everyone for helping me, I was so lost and it looked so difficult, that when I managed to do it I was very happy and satisfied