Deviant Login Shop  Join deviantART for FREE Take the Tour
×



Details

Submitted on
November 2, 2011
Link
Thumb

Stats

Views
13,846 (6 today)
Favourites
16 (who?)
Comments
9
×
This is a code walkthrough of my "Do I Need a Jacket?" Rainmeter weather skin.  The goal of the skin is to replicate doineedajacket.com in a Rainmeter weather skin, including the ability of the end user to set their own temperature thresholds.  Here's a screenshot of what this skin looks like:



Download Here

The Groundwork

First, lets get the basics out of the way.  We of course need [Rainmeter], [Metadata], and [Variables] sections.

[Rainmeter]
Update=1000
Author=Flying Hyrax | flyinghyrax.deviantart.com
DynamicWindowSize=1
MouseOverAction=!Execute [!ShowMeterGroup buttons][!Redraw]
MouseLeaveAction=!Execute [!HideMeterGroup buttons][!Redraw]

[Metadata]
Name="Do I Need a Jacket?"
Version=1.0
License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0
Information=Tells you if you'll need a jacket, based on current weather information from Yahoo! Weather and threshold values which you can set. | ALL credit for idea due to www.doineedajacket.com | Variables/options consolidated in Settings.txt in skin's root folder.

You can ignore the MouseOver/LeaveAction bits in the [Rainmeter] section for now - that's not important until later.

In order to make it simple for users to edit the options for our skins, and also to make things easy on ourselves if we decide to do more than one version of the skin, we'll put the necessary variables in a separate file using include:

[Variables]
include=#CURRENTPATH#settings.txt

This directs the skin to import the contents of a file called "settings.txt" that is in the same folder as the skin itself.  For reference, here are the contents of that file:

[Variables]
loc=USWA0395
unit=f

hotTemp=80
coldTemp=60
freezeTemp=32

windLow=15
windHigh=30
windExtreme=77

color=200,200,200,200
font1=Segoe UI Light
font2=Helvetica
size1=28
size2=14

Notice the repeat of the [Variables] section header.  This is necessary because when include imports the contents of an external file, those contents are read as if they are the last thing in the skin.  If we left out the [Variables] header in settings.txt, then Rainmeter would think our variables were part of the last measure or meter in our skin.

WebParser Measures

Now, lets get on to the meat of the matter, as it were.  We'll need some WebParser measures to collect the weather data we'll be using from Yahoo! Weather.  I'm not going to explain WebParser and Regular Expressions in this walkthrough, but there are already numerous helpful resources on that.  For instance, this WebParser primer.  Anyway:

[mWeatherData]
Measure=PLUGIN
Plugin=PluginsWebParser.dll
URL=http://weather.yahooapis.com/forecastrss?p=#loc#&u=#unit#
RegExp="(?siU)<yweather:location city="(.*)".*region="(.*)".*country="(.*)".*<yweather:units temperature="(.*)".*speed="(.*)".*speed="(.*)".*<pubDate>(.*)</pubDate>.*<yweather:condition  text="(.*)".*temp="(.*)".*low="(.*)""
UpdateDivider=900
ErrorString="ixnay on the eatherway"
DecodeCharacterReference=1
ForceReload=1
Debug=0

[mCity]
Measure=Plugin
Plugin=PluginsWebParser.dll
URL=[mWeatherData]
StringIndex=1

[mRegion]
Measure=Plugin
Plugin=PluginsWebParser.dll
URL=[mWeatherData]
StringIndex=2

[mCountry]
Measure=Plugin
Plugin=PluginsWebParser.dll
URL=[mWeatherData]
StringIndex=3

[mTempUnit]
Measure=Plugin
Plugin=PluginsWebParser.dll
URL=[mWeatherData]
StringIndex=4

[mWindUnit]
Measure=Plugin
Plugin=PluginsWebParser.dll
URL=[mWeatherData]
StringIndex=5

[mWind]
Measure=Plugin
Plugin=PluginsWebParser.dll
URL=[mWeatherData]
StringIndex=6

[mDate]
Measure=Plugin
Plugin=PluginsWebParser.dll
URL=[mWeatherData]
StringIndex=7

[mCondition]
Measure=Plugin
Plugin=PluginsWebParser.dll
URL=[mWeatherData]
StringIndex=8

[mTemp]
Measure=Plugin
Plugin=PluginsWebParser.dll
URL=[mWeatherData]
StringIndex=9

Calc Measures

Now we get to the fun stuff.  First, we're going to use a CALC measure to compare the current temperature to the values in "settings.txt".  We'll make four basic ranges that the temperature can be in: Hot, warm, cold, and freezing.  The four ranges are separated by the "hotTemp", "coldTemp", and "freezeTemp" variables.  

[mCalcTemp]
Measure=CALC
Formula=#freezeTemp# > mTemp ? 3 : (#coldTemp# > mTemp ? 2 : (#hotTemp# > mTemp ? 1 : 0))

