It is currently June 24th, 2019, 8:23 pm

Weather Skin Tutorial

Our most popular Tips and Tricks from the Rainmeter Team and others
User avatar
jsmorley
Developer
Posts: 19268
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Weather Skin Tutorial

jsmorley » April 19th, 2016, 9:35 pm

What with the recent instability of the RSS feed for Yahoo! Weather, I thought I might offer some tips on how you can create a weather skin from scratch, using the WXData feed from Weather.com. This is NOT a tutorial on how to "change" your existing Yahoo! Weather skins to use a different feed, but I will say that if you wrap your head around how to create a simple weather skin with WXData, it will be a big help if and when you want to do so.

Don't like Regular Expression? No problem, let me do that for you

Probably the most complicated part of creating a weather skin is figuring out the RegExp option for WebParser, the Regular Expression needed to "parse" the feed, capturing and returning the values you want. If you wanted to use pretty much all the information from a six-day WXData weather feed, that would be somewhere around 180 bits of data to parse. The RegExp is going to be huge and complicated, and you can only parse up to 99 StringIndex numbers in a WebParser measure anyway.

So what I have done is create an @Include file, that you simply include with your skin, that has done all this work for you. Better yet, I use an approach where you don't have to count some huge number of (.*) "captures" in the RegExp to see which StringIndex to use. We will get to that in a second.

First though, let's get started...

What URL should we use for the WXData feed?

First we need to set up some [Variables] with some personalized information for our feed.

I like to create an @Include file, I call mine WXDataWeatherVars.inc, and put it in @Resources.

WXDataWeatherVars.inc:

Code: Select all

[Variables]
; LocationCode can be obtained at http://wxdata.weather.com/wxdata/search/search?where=YourCityName
LocationCode=USVA0944
; UnitOfMeasure can be "f" (Fahrenheit / Imperial) or "m" (Celsius / Metric)
UnitOfMeasure=f
; Number of days to return in the feed.(1-6).
; The feed will always return the current conditions and the forecast for "Today"
; Then up to 5 additional forecast days. (Day 1 - Day 5)
DaysFeed=6
; Locale (language) to use in the feed.
; https://msdn.microsoft.com/en-us/goglobal/bb896001.aspx
; Note that Weather.com uses "_" underline instead of "-" dash in the codes.
Locale=en_US
Then just use a URL like this:

Code: Select all

URL=http://wxdata.weather.com/wxdata/weather/local/#LocationCode#?cc=*&unit=#UnitOfMeasure#&dayf=#DaysFeed#&locale=#Locale#
Using a "Super Parent" in WebParser

Here is the start of our example skin:

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Variables]
@IncludeVars=#@#WXDataWeatherVars.inc
@IncludeRegExp=#@#WXDataWeatherRegExp.inc

; Get the entire feed as a "super parent"

[WeatherParent]
Measure=Plugin
Plugin=WebParser
URL=http://wxdata.weather.com/wxdata/weather/local/#LocationCode#?cc=*&unit=#UnitOfMeasure#&dayf=#DaysFeed#&locale=#Locale#
RegExp=(?siU)^(.*)$
FinishAction=[!EnableMeasureGroup Weather]
As you can see, I am getting the entire feed ^(.*)$ as a single string in the value for [WeatherParent]. That is going to be our "Super Parent". Let's talk about that now.

I'm using a capability of WebParser, where you can have a "parent" measure use the value of another "parent" measure as the URL option instead of a link to some website. Just set URL=[SomeMeasure] and instead of using StringIndex like you would on a "child" measure, use a RegExp instead. So instead of just asking the "parent", in this case the "super parent", for a single bit of information based on a StringIndex, you will actually "parse" the parent measure's data.

But wait a minute, I still don't like Regular Expression!

That is where the second @Include file we add to the skin, called WXDataWeatherRegExp.inc, comes in. I have created separate RegExp options in this file, one for each of the logical sections of the WXData feed. You just have to get that "super parent" with the entire feed, then create "parent" measures that use one of the included RegExp options. Best way to explain this is to demonstrate.

First, the WXDataWeatherRegExp.inc file:

Code: Select all

