Monday, December 28, 2009

gMFSK getwx - a more finished script :)

Well... I didnt expect this to be quite so popular :) I woke up to a full inbox this morning - hard to believe so many people found the script so quickly.

OK, I realise that not everyone who uses gMFSK is a php programmer, and somne people are a little wary of editing the cron tab, so Ive written out a script that does everything - ie: it checks if there is a recent local copy of the RSS xml and builds the weather data from that - only downloading from yahoo if more than 30 minutes (by default) have passed.

Ive added lots of comments so as a combination of the new script and reading the previous blog entry it should be very clear how this works. I hope it will lead you on to a bit more experimenting with other on-line RSS sources you may want to use.

enjoy:


#!/usr/bin/php
<?
/* gMFSK getwx::

A simple script to grab your local weather from the web to insert into F-key
macros in the same way as $mycall $yourcall etc.

This is a slightly more finished version of the test scripts recently published
on my blog. This version checks if it has a local copy with a recent datestamp
of the RSS data from yahoo - then builds a complete weather report from the cached
data to save hitting yahoo every time the script is called.

Yes it could be done more easilly using cron, but feedback from some users
has suggested that a self contained "easy" script is wanted

Yes I could have used CURL - but a basic php_cli install doesnt always have
CURL compiled in.

to get the right url for your local yahoo weather vist weather.yahoo.com
type in your location and hit return. When you get your local weather click
on the orange RSS button and make a note of the URL. its the p=XXXXXXXXX bit that
is important. Changing the u=f to u=c gets you metric results

You need php_cli installed for this script to work eg: sudo apt-get install php5_cli

save this script to your gMFSK directory, remember to chmod it +x to be executeable

in one of the gMFSK function key windows add the command:

$(/home/g7nbp/gMFSK/getwx)

Remember to alter your path to point at wherever the file is saved.


Please feel free to experiment :)

Written by g7nbp 28-12-2009
*/


// OK first a few variables
$pageurl = "http://weather.yahooapis.com/forecastrss?p=UKXX1012&u=c"; // url of yahoo weather RSS feed
$file = "wx.xml"; // the file to save the xml to
$update_time = 1800; // period between getting updates down in seconds



if (file_exists($file)){

// the wx.xml file has been found :)
$fileage = time() - filemtime($file); // workout how old the local copy is
if ($fileage >= $update_time){
// local copy older than update_time - call the get_xml routine to read from website
get_xml();
}

}else{
// no the wx.xml file has not been found (first run??) so call the get_xml routine
get_xml();
}

// OK assuming nothing broke we can now work with the local copy :)


$rss = simplexml_load_file($file); // open local copy

// Build the variables from the assorted yweather:something namespaces
$condx = $rss->xpath('//yweather:condition/@text');
$condx = ltrim(rtrim($condx[0])) ." ";

$pressure = $rss->xpath('//yweather:atmosphere/@pressure');
$pressure_units = $rss->xpath('//yweather:units/@pressure');
$pressure = ltrim(rtrim($pressure[0])) . $pressure_units[0];

$temp = $rss->xpath('//yweather:condition/@temp');
$temp_units = $rss->xpath('//yweather:units/@temperature');
$temp = ltrim(rtrim($temp[0])) ."°". $temp_units[0];

$windd = $rss->xpath('//yweather:wind/@direction');
$winds = $rss->xpath('//yweather:wind/@speed');
$wind_units = $rss->xpath('//yweather:units/@speed');
$wind = ltrim(rtrim($windd[0])) . "° ". ltrim(rtrim($winds[0])) . $wind_units[0];

// finally build our output string

echo "local WX: Temp=". $temp . " Pressure=" . $pressure . " Wind=" . $wind . " Condx=" . $condx . "\n" ;

// --- thats all folks! ---


// functions live here

function get_xml(){
// a really simple file_get file_put routine to grab a copy of the weather XML
// and save it local to save hitting yahoo every time time we run the srcipt
global $file, $pageurl;
$xml =file_get_contents($pageurl);
file_put_contents($file, $xml);
}

?>


Sunday, December 27, 2009

gMFSK enhancements:: WX report... and beyond

Hi All...

Its been a while since I last blogged, but feeling suitably pleased with my recent efforts, so its time to blog :)

A while back I noticed that some PSK31 contacts have included automatic weather data, data from qrz.com, data from all over the web in fact. I wanted to add similar functionality to gMFSK