Here's what we're doing with that formula.  There are three nested If/Then statements there (see here, scroll down to "Conditional Operator").  To paraphrase: "Is mTemp (the current temperature) less then #freezeTemp#?  If yes, then return a value of 3.  If not, then is it less than #coldTemp#?  If yes..."

You get the idea.  Since we're starting at the lowest temperature threshold, we don't have to use both a greater than and a less than comparison to figure out which range the temperature is in.  If it's colder than #freezeTemp#, then it's freezing, and if it's not colder than #freezeTemp# but is colder than #coldTemp#, then it has to be in the "cold" range, and so on.

Let's move on. This skin is going to be text based.  We need a way to show a little text description of just how cold or warm it is, for humor's sake.  We'll use another Calc measure, with some Substitutes:

[mTempSubs]
Measure=CALC
Formula=mCalcTemp
Substitute="3":"darn cold out","2":"chilly out","1":"temperate","0":"positively balmy"

If we only needed this text, than we could just put the "Substitute=..." back inside [mCalcTemp].  However, we need both - we'll use the raw numbers (0-3) later on, so we need a second measure.

Now we're going to do basically the same thing, only comparing the current wind speed to the wind thresholds:

[mCalcWind]
Measure=CALC
Formula=#windLow# > mWind ? 0 : (#windHigh# > mWind ? 1 : (#windExtreme# > mWind ? 2 : (#windExtreme# <= mWind ? 3 : 4)))

[mWindSubs]
Measure=CALC
Formula=mCalcWind
Substitute="0":"not windy","1":"somewhat breezy","2":"very windy","3":"your computer just blew away"

The main difference is that [mCalcWind] has one more nested conditional operator than [mCalcTemp], and the numbers go the other way - zero first progressing to 3 instead of 3 decreasing to zero.  It could be done in either order, but it makes things easier to keep track of later when we actually determine whether or not you need a jacket.  Before we do that, we need one more bunch of conditional operators.

In English, the conjunction used between two phrases depends on the agreement or disagreement of the phrases (English majors everywhere will cringe when they read that description, but that's basically it.)  In this case, we have two phrases - one for the temperature and one for the wind.  Depending on conditions, there are several possibilities:
   1) It's cold and windy
   2) It's cold, but not windy
   3) It's warm, but windy
   4) It's warm and not windy.
Now we just need to express that in a formula:

[mCalcJunction]
Measure=CALC
Formula=(mCalcTemp > 1) && (mCalcWind > 0) ? 1 : ((mCalcTemp > 1) && (mCalcWind <= 0) ? 2 : ((mCalcTemp <= 1) && (mCalcWind > 0) ? 2 : ((mCalcTemp <= 1) && (mCalcWind <= 0) ? 1 : 0)))
Substitute="1":"and","2":"but","0":","

Notice the logical AND operator (&&), just don't confuse it with the English language and I was talking about above.  If the temperature range is greater than 1 (cold or freezing), AND the wind range is greater than 0 (breezy, windy, or a freaking hurricane), then you need a jacket because of both the temperature and the wind.  If that's not the case, then we use our nested conditional operators to move on to the next case.  Each case gets either a 1 (substituted for "and") or a 2 (substituted for "but").

Lastly, we're finally going generate an actual yes or no answer to our original question: do you need a jacket?

[mCalcYN]
Measure=CALC
Formula=(1 < mCalcTemp) || (0 < mCalcWind) ? 1 : 0
Substitute="1":"","0":" don't"

This one is simple; the "||" is a logical OR operator.  If the temperature is in the cold or freezing ranges, OR if the wind is above the "0" range (OR both), then the conditional operator evaluates to true (1), if not, it evaluates to false (0).  

Meters

...then we use a substitute so that we can plug this info into our main string meter:

[Y/N]
Meter=STRING
MeasureName=mCalcYN
FontFace=#font1#
FontSize=#size1#
FontColor=#color#
X=0
Y=0
AntiAlias=1
SolidColor=0,0,0,1
Text="You%1 need a jacket."

The "%1" in the "Text=" line is the output of the [mCalcYN] measure from above, which because of the substitute will be either nothing or the word " don't".  So the string will read either "You need a jacket" or "You don't need a jacket."

The string meter for the secondary text is bit of a beast to look at, but it's pretty simple if you break it down:

[Elaboration]
Meter=STRING
MeasureName=mTempSubs
MeasureName2=mWindSubs
MeasureName3=mCalcJunction
MeasureName4=mCondition
MeasureName5=mTemp
MeasureName6=mTempUnit
MeasureName7=mWind
MeasureName8=mWindUnit
MeasureName9=mCity
MeasureName10=mRegion
MeasureName11=mCountry
MeasureName12=mDate
FontFace=#font2#
FontSize=#size2#
FontColor=#color#
X=5
Y=43
AntiAlias=1
SolidColor=0,0,0,1
Text="It's %1, %3 %2."
ToolTipText="%9 %10 %11#CRLF#%12#CRLF#%4, %5 %6#CRLF#Wind: %7 %8"