; Do NOT change this file unless you are sure you know what you are doing.
; ========================================================================
[Variables]
UnitsOfMeasure=(?siU)<head>.*<locale>(.*)</locale>.*<form>(.*)</form>.*<ut>(.*)</ut>.*<ud>(.*)</ud>.*<us>(.*)</us>.*<up>(.*)</up>.*<ur>(.*)</ur>.*</head>
Location=(?siU)<loc id="(.*)".*<dnam>(.*)</dnam>.*<tm>(.*)</tm>.*<lat>(.*)</lat>.*<lon>(.*)</lon>.*<sunr>(.*)</sunr>.*<suns>(.*)</suns>.*<zone>(.*)</zone>.*</loc>
CurrentConditions=(?siU)<cc>.*<lsup>(.*)</lsup>.*<obst>(.*)</obst>.*<tmp>(.*)</tmp>.*<flik>(.*)</flik>.*<t>(.*)</t>.*<icon>(.*)</icon>
CurrentBarometric=(?siU)<cc>.*<bar>.*<r>(.*)</r>.*<d>(.*)</d>.*</bar>
CurrentWind=(?siU)<cc>.*<wind>.*<s>(.*)</s>.*<gust>(.*)</gust>.*<d>(.*)</d>.*<t>(.*)</t>.*</wind>
CurrentElements=(?siU)<cc>.*<hmid>(.*)</hmid>.*<vis>(.*)</vis>.*<uv>.*<i>(.*)</i>.*<t>(.*)</t>.*</uv>.*<dewp>(.*)</dewp>.*<moon>.*<icon>(.*)</icon>.*<t>(.*)</t>.*</moon>.*</cc>
TodayGeneral=(?siU)<dayf>.*<lsup>(.*)</lsup>.*<day d="0".*t="(.*)".*dt="(.*)".*<hi>(.*)</hi>.*<low>(.*)</low>.*<sunr>(.*)</sunr>.*<suns>(.*)</suns>
TodayDayConditions=(?siU)<day d="0".*<part p="d">.*<icon>(.*)</icon>.*<t>(.*)</t>.*</part>
TodayDayWind=(?siU)<day d="0".*<part p="d">.*<wind>.*<s>(.*)</s>.*<gust>(.*)</gust>.*<d>(.*)</d>.*<t>(.*)</t>.*</wind>.*</part>
TodayDayElements=(?siU)<day d="0".*<part p="d">.*<bt>(.*)</bt>.*<ppcp>(.*)</ppcp>.*<hmid>(.*)</hmid>.*</part>
TodayNightConditions=(?siU)<day d="0".*<part p="n">.*<icon>(.*)</icon>.*<t>(.*)</t>.*</part>
TodayNightWind=(?siU)<day d="0".*<part p="n">.*<wind>.*<s>(.*)</s>.*<gust>(.*)</gust>.*<d>(.*)</d>.*<t>(.*)</t>.*</wind>.*</part>
TodayNightElements=(?siU)<day d="0".*<part p="n">.*<bt>(.*)</bt>.*<ppcp>(.*)</ppcp>.*<hmid>(.*)</hmid>.*</part>
Day1General=(?siU)<day d="1".*t="(.*)".*dt="(.*)".*<hi>(.*)</hi>.*<low>(.*)</low>.*<sunr>(.*)</sunr>.*<suns>(.*)</suns>
Day1DayConditions=(?siU)<day d="1".*<part p="d">.*<icon>(.*)</icon>.*<t>(.*)</t>
Day1DayWind=(?siU)<day d="1".*<part p="d">.*<wind>.*<s>(.*)</s>.*<gust>(.*)</gust>.*<d>(.*)</d>.*<t>(.*)</t>.*</wind>
Day1DayElements=(?siU)<day d="1".*<part p="d">.*<bt>(.*)</bt>.*<ppcp>(.*)</ppcp>.*<hmid>(.*)</hmid>.*</part>
Day1NightConditions=(?siU)<day d="1".*<part p="n">.*<icon>(.*)</icon>.*<t>(.*)</t>
Day1NightWind=(?siU)<day d="1".*<part p="n">.*<wind>.*<s>(.*)</s>.*<gust>(.*)</gust>.*<d>(.*)</d>.*<t>(.*)</t>.*</wind>
Day1NightElements=(?siU)<day d="1".*<part p="n">.*<bt>(.*)</bt>.*<ppcp>(.*)</ppcp>.*<hmid>(.*)</hmid>.*</part>
Day2General=(?siU)<day d="2".*t="(.*)".*dt="(.*)".*<hi>(.*)</hi>.*<low>(.*)</low>.*<sunr>(.*)</sunr>.*<suns>(.*)</suns>
Day2DayConditions=(?siU)<day d="2".*<part p="d">.*<icon>(.*)</icon>.*<t>(.*)</t>
Day2DayWind=(?siU)<day d="2".*<part p="d">.*<wind>.*<s>(.*)</s>.*<gust>(.*)</gust>.*<d>(.*)</d>.*<t>(.*)</t>.*</wind>
Day2DayElements=(?siU)<day d="2".*<part p="d">.*<bt>(.*)</bt>.*<ppcp>(.*)</ppcp>.*<hmid>(.*)</hmid>.*</part>
Day2NightConditions=(?siU)<day d="2".*<part p="n">.*<icon>(.*)</icon>.*<t>(.*)</t>
Day2NightWind=(?siU)<day d="2".*<part p="n">.*<wind>.*<s>(.*)</s>.*<gust>(.*)</gust>.*<d>(.*)</d>.*<t>(.*)</t>.*</wind>
Day2NightElements=(?siU)<day d="2".*<part p="n">.*<bt>(.*)</bt>.*<ppcp>(.*)</ppcp>.*<hmid>(.*)</hmid>.*</part>
Day3General=(?siU)<day d="3".*t="(.*)".*dt="(.*)".*<hi>(.*)</hi>.*<low>(.*)</low>.*<sunr>(.*)</sunr>.*<suns>(.*)</suns>
Day3DayConditions=(?siU)<day d="3".*<part p="d">.*<icon>(.*)</icon>.*<t>(.*)</t>
Day3DayWind=(?siU)<day d="3".*<part p="d">.*<wind>.*<s>(.*)</s>.*<gust>(.*)</gust>.*<d>(.*)</d>.*<t>(.*)</t>.*</wind>
Day3DayElements=(?siU)<day d="3".*<part p="d">.*<bt>(.*)</bt>.*<ppcp>(.*)</ppcp>.*<hmid>(.*)</hmid>.*</part>
Day3NightConditions=(?siU)<day d="3".*<part p="n">.*<icon>(.*)</icon>.*<t>(.*)</t>
Day3NightWind=(?siU)<day d="3".*<part p="n">.*<wind>.*<s>(.*)</s>.*<gust>(.*)</gust>.*<d>(.*)</d>.*<t>(.*)</t>.*</wind>
Day3NightElements=(?siU)<day d="3".*<part p="n">.*<bt>(.*)</bt>.*<ppcp>(.*)</ppcp>.*<hmid>(.*)</hmid>.*</part>
Day4General=(?siU)<day d="4".*t="(.*)".*dt="(.*)".*<hi>(.*)</hi>.*<low>(.*)</low>.*<sunr>(.*)</sunr>.*<suns>(.*)</suns>
Day4DayConditions=(?siU)<day d="4".*<part p="d">.*<icon>(.*)</icon>.*<t>(.*)</t>
Day4DayWind=(?siU)<day d="4".*<part p="d">.*<wind>.*<s>(.*)</s>.*<gust>(.*)</gust>.*<d>(.*)</d>.*<t>(.*)</t>.*</wind>
Day4DayElements=(?siU)<day d="4".*<part p="d">.*<bt>(.*)</bt>.*<ppcp>(.*)</ppcp>.*<hmid>(.*)</hmid>.*</part>
Day4NightConditions=(?siU)<day d="4".*<part p="n">.*<icon>(.*)</icon>.*<t>(.*)</t>
Day4NightWind=(?siU)<day d="4".*<part p="n">.*<wind>.*<s>(.*)</s>.*<gust>(.*)</gust>.*<d>(.*)</d>.*<t>(.*)</t>.*</wind>
Day4NightElements=(?siU)<day d="4".*<part p="n">.*<bt>(.*)</bt>.*<ppcp>(.*)</ppcp>.*<hmid>(.*)</hmid>.*</part>
Day5General=(?siU)<day d="5".*t="(.*)".*dt="(.*)".*<hi>(.*)</hi>.*<low>(.*)</low>.*<sunr>(.*)</sunr>.*<suns>(.*)</suns>
Day5DayConditions=(?siU)<day d="5".*<part p="d">.*<icon>(.*)</icon>.*<t>(.*)</t>
Day5DayWind=(?siU)<day d="5".*<part p="d">.*<wind>.*<s>(.*)</s>.*<gust>(.*)</gust>.*<d>(.*)</d>.*<t>(.*)</t>.*</wind>
Day5DayElements=(?siU)<day d="5".*<part p="d">.*<bt>(.*)</bt>.*<ppcp>(.*)</ppcp>.*<hmid>(.*)</hmid>.*</part>
Day5NightConditions=(?siU)<day d="5".*<part p="n">.*<icon>(.*)</icon>.*<t>(.*)</t>
Day5NightWind=(?siU)<day d="5".*<part p="n">.*<wind>.*<s>(.*)</s>.*<gust>(.*)</gust>.*<d>(.*)</d>.*<t>(.*)</t>.*</wind>
Day5NightElements=(?siU)<day d="5".*<part p="n">.*<bt>(.*)</bt>.*<ppcp>(.*)</ppcp>.*<hmid>(.*)</hmid>.*</part>
So if you want some bit of information from for instance the part of the feed near the top that returns the "units of measure" used in the feed, you would simply crate a parent measure, using the "super parent" as the source, and the variable #UnitsOfMeasure# as the RegExp. Then you create "child" measures to get the individual bits of information from this section.

Those RegExp variables are kinda hard to understand! What does <dnam> mean?

Yeah, I have some help for that as well...

WXDataCheatSheet.txt:

Code: Select all

=======================================================================================
Example URL
http://wxdata.weather.com/wxdata/weather/local/USVA0944?cc=*&unit=f&dayf=6&locale=en_US
=======================================================================================

RegExp=#UnitsOfMeasure#
=======================
StringIndex=1	<locale>(.*)</locale>		Locale the feed is using - Example: "en_US"
StringIndex=2	<form>(.*)</form>				Form factor feed is using - Example: "MEDIUM"
StringIndex=3	<ut>(.*)</ut>						Unit of measure for temperature - Example "F"
StringIndex=4	<ud>(.*)</ud>						Unit of measure for distance - Example "mi"
StringIndex=5	<us>(.*)</us>						Unit of measure for speed - Example: "mph"
StringIndex=6	<up>(.*)</up>						Unit of measure for barometric pressure - Example: "in"
StringIndex=7	<ur>(.*)</ur>						Unit of measure for precipitation amount - Example: "in"

RegExp=#Location#
=================
StringIndex=1	<locid="(.*)"						Location ID the feed is using - Example: "USVA0944"
StringIndex=2	<dnam>(.*)</dnam>				Location name the feed is using - Example: "Fort Hunt, VA"
StringIndex=3	<tm>(.*)</tm>						Current time at the location - Example: "11:08 AM"
StringIndex=4	<lat>(.*)</lat>					Latitude of the location - Example: "38.73"
StringIndex=5	<lon>(.*)</lon>					Longitude of the location - Example: "-77.06"
StringIndex=6	<sunr>(.*)</sunr>				Time for sunrise for current day - Example: "6:25 AM"
StringIndex=7	<suns>(.*)</suns>				Time for sunset for current day - Example: "7:50 PM"
StringIndex=8	<zone>(.*)</zone>				Timezone offset from UTC for the location - Example: "-4"

RegExp=#CurrentConditions#
==========================
StringIndex=1	<lsup>(.*)</lsup>				Date and time of the observation - Example: "4/19/16 10:45 AM EDT"
StringIndex=2	<obst>(.*)</obst>				Name of the station making the observation - "Example: "Fort Belvoir, VA, US"
StringIndex=3	<tmp>(.*)</tmp>					Current temperature in degrees - Example: "80"
StringIndex=4	<flik>(.*)</flik>				Current "feels like" temperature in degrees - Example: "79"
StringIndex=5	<t>(.*)</t>							Text of current conditions - Example: "Partly Cloudy"
StringIndex=6	<icon>(.*)</icon>				Icon number for current conditions - Example: "32"

RegExp=#CurrentBarometric#
==========================
StringIndex=1	<r>(.*)</r>							Current pressure reading - Example: "30.06"
StringIndex=2	<d>(.*)</d>							Current direction of pressure "change" - Example: "rising"

RegExp=#CurrentWind#
====================
StringIndex=1	<s>(.*)</s>							Current wind speed - Example: "6" (or "calm")
StringIndex=2	<gust>(.*)</gust>				Current wind gust speed - Example: "10" (or "N/A")
StringIndex=3	<d>(.*)</d>							Current wind direction in compass degrees - Example: "330"
StringIndex=4	<t>(.*)</t>							Current wind direction compass text - Example: "NW"

RegExp=#CurrentElements#
========================
StringIndex=1	<hmid>(.*)</hmid>				Current humidity in percent - Example: "20"
StringIndex=2	<vis>(.*)</vis>					Current visibility distance - Example: "10.0"
StringIndex=3	<i>(.*)</i>							Current UV index number - Example: "5"
StringIndex=4	<t>(.*)</t>							Current UV index text - Example: "Moderate"
StringIndex=5	<dewp>(.*)</dewp>				Current dewpoint in degrees - Example: "36"
StringIndex=6	<icon>(.*)</icon>				Current moon phase icon number - Example: "12"
StringIndex=7	<t>(.*)</t>							Current moon phase text - Example: "Waxing Gibbous"

RegExp=#TodayGeneral#
=====================
StringIndex=1	<lsup>(.*)</lsup>				Date and time of the observation - Example: "4/19/16 10:45 AM EDT"
StringIndex=2	t="(.*)"								Day of the week text - Example: "Tuesday"
StringIndex=3	dt="(.*)"								Month and day text - Example: "Apr 19"
StringIndex=4	<hi>(.*)</hi>						Forecast high temperature in degrees - Example: "81"
StringIndex=5	<low>(.*)</low>					Forecast low temperature in degrees - Example: "45"
StringIndex=6	<sunr>(.*)</sunr>				Time for sunrise for current day - Example: "6:25 AM"
StringIndex=7	<suns>(.*)</suns>				Time for sunset for current day - Example: "7:50 PM"

=====================================================================================================
Note: At some time in the afternoon, all "day" values for "today" will become "", or an empty string.
This is because there can't logically be a "forecast" for a time that has passed.
Test with IFMatch and use "night" values if "day" values are not found.
=====================================================================================================

RegExp=#TodayDayConditions#
===========================
StringIndex=1	<icon>(.*)</icon>				Icon number for today "day" forecast conditions - Example: "32"
StringIndex=2	<t>(.*)</t>							Text of today "day" forecast conditions - Example: "Partly Cloudy"

RegExp=#TodayDayWind#
=====================
StringIndex=1	<s>(.*)</s>							Forecast for today "day" wind speed - Example: "6" (or "calm")
StringIndex=2	<gust>(.*)</gust>				Forecast for today "day" wind gust speed - Example: "10" (or "N/A")
StringIndex=3	<d>(.*)</d>							Forecast for today "day" wind direction in compass degrees - Example: "330"
StringIndex=4	<t>(.*)</t>							Forecast for today "day" wind direction compass text - Example: "NW"

RegExp=#TodayDayElements#
=========================
StringIndex=1	<bt>(.*)</bt>						Short text of today "day" forecast conditions - Example: "P Cloudy"
StringIndex=2	<ppcp>(.*)</ppcp>				Forecast for today "day" precipitation in percent - Example: "10"				
StringIndex=3	<hmid>(.*)</hmid>				Forecast for today "day" humidity in percent - Example: "20"

RegExp=#TodayNightConditions#
=============================
StringIndex=1	<icon>(.*)</icon>				Icon number for today "night" forecast conditions - Example: "32"
StringIndex=2	<t>(.*)</t>							Text of today "night" forecast conditions - Example: "Partly Cloudy"

RegExp=#TodayNightWind#
=======================
StringIndex=1	<s>(.*)</s>							Forecast for today "night" wind speed - Example: "6" (or "calm")
StringIndex=2	<gust>(.*)</gust>				Forecast for today "night" wind gust speed - Example: "10" (or "N/A")
StringIndex=3	<d>(.*)</d>							Forecast for today "night" wind direction in compass degrees - Example: "330"
StringIndex=4	<t>(.*)</t>							Forecast for today "night" wind direction compass text - Example: "NW"

RegExp=#TodayNightElements#
===========================
StringIndex=1	<bt>(.*)</bt>						Short text of today "night" forecast conditions - Example: "P Cloudy"
StringIndex=2	<ppcp>(.*)</ppcp>				Forecast for today "night" precipitation in percent - Example: "10"				
StringIndex=3	<hmid>(.*)</hmid>				Forecast for today "night" humidity in percent - Example: "20"

RegExp=#Day1General#
====================
StringIndex=1	t="(.*)"								Day of the week text - Example: "Wednesday"
StringIndex=2	dt="(.*)"								Month and day text - Example: "Apr 20"
StringIndex=3	<hi>(.*)</hi>						Forecast high temperature in degrees - Example: "81"
StringIndex=4	<low>(.*)</low>					Forecast low temperature in degrees - Example: "45"
StringIndex=5	<sunr>(.*)</sunr>				Time for sunrise for day 1 - Example: "6:25 AM"
StringIndex=6	<suns>(.*)</suns>				Time for sunset for day 1 - Example: "7:50 PM"

RegExp=#Day1DayConditions#
==========================
StringIndex=1	<icon>(.*)</icon>				Icon number for day 1 "day" forecast conditions - Example: "32"
StringIndex=2	<t>(.*)</t>							Text of day 1 "day" forecast conditions - Example: "Partly Cloudy"

RegExp=#Day1DayWind#
====================
StringIndex=1	<s>(.*)</s>							Forecast for day 1 "day" wind speed - Example: "6" (or "calm")
StringIndex=2	<gust>(.*)</gust>				Forecast for day 1 "day" wind gust speed - Example: "10" (or "N/A")
StringIndex=3	<d>(.*)</d>							Forecast for day 1 "day" wind direction in compass degrees - Example: "330"
StringIndex=4	<t>(.*)</t>							Forecast for day 1 "day" wind direction compass text - Example: "NW"

RegExp=#Day1DayElements#
=======================
StringIndex=1	<bt>(.*)</bt>						Short text of day 1 "day" forecast conditions - Example: "P Cloudy"
StringIndex=2	<ppcp>(.*)</ppcp>				Forecast for day 1 "day" precipitation in percent - Example: "10"				
StringIndex=3	<hmid>(.*)</hmid>				Forecast for day 1 "day" humidity in percent - Example: "20"

RegExp=#Day1NightConditions#
============================
StringIndex=1	<icon>(.*)</icon>				Icon number for day 1 "night" forecast conditions - Example: "32"
StringIndex=2	<t>(.*)</t>							Text of day 1 "night" forecast conditions - Example: "Partly Cloudy"

RegExp=#Day1NightWind#
======================
StringIndex=1	<s>(.*)</s>							Forecast for day 1 "night" wind speed - Example: "6" (or "calm")
StringIndex=2	<gust>(.*)</gust>				Forecast for day 1 "night" wind gust speed - Example: "10" (or "N/A")
StringIndex=3	<d>(.*)</d>							Forecast for day 1 "night" wind direction in compass degrees - Example: "330"
StringIndex=4	<t>(.*)</t>							Forecast for day 1 "night" wind direction compass text - Example: "NW"

RegExp=#Day1NightElements#
==========================
StringIndex=1	<bt>(.*)</bt>						Short text of day 1 "night" forecast conditions - Example: "P Cloudy"
StringIndex=2	<ppcp>(.*)</ppcp>				Forecast for day 1 "night" precipitation in percent - Example: "10"				
StringIndex=3	<hmid>(.*)</hmid>				Forecast for day 1 "night" humidity in percent - Example: "20"

==============================================================================================
Days 2 though 5 (possible total of 6 days including "today") follow the same pattern as day 1.
==============================================================================================
So if I am using RegExp=#Location# in my parent, and I want the name of my location, I can see that I want StringIndex=2, which is "Location name the feed is using - Example: "Fort Hunt, VA"".

So I might do that like this:

Code: Select all

[WeatherParent]
Measure=Plugin
Plugin=WebParser
URL=http://wxdata.weather.com/wxdata/weather/local/#LocationCode#?cc=*&unit=#UnitOfMeasure#&dayf=#DaysFeed#&locale=#Locale#
RegExp=(?siU)^(.*)$
FinishAction=[!EnableMeasureGroup Weather]

[LocationParent]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[WeatherParent]
RegExp=#Location#
Disabled=1

[CityNameChild]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[LocationParent]
StringIndex=2
Disabled=1
So now I have the location name as the value of [CityNameChild], and didn't have to do any regular expression from scratch at all.

What if I want something like for instance "How windy is it going to be tomorrow during the day?" That's obscure enough...

Simple:

Code: Select all

[Day1DayWindParent]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[WeatherParent]
RegExp=#Day1DayWind#
Disabled=1

[Day1DayWindChild]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[Day1DayWindParent]
StringIndex=1
Disabled=1
Putting it all together

Here is an example skin, that demonstrates how to "include" the couple of files we need, and how to use the "Super Parent" / "Parent" / "Child" approach to parse the WXData weather feed.

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Metadata]
Name=WXDataTutorial
Author=JSMorley
Version=Apr 19, 2016
License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0
Information=Example skin demonstrating how to create a|weather skin using the feed from weather.com

[Variables]
@IncludeVars=#@#WXDataWeatherVars.inc
@IncludeRegExp=#@#WXDataWeatherRegExp.inc

; Get the entire feed as a "super parent"

[WeatherParent]
Measure=Plugin
Plugin=WebParser
URL=http://wxdata.weather.com/wxdata/weather/local/#LocationCode#?cc=*&unit=#UnitOfMeasure#&dayf=#DaysFeed#&locale=#Locale#
RegExp=(?siU)^(.*)$
FinishAction=[!EnableMeasureGroup Weather]

; Using the "super parent", get the various parent and child measures for our desired data
; See WXDataCheatSheet.txt in @Resources\WXDataHelp

[LocationParent]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[WeatherParent]
RegExp=#Location#
Disabled=1

[CityNameChild]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[LocationParent]
StringIndex=2
Disabled=1

[UnitsParent]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[WeatherParent]
RegExp=#UnitsOfMeasure#
Disabled=1

[UnitsTempChild]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[UnitsParent]
StringIndex=3
Disabled=1

[UnitsSpeedChild]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[UnitsParent]
StringIndex=5
Disabled=1

[CurrentConditionsParent]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[WeatherParent]
RegExp=#CurrentConditions#
Disabled=1

[CurrentTempChild]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[CurrentConditionsParent]
StringIndex=3
Disabled=1

[CurrentConditionsChild]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[CurrentConditionsParent]
StringIndex=5
Disabled=1

[CurrentIconChild]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[CurrentConditionsParent]
StringIndex=6
Disabled=1

[TodayGeneralParent]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[WeatherParent]
RegExp=#TodayGeneral#
Disabled=1

[TodayLowChild]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[TodayGeneralParent]
StringIndex=5
Disabled=1

[TodayHighChild]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[TodayGeneralParent]
StringIndex=4
Disabled=1

; Meters

[MeterCurrentIcon]
Meter=Image
Y=0
W=78
H=78
ImagePath=#@#WeatherIcons
MeasureName=CurrentIconChild

[MeterCurrentTemp]
Meter=String
MeasureName=CurrentTempChild
MeasureName2=UnitsTempChild
X=190
Y=5
FontSize=40
FontColor=255,255,255,255
SolidColor=0,0,0,1
StringAlign=Right
AntiAlias=1
Text=%1°%2

[MeterLine]
Meter=Image
X=85
Y=0R
W=103
H=1
SolidColor=255,255,255,255

[MeterCurrentConditions]
Meter=String
MeasureName=CurrentConditionsChild
X=188
Y=7R
FontSize=15
FontColor=255,255,255,255
SolidColor=0,0,0,1
StringAlign=Right
AntiAlias=1

[MeterTodayLowHigh]
Meter=String
MeasureName=TodayLowChild
MeasureName2=TodayHighChild
X=188
Y=5R
FontSize=11
FontColor=255,255,255,255
SolidColor=0,0,0,1
StringAlign=Right
AntiAlias=1
Text=Low %1° High %2°
WXDataTutorial.png
WXDataTutorial_1.0.rmskin
I have included several files that can be used as a reference to the WXData feed and what it all means in @Resources\WXDataHelp.

WXDataCheatSheet.txt
WXDataExampleFeed.txt
WXDataIconCodes.txt

Another, much more robust example of how to use all this can be found at WXDataWeather 2.1 on deviantART.

Feel free to ask any questions you might have, as long as they are not "How do I use this to fix my Enigma/Jarvis/Omnimo etc. skin?" I'm sorry, but I have no interest in those giant, complicated skin suites, and you are on your own. The point of this is to show you how YOU might create a weather skin, from scratch, using the WXData feed.
You do not have the required permissions to view the files attached to this post.
User avatar
jsmorley
Developer
Posts: 19268
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Weather Skin Tutorial - Extra Credit

jsmorley » April 20th, 2016, 1:52 pm

One of the strengths of the WXData (Weather.com) feed is that it returns both "day" and "night" forecasts for both the current day, and for each of the following days in the feed. That means you can show either or both as desired.

However, for the current day, "today", the "day" forecast is only returned up to a certain point in the afternoon.

After that, it isn't really a "forecast" anymore is it? It's at best the current conditions, and at worse just history.

What happens is that after that time the icon code and temperature values for the "day" part of the "today" information will return an empty string, or "".

In effect what the feed will return is:

<icon></icon>

instead of something like:

<icon>32</icon>

If you are using the forecast information for the current day in your skin, you need to take steps to react to this. What you want to do is check for an empty "" icon code, and instead of using the "day" values for today in your skin, switch to the "night" values.

Fortunately, this is not hard. Let's look at some code:

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Metadata]
Name=WXData Day vs Night
Author=JSMorley
Version=Apr 20, 2016
License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0
Information=Example skin demonstrating how to create a|weather skin using the feed from weather.com

[Variables]
@IncludeVars=#@#WXDataWeatherVars.inc
@IncludeRegExp=#@#WXDataWeatherRegExp.inc

; Get the entire feed as a "super parent"

[WeatherParent]
Measure=Plugin
Plugin=WebParser
URL=http://wxdata.weather.com/wxdata/weather/local/#LocationCode#?cc=*&unit=#UnitOfMeasure#&dayf=#DaysFeed#&locale=#Locale#
RegExp=(?siU)^(.*)$
FinishAction=[!EnableMeasureGroup Weather]

; Using the "super parent", get the various parent and child measures for our desired data
; See WXDataCheatSheet.txt in @Resources\WXDataHelp

; First we will get the icon code for today / day. If that is "" or empty, then we know
; that the feed is no longer returning a "forecast" for the daytime, and we need to 
; use the nighttime values instead.

[TodayDayConditionsParent]
Measure=Plugin
Plugin=WebParser
Group=Weather
URL=[WeatherParent]
RegExp=#TodayDayConditions#
Disabled=1

[TodayDayIconChild]
Measure=Plugin
Plugin=WebParser
Group=Weather
URL=[TodayDayConditionsParent]
StringIndex=1
Disabled=1
IfMatch=^$
IfMatchAction=[!SetVariable TimeOfDay "tonight"][!SetOption MeterChanceOfRainPercent MeasureName "TodayNightPrecipChild"][!ShowMeterGroup Weather][!UpdateMeter *][!Redraw] 
IfNotMatchAction=[!SetVariable TimeOfDay "today"][!SetOption MeterChanceOfRainPercent MeasureName "TodayDayPrecipChild"][!ShowMeterGroup Weather][!UpdateMeter *][!Redraw] 

[TodayDayElementsParent]
Measure=Plugin
Plugin=WebParser
Group=Weather
URL=[WeatherParent]
RegExp=#TodayDayElements#
Disabled=1

[TodayNightElementsParent]
Measure=Plugin
Plugin=WebParser
Group=Weather
URL=[WeatherParent]
RegExp=#TodayNightElements#
Disabled=1

[TodayDayPrecipChild]
Measure=Plugin
Plugin=WebParser
Group=Weather
URL=[TodayDayElementsParent]
StringIndex=2
Disabled=1

[TodayNightPrecipChild]
Measure=Plugin
Plugin=WebParser
Group=Weather
URL=[TodayNightElementsParent]
StringIndex=2
Disabled=1

; Meters

[MeterChanceOfRainLabel]
Meter=String
Group=Weather
FontSize=20
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
Hidden=1
DynamicVariables=1
Text=Chance of rain #TimeOfDay# is

[MeterChanceOfRainPercent]
Meter=String
Group=Weather
X=0R
FontSize=20
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
Hidden=1
Text=%1%
So what I am doing is getting the "day" icon for today with:

[TodayDayConditionsParent]
Measure=Plugin
Plugin=WebParser
Group=Weather
URL=[WeatherParent]
RegExp=#TodayDayConditions#
Disabled=1

[TodayDayIconChild]
Measure=Plugin
Plugin=WebParser
Group=Weather
URL=[TodayDayConditionsParent]
StringIndex=1
Disabled=1

Then I use IfMatch to check if the icon code number returned is an empty string "".

IfMatch=^$

In regular expression, ^ means "start of string" and $ means "end of string".

If it IS, then I use !SetVariable to set a cosmetic "time of day" variable, and !SetOption to change the MeasureName my meter will use to display the "night" value for the percentage chance of precipitation. If it is NOT, then I do the same thing, but use the "day" value for the percentage of precipitation in my meter.

IfMatchAction=[!SetVariable TimeOfDay "tonight"][!SetOption MeterChanceOfRainPercent MeasureName "TodayNightPrecipChild"][!ShowMeterGroup Weather][!UpdateMeter *][!Redraw]
IfNotMatchAction=[!SetVariable TimeOfDay "today"][!SetOption MeterChanceOfRainPercent MeasureName "TodayDayPrecipChild"][!ShowMeterGroup Weather][!UpdateMeter *][!Redraw]

1.png
2.png
You do not have the required permissions to view the files attached to this post.
User avatar
Active Colors
Moderator
Posts: 509
Joined: February 16th, 2012, 3:32 am

Re: Weather Skin Tutorial

Active Colors » April 23rd, 2016, 9:54 am