I noted that gMFSK (others will probably work too!) allows a shell command to be run as part of the macro system assigned to the function keys - extending the usual $mycall $yourcall syntax as far as you care to imagine. This is the way in :)

Basically to run any other command in gMFSK the syntax is $(/path/to/the/app)

So... after a bit of digging I found that the yahoo weather xml call brings back the data Im looking for (temp, pressure, wind and a description) and although it uses some extended xml namespace synatx is very easy to parse. I quickly wrote some test apps in php (yes I could have written them in C, perl or any other lang, but php makes this type of rss scraping easy and its what Im most fulent in).

(The reason for deciding upon yahoo by the way is that they change their XML far less frequently than other well known RSS feeds)

Basically the test scripts drag back the rss page from

http://weather.yahooapis.com/forecastrss?p=UKXX1012&u=c

which is my local weather station. To find the url for yours visit http://weather.yahoo.com/ type in your location into the city or zipcode box, and then click on the orange RSS feed button on the right and note the url of the rss feed. The important bit is the p=XXXXXXXXXX bit. You may want to change the final u=f to u=c if you want mainly metric results.

If you view the source of what comes back you will seethat most of the required info is there for the taking, if you can manipulate the

<yweather:wind chill="1" direction="260" speed="14.48" />

colon extended namespace format.

I wrote 4 test scripts for temp, pressure, wind, and conditions using php (If you dont have php-cli installed you need to add it - debian / ubuntu / similar systems can simply run
> sudo apt-get-install php5-cli

to add php script support without the need to add all the apache libs etc)

Each script calls the web page direct, but this is of course wasteful as the data is only updated every 30 mins or so. Most users will want to modify the scripts to point at a local version of the data and cron an hourly download, but thats up to you to work out ;)



temp::
#!/usr/bin/php
<?
$rss = simplexml_load_file('http://weather.yahooapis.com/forecastrss?p=UKXX1012&u=c');
$temps = $rss->xpath('//yweather:condition/@temp');
$units = $rss->xpath('//yweather:units/@temperature');
$temp = ltrim(rtrim($temps[0])) ."°". $units[0];
echo "T: " .$temp;
?>


Pressure::
#!/usr/bin/php
<?
$rss = simplexml_load_file('http://weather.yahooapis.com/forecastrss?p=UKXX1012&u=c');
$pressures = $rss->xpath('//yweather:atmosphere/@pressure');
$units = $rss->xpath('//yweather:units/@pressure');
$pressure = ltrim(rtrim($pressures[0])) . $units[0];
echo "P: ". $pressure;
?>

Wind::
#!/usr/bin/php
<?
$rss = simplexml_load_file('http://weather.yahooapis.com/forecastrss?p=UKXX1012&u=c');
$windd = $rss->xpath('//yweather:wind/@direction');
$winds = $rss->xpath('//yweather:wind/@speed');
$units = $rss->xpath('//yweather:units/@speed');
$wind = ltrim(rtrim($windd[0])) . "° ". ltrim(rtrim($winds[0])) . $units[0];
echo "W: " .$wind;
?>

condx::
#!/usr/bin/php
<?
$rss = simplexml_load_file('http://weather.yahooapis.com/forecastrss?p=UKXX1012&u=c');
$condx = $rss->xpath('//yweather:condition/@text');
$condx = ltrim(rtrim($condx[0])) ." ";
echo $condx;
?>


You need to mod each of the scripts to be executable via chmod +x and save to the gMFSK dir in your homedir.

Each script can be tested on the command line.

Finally you need to add them to gMFSK. In my case Ive added a combined wx macro to F12:

WX: $(/home/chrisw/gMFSK/condx) - $(/home/chrisw/gMFSK/temp) $(/home/chrisw/gMFSK/wind) $(/home/chrisw/gMFSK/pressure)

(change chrisw to whatever your homedir is!)


Hitting F12 now of course brings back to the TX window:
WX: Mostly Cloudy - T: 4°C W: 290° 8.05km/h P: 982.05mb



As commented, each script hits yahoo for about 1k of data so while this inst a huge amount, its not very sporting every QSO so consider using a wget script from the cron to grab a local offline copy of the page and parse that rather than hitting the web every time!

Hopefully that provides some inspiration for others to go on to explore other dynamic data includes in gMFSK from not only yahoo weather, but the whole of the net :)