• No results found

One of the key aspects of OpenRemote is its ability to fully integrate open standard

protocols like TCP/IP, HTTP and Telnet. This allows for correlation and interaction of the building infrastructure with devices that use Internet protocols, such as consumer

electronics, home appliances, smartphones or information services. As an example we will design a smart weather sensor for our building automation project, which retrieves

weather information from the Internet.

6.1 OpenRemote Control via HTTP: Retrieving Internet Weather Data

Our objective for this section is to retrieve precipitation and temperature information for a particular geographic location from the Yahoo Internet weather service, import it into an OpenRemote sensor and display it on our smartphone or tablet control panel.

We start by going to OpenRemote Designer and, creating a new device, which we call HTTP. Under this device we create a command which we will call Weather Berlin by selecting

New — New command. As the protocol we select HTTP.

The corresponding HTTP URL for retrieving the weather data from the Yahoo website can easily be crafted following the Yahoo format instructions. The location needs to be

specified using the Yahoo WOEID (Where On Earth Identifier), which for our example Berlin, Germany turns out to be 638242. (There are many sites on the Internet that offer WOEID searches). As the unit u for the temperature we can choose between c for Celsius and f for Fahrenheit. With that we have our URL which we enter into our command

window:

http://weather.yahooapis.com/forecastrss?w=638242&u=c

(Do not try to call up the above URL yet, since this is an RSS feed. You will see in a

minute what we do.) As HTTP method we specify GET and as polling interval 15s with s for seconds. What is left is the slightly tricky part of extracting the temperature value from the data the Yahoo site sends back triggered by our HTTP GET command.

For data extraction from the HTTP response OpenRemote offers two possibilities: XPath or regular expressions. If the data comes back in XML format, which would be the

preferred way, it is easiest to use an XPath expression for the data filter.

For those who have not worked with XML before - it is a really simple, mostly self-explanatory specification for data containers. It is also widely used on the Internet as the data transport format of choice, allowing for easy data exchange between different entities (websites, databases, software, etc.). XPath is nothing more than a structured definition language (similar to regular expressions) to extract and filter data out of XML data

structures. (A good tutorial to start with XPath, in case you have not worked with it before, is available at http://www.w3schools.com/xpath/xpath_syntax.asp). W3 also provides an excellent XML tutorial at http://www.w3schools.com/xml/.

Since this Yahoo response comes back as a RSS service (with a XML data structure inside) standard browsers will try to activate their RSS plug-in, when the HTTP response arrives. Since at first we just want to take a look at the source of the data being sent back, we use a little trick, which works with Firefox browsers. We precede our URL entry with

“view-source:” and enter:

view-source:http://weather.yahooapis.com/forecastrss?w=638242&u=c This will get us the source of the Yahoo response displayed:

<?xml version=“1.0” encoding=“UTF-8” standalone=“yes” ?>

<rss version=“2.0” xmlns:yweather=“http://xml.weather.yahoo.com/ns/rss/1.0”

xmlns:geo=“http://www.w3.org/2003/01/geo/wgs84_pos#”>

<channel>

<title>Yahoo! Weather - Berlin, DE</title>

<link>http://us.rd.yahoo.com/dailynews/rss/weather/Berlin__DE/*http://weather.yahoo.com/forecast/GMXX1273_c.html</link>

<description>Yahoo! Weather for Berlin, DE</description>

<language>en-us</language>

<lastBuildDate>Sun, 28 Oct 2012 6:50 am CEST</lastBuildDate>

<ttl>60</ttl>

<yweather:location city=“Berlin” region=“BE” country=“Germany”/>

<yweather:units temperature=“C” distance=“km” pressure=“mb” speed=“km/h”/>

<yweather:wind chill=”-6” direction=“250” speed=“8.05” />

<yweather:atmosphere humidity=“100” visibility=“9.99” pressure=“982.05” rising=“1” />

<yweather:astronomy sunrise=“6:54 am” sunset=“4:43 pm”/>

<image>

<title>Yahoo! Weather</title>

<width>142</width>

<height>18</height>

<link>http://weather.yahoo.com</link>

<url>http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif</url>

</image>

<item>

<title>Conditions for Berlin, DE at 6:50 am CEST</title>

<geo:lat>52.52</geo:lat>

<geo:long>13.38</geo:long>

<link>http://us.rd.yahoo.com/dailynews/rss/weather/Berlin__DE/*http://weather.yahoo.com/forecast/GMXX1273_c.html</link>

<pubDate>Sun, 28 Oct 2012 6:50 am CEST</pubDate>

<yweather:condition text=“Partly Cloudy” code=“29” temp=”-3” date=“Sun, 28 Oct 2012 6:50 am CEST” />

<description><![CDATA[

<img src=“http://l.yimg.com/a/i/us/we/52/29.gif”/><br />

<b>Current Conditions:</b><br />

Partly Cloudy, -3 C<BR />

<BR /><b>Forecast:</b><BR />

Sun - Sunny. High: 7 Low: -3<br />

Mon - Partly Cloudy. High: 6 Low: 1<br />

<br />

<a

href=“http://us.rd.yahoo.com/dailynews/rss/weather/Berlin__DE/*http://weather.yahoo.com/forecast/GMXX1273_c.html”>Full Forecast at Yahoo! Weather</a><BR/><BR/>

(provided by <a href=“http://www.weather.com” >The Weather Channel</a>)<br/>

]]></description>

<yweather:forecast day=“Sun” date=“28 Oct 2012” low=”-3” high=“7” text=“Sunny” code=“32” />

<yweather:forecast day=“Mon” date=“29 Oct 2012” low=“1” high=“6” text=“Partly Cloudy” code=“30” />

<guid isPermaLink=“false”>GMXX1273_2012_10_29_7_00_CEST</guid>

</item>

</channel>

</rss>

<!— api7.weather.ch1.yahoo.com Sun Oct 28 06:31:55 PST 2012 —>

What looks scary at first sight is actually not all that bad, since it is XML, and thus well structured. Recognizing the XML node structure, what we really want to look at is quickly reduced to

<channel>

……

<item>

…….

<yweather:condition text=“Fair” code=“33” temp=“13” date=“Wed, 17 Oct 2012 8:49 pm CEST” />

…..

</item>

……

</channel>

What we are looking for are the values of the attributes temp (13) and text (Fair) inside the XML element <condition> right inside its parent <item>.

There is one more thing we need to know before we can design the XPATH definition for our search string. The element we are looking for starts with a name, followed by a colon:

<yweather:Conditio …

This is the syntax for a so called XML namespace. XML namespaces are local additions to element names. They are used to avoid element conflict when adding together documents that use the same element names. A namespace is defined by the so called xmlns attribute at the start tag of the element where they are used or in the XML root element. In our case the name space yweather is defined at the very beginning of the XML document:

xmlns:yweather=“http://xml.weather.yahoo.com/ns/rss/1.0”

With a double backslash // XPath can jump right to the XML node regardless of where it is, and @temp references the value of the attribute temp. Without the namespace our XML definition would be as simple as

//condition//@temp

In our case we need to tell XPath, that our target element is part of a local namespace.

With that, our XPath expressions read as follows:

//*[local-name() = ‘condition’]//@temp //*[local-name() = ‘condition’]//@text

To validate our assumption we copy the source of the Yahoo response and our XPath expression into the online XPath query checker under

http://emdin.info/r/xpath_checker/

and see that our assumption was correct (Figure 6.1).