What is recommended UpdateRate for a weather skin?

I remember there were couple of controversies regarding how often a weather skin should be updated. What is the value you recommend if a skin's Update is 1000 (1 sec)?
User avatar
jsmorley
Developer
Posts: 19268
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Weather Skin Tutorial

jsmorley » April 23rd, 2016, 10:49 am

Active Colors wrote:What is recommended UpdateRate for a weather skin?

I remember there were couple of controversies regarding how often a weather skin should be updated. What is the value you recommend if a skin's Update is 1000 (1 sec)?
I just don't use UpdateRate on a weather skin. The default is 600, which would be 10 minutes, which is a good interval. Most weather feeds update their data every 10 minutes, so there is very limited value it hitting them more often than that.
User avatar
Benjamin Linus
Posts: 171
Joined: July 12th, 2009, 4:05 pm
Location: The Island

Re: Weather Skin Tutorial

Benjamin Linus » April 23rd, 2016, 2:53 pm

:bow:

Excellent guide that man, thanks as always :thumbup:
Image
User avatar
exper1mental
Posts: 282
Joined: January 9th, 2013, 7:52 pm
Location: Southern USA

Re: Weather Skin Tutorial

exper1mental » April 24th, 2016, 11:31 pm

Thank you for this treasure of information you have gather together here! :D

U.S. ZIP Codes also work for the location code (the weather in Central Park, NY can be pulled up using Weather Code USNY0996 or ZIP Code 10024).


You can also verify this by using http://wxdata.weather.com/wxdata/search/search?where=YourZIPCode. There isn't really any practical reason to do this however because Weather.com will simply tell you that your ZIP code is your location code.

I'm a bit curious to find out what else this search functionality might be able to let us do...
Image
JonPeyton
Posts: 5
Joined: November 3rd, 2015, 1:39 am

Re: Weather Skin Tutorial

JonPeyton » April 25th, 2016, 2:57 am

As usual Mr Morley Thanks so very very much!
koutamarto
Posts: 9
Joined: December 23rd, 2016, 5:53 am

Re: Weather Skin Tutorial

koutamarto » January 2nd, 2017, 5:42 am

Thanks for this guide.It is very thorough and is much appreciated.
A few questions.
1. If I make my own skin can I use the stuff you have provided please?

2.I have managed to get it working with the current weather. Ultimately what I was hoping to do was to have a skin showing current temp with an icon with a tooltip showing tomorrows forecast. Is this possible? Figured this one out.

3. Before I bothered trying the tooltip I thought I would just try to get a meter to show the forecast for tomorrow. However I can not get the high temp (or anything else) to show for day1.

Here is the code I am using. can you help please?

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Variables]
@IncludeVars=#@#WXDataWeatherVars.inc
@IncludeRegExp=#@#WXDataWeatherRegExp.inc


[WeatherParent]
Measure=Plugin
Plugin=WebParser
URL=http://wxdata.weather.com/wxdata/weather/local/#LocationCode#?cc=*&unit=#UnitOfMeasure#&dayf=#DaysFeed#&locale=#Locale#
RegExp=(?siU)^(.*)$
FinishAction=[!EnableMeasureGroup Weather]

[LocationParent]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[WeatherParent]
RegExp=#Location#
Disabled=1

[CityNameChild]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[LocationParent]
StringIndex=2
Disabled=1

[UnitsParent]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[WeatherParent]
RegExp=#UnitsOfMeasure#
Disabled=1

[UnitsTempChild]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[UnitsParent]
StringIndex=3
Disabled=1


[Day1ConditionsParent]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[WeatherParent]
RegExp=#Day2General#
Disabled=1

[Day1ConditionsChild]
Measure=Plugin
Group=Weather
Plugin=WebParser
URL=[Day1ConditionsParent]
StringIndex=3
Disabled=1


;---------------------------------------------------------

[Day1Temp]
Meter=String
MeasureName=Day1ConditionsChild
MeasureName2=UnitsTempChild
X=10
Y=10
FontSize=18
FontColor=255,255,255,255
SolidColor=0,0,0,1
StringAlign=Left
AntiAlias=1
Text=%1°%2
cheers
Last edited by koutamarto on January 4th, 2017, 7:19 am, edited 2 times in total.
koutamarto
Posts: 9
Joined: December 23rd, 2016, 5:53 am

Re: Weather Skin Tutorial

koutamarto » January 4th, 2017, 7:17 am

jsmorley wrote:I just don't use UpdateRate on a weather skin. The default is 600, which would be 10 minutes, which is a good interval. Most weather feeds update their data every 10 minutes, so there is very limited value it hitting them more often than that.
Hi there anychance of some advice on my above question please?
It would be much appreciated.

Cheers
User avatar
fonpaolo
Moderator
Posts: 1351
Joined: April 11th, 2013, 8:08 pm
Location: Italy

Re: Weather Skin Tutorial

fonpaolo » January 4th, 2017, 9:09 am

About #1, yes, you can use the code, give only credit to the creator. ;-)

About #3, first of all, open Rainmeter log and look for Day1ConditionsChild measure, what is listed there?