The first three measures are used in "Text=" and come from our the temperature range substitution, wind range substitution, and the measure we used to find the right conjunction depending on the weather conditions.  Measures 4 through 12 are all for the "ToolTipText=".  This way, the user can mouse over the string and see the actual current weather data, the location that Yahoo! weather associates with the weather location code in "settings.txt," and a timestamp of the last time the weather feed data was updated.

Lastly, we're going to make three little buttons that show up when you mouse over the skin.  These image meters will open "settings.txt," refresh the skin, and open the readme file:

[Settings]
Meter=IMAGE
ImageName=set.png
SolidColor=0,0,0,1
X=0
Y=0
W=24
PreserveAspectRatio=1
AntiAlias=1
ImageTint=#color#
Group=buttons
Hidden=1
LeftMouseUpAction=!Execute ["#CURRENTPATH#settings.txt"]
ToolTipText="Open settings.txt"

[Refresh]
Meter=IMAGE
ImageName=fresh.png
SolidColor=0,0,0,1
X=5R
Y=r
W=24
PreserveAspectRatio=1
AntiAlias=1
ImageTint=#color#
Group=buttons
Hidden=1
LeftMouseUpAction=!Refresh
ToolTipText="Refresh skin"

[Help]
Meter=IMAGE
ImageName=help.png
SolidColor=0,0,0,1
X=5R
Y=r
W=24
PreserveAspectRatio=1
AntiAlias=1
ImageTint=#color#
Group=buttons
Hidden=1
LeftMouseUpAction=!Execute ["#CURRENTPATH#info.rtf"]
ToolTipText="Open ReadMe"

This was what those Mouse Actions in the [Rainmeter] section were for.  You can see that all three image meters are part of the "buttons" group and are hidden by default; but because of those Mouse Actions they will show whenever the user's mouse goes inside the skin's window.


And that's pretty much all there is to it.  As an example skin this might not be the best choice, because the skin needs several other files to work with this code: the settings.txt file, the images for the buttons, etc.  However, I though the discussion of the Calc Formulas at least might be helpful to someone, and it was fun and good practice to write this out.

- fh
Add a Comment:
 
:iconkaberton:
kaberton Featured By Owner May 26, 2013
Question. It currently says that it's hot and breezy, and that I need a jacket. Is there a way to change it so that if it's hot I never need a jacket according to the widget?
Reply
:iconflyinghyrax:
FlyingHyrax Featured By Owner May 26, 2013
The quick and easy way would be to just get rid of the "|| (0 < mCalcWind)" in [mCalcYN]. If you do that then the skin will only give a Yes
if it is Chilly or Cold. It could be fine tuned a bit more to also give Yes when it is Temperate and Windy/Extremely Windy:
Formula=((mCalcTemp > 1) || (mCalcTemp = 1 && mCalcWind > 1)) ? 1 : 0
Reply
:iconralfarios:
Ralfarios Featured By Owner Jan 3, 2013  Hobbyist General Artist
Anyone know what is Target Application for Windows Search? Please Help me..
Reply
:iconmasterq2:
MASTERQ2 Featured By Owner Sep 22, 2012  Hobbyist Interface Designer
hi :D
can you Help me in a little (rainmeter button tutorial) like for the mplayer
i have one button working but i need to know how to get many buttons working for my LCARS WInamp.
this will be my first one that i made but i need help in some codeing.. like how to link a button to a file like
WMP - iTunes - Winamp..like when i click WMP it will go to WMP then when i click iTunes it will go to iTunes and so on and
so on just like that... can you help me ? :D
Reply
:iconflyinghyrax:
FlyingHyrax Featured By Owner Sep 23, 2012
I might know, but I want to make sure that I know what you're asking...

You need to be able to change the media player being used by clicking on a button in the skin? If you are using the NowPlaying.dll plugin, then I think I might know a way. You could use the !SetOption bang to change the "PlayerName=..." value in your main NowPlaying measure.

However, I haven't worked with Rainmeter in a little while so it might be the best idea to just ask around on the forums. All the experts/gurus are over there. I'll bet they have a way to do that curved volume bar too.
Reply
:iconmasterq2:
MASTERQ2 Featured By Owner Sep 24, 2012  Hobbyist Interface Designer
i did. but after i look at so many wmp skins i decided to keep my old skin and go with a new way of making this work so i did...
i will put some more work into this one to make it so cool

thank for the reply :D
Reply
:iconplaviniss:
plaviniss Featured By Owner Feb 24, 2012
can someone help me change the font style of the elementary skin i am new at this and i am stumped
Reply
:iconflyinghyrax:
FlyingHyrax Featured By Owner Feb 28, 2012
Hi plaviniss,
I replied to the Note you sent; let me know how things work out for you.
Reply
:iconkarmat111:
karmat111 Featured By Owner Nov 2, 2011
:thumbsup:
Reply
Add a Comment: