Improve the Weather with PHP

Ever wanted to turn a cloudy day into a sunny one? Well now you can, with the magic of PHP. If you use the Live Theme here at Mike Industries, you may have noticed that the weather conditions displayed in the header have improved markedly over the last couple of weeks. We’ve gone from a summer of “partly cloudy” and “fair” days to “sunny”, “beautiful”, and “spectacular” days. Here’s the lowdown on the PHP-induced warming trend:

When I first launched the Live Theme, it was merely a live shot of Puget Sound with no weather conditions readout. But then I saw Michael Simmons’ handy dandy weather readout and got jealous enough to set up a weather readout of my own (full instructions will follow later in this article). Problem was, I didn’t like what I was seeing on the weather report. We are in the middle of our third spectacularly sunny Seattle summer in a row and my weather readout still said things like “Partly Cloudy”.

Then one day a couple of weeks ago, something made me snap. I looked out the window of my office at the 360 degree view, and I saw nothing but blue sky and one tiny speck of a cloud in the distance. I then went to the web and saw that Mike Industries was reporting “Partly Cloudy and 80 degrees”. It was clear at this point that something had to be done.

Go straight to the source

As it turns out, the noaa.gov weather feeds are generated at various airports around the country. I chose Seattle’s Boeing Field, being that it is only about 10 miles away from me. Well, it turns out that the poor schmo who is in charge of watching clouds and reporting weather conditions at Boeing Field is some kind of pessimist. Either that or he’s trying to uphold Seattle’s reputation as a foul-weather city so no one else moves here. For all I know, he might even be choosing what weather conditions to report by throwing darts. One thing was clear — his input was not up to the Mike Industries Meteorological Reporting Standards, and thus, I had to banish him from the site.

With one cloudwatcher already dismissed, I moved on to other nearby airports. The next two closest were Sea-Tac and Renton. I monitored each airport’s reports a few times a day over the next week and Sea-Tac’s were still a little negative for my tastes, but I thought I might have a winner in Renton. I don’t know what they put in the coffee at Renton airport, but for whatever reason, the reports were quite a bit more accurate. So I settled on Renton.

Tomato tomahto

So you’d think everything would be all solved now, right? Well, not quite. Apparently, the Renton schmo really likes the word “fair”. I like “fair” to describe skin tones, carnivals, and reasonable policies, but I just don’t like it to describe beautiful clear skies. “Fair and 80 degrees”? It just sounds very average to me. How was that chicken? “I don’t know. It was fair.”

Now that I had at least an accurate weather report to work with, I figured I’d rip a page out of The Wolf’s book and start replacing stuff with PHP. In general, I noticed the following things about Renton’s weather report:

“Mostly Cloudy” is actually partly cloudy
“Partly Cloudy” is actually mostly sunny
“Fair” is actually really sunny

Armed with these three conditions to change, I used PHP to perform the weather upgrade. The first two were fairly straightforward, but I really wanted to go over the top on the last one. When it’s nice out, I really want to let you know about it. So I set up a random number system in PHP whereby “fair” gets replaced randomly by one of the following:

Spectacular
Beautiful
Sunny
Not a Cloud in the Sky

Great! So we’re done now, right? Not quite.

Sunglasses at night

Unless you’re Corey Hart, you can’t see solar rays under the cover of darkness. Therefore, it makes no sense to report things like “sunny” or “spectacular” when it’s nighttime. “Clear” is probably a better descriptor. So the next step was inserting logic into the PHP code which would decide what term to display depending on if it was dark or light in Seattle at the time. Since it’s no fun to just estimate it, I decided to use a Sunrise/Sunset function unearthed at this curious location in Liechtenstein. It’s a PHP function, wrapped in a class, which spits out the sunrise or sunset time at a set latitude and longitude for any day of the year. Armed with this piece of PHP, I created a conditional in my weather script which substitutes “clear” for “fair” at night, and one of the four reasonable embellishments during the day.

Incidentally, there was one other way I was thinking about doing this. That was to actually take a brightness reading of the current Live Cam shot and base it on that. Dark Live Cam equals night, Light Live Cam equals day. The only problem with that is that the chance for errors seems high. Why trust a DV cam when you can trust astronomy.

The code

So there you have it. Better weather with PHP. I’m providing the code below in case you’d like to implement it on your own site. Here are the instructions:

  1. Save sun.php and weather.php to your server.
  2. Customize the variables in weather.php with your geographical location, local server path and any additional embellishments you wish. My weather feed pulls from KRNT.rss which is Renton airport. You’ll have to change that value to an airport closer to you. You can look up your airport here. And you can look up your latitude and longitude here. By the way, I’m using kind of a Busch League method to parse the RSS file. If any of you PHP people out there have a better way, I’ll swap it in there.
  3. Set up a cronjob to hit the weather.php file every half hour or hour.
  4. That php file will save the weather information (e.g. Sunny and 70) to a little file called “weatherslug.txt” which you can then pull into your pages with PHP or Flash. I use Flash and feed the file contents in via flashvars.

That’s it!

Like this entry? You can follow me on Twitter here, subscribe via email here, or get the RSS feed if that's how you roll.

36 Responses:

  1. Wired says:

    … you REALLY have too much time on your hands …

    Then again, I AM reading this at 3 AM right after a friend IM’d me about it right after his Bloglines Notifier notified him (I don’t use the Notifier).

    … (looks around) oookkkay, you’re not the only one :) …

    … time to invent a web based notifier for whilst I’m at work me thinks … :)

  2. Using crond to access a php? That sound somehow dangerous. What if, and it’s only a big if, someone malicious hits that php 100 times a second. Not only will your server go to 100% CPU but you’ll also flood the guys offering the weather service.

    If I remember correctly, you can call a php script by running php path_to_file so you don’t have to have the php in a public location, but that was “back in the day”. I suppose this would be a perfect job for Perl, on the other hand.

  3. Mike D. says:

    Gabriel,

    I’m definitely interested in hearing about any better ways to do this, including the path_to_file thing you mentioned, but consider:

    1. What’s the difference between someone hitting this PHP script 100 times a second and someone hitting any other PHP page on my site 100 times a second? That said, it’s probably a good idea to rename weather.php anyway.

    2. If you want to take down poor NOAA, can’t you just bang on their rss feeds yourself?

  4. Jon Hicks says:

    Hey, I’m English, so this suits us weather-obsessed types! Nice, I might have a go at this myself (cron jobs are a distant speck on the horizon to me…)

  5. Really like the Live theme, any chance of centigrade for us Europeans? (or Kelvins would be cool maybe)

    (Editor’s Note: You got it. I just added centigrade in there. Kelvins would be cool, yes, but that’s entering a level of geekness that I’m not ready to accept yet.)

  6. M says:

    I’m so impressed I don’t know what to say! Haha!

    Thanks for continuously dishing out new things to inspire the rest of us.

  7. Sam Ryan says:

    Wow. This is really cool. Too bad I can’t afford a webcam to go with it.
    Speaking of which, I just looked at the LIVE theme for the first time. Do you by chance live in Magnolia?

  8. Trent says:

    Suggestion: if you are distributing someone else’s work (viz. the Astro_Sunrise class), give them credit by including their commented “header” in your distributed source code.

    (Editor’s Note: Done. Need to get over this impulse to save bandwidth… :) )

  9. rssweather.com’s weather directory looks promising for finding locations that are hard to find good airport feeds for.

    For instance, the airport nearest Nevada City, CA was way off since the elevation is way different (this is in the Sierra Nevadas) — but this site has a feed just for Nevada City.

    They have a couple of stipulations for using their feeds which you may not like: only one check per hour, and you must link to them. Are there RSS weather directory sites that let you use their feeds for “free”?

  10. Bill says:

    Nice! But can’t you make the image a little less grainy? What’s with all the lines through it?

  11. Jina says:

    Impressive. :)

  12. thanks to the handy people at xoapweather, the weather channel is accessible to the weather hardcore.

    http://xoap.weather.com/weather/local/08343?dayf=1 is an xml feed with which to play.
    (subsitute your zip, then view the source or change the dayf value for a forecast)

    i went through a weather kick a while back. (un)fortunately work picked up and i never got a chance to finish my weather module.

  13. Mike D. says:

    Jon: C’mon, crons are cake! It’s one line of code:

    10 * * * * /yourlocalfilepath/weather.php > /dev/null

    That’s it. That will hit the file once an hour on the tens.

    Sam: Nope, I live in Queen Anne, but the view is similar to the one you’d get in Magnolia (west facing towards Alki).

    Bill: Find me a webcam which produces high resolution snaps and I can improve the picture quality. All webcams basically produce shit snapshots so I’m not even using one. I’m using a full-on Sony DV Cam. As for the artificial scanlines, I put those in there because they actually give the illusion that the picture is sharper (a la a television set).

  14. Nice move, Mike. I was just in Seattle for the past few days and it really was spectacular, not “fair” or “partly cloudy” in the least.

  15. Can PHP wipe off the window too?

  16. randy says:

    Nice.

    I can’t seem to get a download (always zero bytes) on the first step “Save sun.php and weather.php to your server.”

    Am I reading it wrong?

    Thanks,
    r

  17. Sweet action.

    Thanks for making the source available. Even if I don’t use it on my site, it was fun and helpful to see how you did it.

    As a partial side-note, your style switcher is nice, too. I had a tough time deciding which style I wanted – all are very nice.

    I have just become a consistent reader. Keep the good stuff comin’.

  18. Wow thats really cool.. I had been wondering how you put together that crazyness.

  19. David Robarts says:

    When I first loaded your site today, it stated “Not a cloud in the sky;” however, the webcam indicated differently. On this page load, the PHP decided it was “Beautiful” and I must agree. A few nice clouds in a mostly clear sky over the sound. Oh to have a web cam and such a view.

  20. CLPettit says:

    You might find this interesting
    http://cleardarksky.com/csk/
    It’ll guess/predict your weather/sky condition night or day.

  21. dominic says:

    so, has anyone got this working for us europeans? – I’d really like to know… Thanks

  22. Schmelding says:

    This rawks and works on my internal server, but a lot of folks can’t use it with sites that reside on a shared hosting service provider because they are restricted from using cronjobs. Any other solutions besides using cron and you’ve got this licked!

  23. Ole Hansen says:

    http://cronjob.de/ is one possible solution for people who cannot set up their own cronjobs.

    Oh, and the validator for the Email Address field is broken. It rejected my perfectly valid address. Hint: just about anything goes before @. This is an example of a syntactically valid address
    “Jack & Jill + their son”@example.com

  24. Schmelding: An alternative to cron is to simply check for each visitor if the current information is more than an hour stale. If so, fetch it while generating their pageview.

    I avoided having cron call PHP by just using wget, eg:

    wget –output-document=/home/me/public_html/weather.rss ‘http://rssweather.com/rss.php?…’

    The single quotes are necessary for the ampersands to get parsed correctly.

  25. I just downloaded this and then uploaded it and it gives me this error:

    “,$CONTENTS); $ARRAY2 = explode(“

    Any ideas why? I am using “http://www.nws.noaa.gov/data/current_obs/KTHV.rss” which is my local airport.

  26. Just tried it again without changing anything and it gave me this:

    #!/usr/local/bin/php -q “,$CONTENTS); $ARRAY2 = explode(“

  27. userdude says:

    Ok, very nice; once I got a clue what was going on, it worked!

    Just one problem: The sunset/sunrise seems to be off by an hour at night. It was reading out 18:13 when in fact it should have said 19:13 for where I’m at lon/lat? I don’t know; looking at the script, it seems to run off the date/timestamp, but I haven’t quite gotten it figured out yet what I can do. Is this an issue with the daylight savings in my area?

    Very nice, though! :D

  28. I was flipping through your blog entries and this one caught my eye. In particular thanks for the pointer to the Astro Sunrise class.

    I combined it with some ideas in an article from Simon Moss over at PHPBuilder on GIS locating with PHP and GD.

    Now my web site displays a cute word map showing my location and the day/night terminator and my sunrise/sunset for today:
    http://ffaat.pointclark.net/blog/

    Couple of things for you:

    The class provides function to set the variables, so rather than your code (eg sunstatus->lat=47) you should just call:
    $sunstatus->setCoords(47,-122);

    (there is error checking in the Set calls). The same for Timezone. Also for the date, use the following instead of your three lines:
    $sunstatus->setDate(date(‘Y’),date(‘m’),date(‘j’));

    Lastly, there is a bug in the class (I have emailed the author). On line 160 $R is used:
    $S = $R – sin($Q) * sin($E);

    This needs to be defined just before use, like so:
    $R = $this->R;
    $S = $R – sin($Q) * sin($E);

    Otherwise the Radius corrections are not applied.

    Again – Thanks! Love the writing.

  29. One comment for UserDude.

    I found the same problem (daylight savings time). As I am running on my local server with the correct time zone settings I changed the call like so:

    $localtime_assoc = localtime(time(), true);

    $sunstatus = New Astro_Sunrise;
    $sunstatus->setTwilight(‘effective’);
    $sunstatus->setCoords($lat, $long);
    $sunstatus->setTimezone(-5 + $localtime_assoc[tm_isdst]);
    $sunstatus->setDate(date(‘Y’),date(‘m’),date(‘j’));

    So if the computer knows it is on DST, it adds 1 to the timezone offset. (I am on EST, -5, in the winter and EDT, -4, in the summer)

    Adjust to meet your needs….

  30. usedude says:

    Hey, that’s great! Thanks for the tip. I was looking for something like that, but didn’t come across an answer. Much thanks.

    If you’d like to see an implementation of the weather and sunrise class, I’ve used it here:

    http://web2.unt.edu/riskman/index.php?section=index

    I modified the weather data to use the XML feed instead, since I found it had much more information contained within it than the RSS feed. I started putting together a small file to author the string data and save it to a flat file, but I haven’t been able to finish it with so many other projects out there. My mockup is located here:

    http://www.mulkeymason.com/communication/setweather.html

    It’s about half-finished, though, and doesn’t work at all in Internet Explorer.

    Thanks again.

  31. Has anyone got this working for Europeans? There don’t seem to be any freely available feeds for us which are as useful as the US ones.

    I’m also having the same problem as Joshua Kendall – running weather.php on my server (having changed the variables) gives me nonsense, and opening weatherslug.txt gives me nothing (i.e. a blank file). Am very confused.

    All help gratefully received

  32. userdude says:

    You can pickup the information from the accuweather.com website:

    http://forecastfox.accuweather.com/adcbin/forecastfox/weather_data.asp?location=EUR|UK|UK001|LONDON|&metric=1

    This is a link to the London, England XML file; this information is updated once every two minutes, I believe. You can pull this and transform it into an array and then traverse the array to get the information that you’re looking for.

    To get the code for your area, visit:

    http://wwwa.accuweather.com/index-world.asp

    and plug in your town/city, and then use the zipcode from the query string, replacing ‘location=EUR|UK|UK001|LONDON|’ in the link above with ‘location=NEW_LOCATION|INFORMATION|QUERY|TEXT’.

    Hope that Helps!
    jd

  33. MultiZ says:

    Thanks for the post.

    Is there an example/demo for the weather module?

    I’ll try it out anyway, probably.

    Thanks again.

  34. jD says:

    Hi Mike,
    Do you think you could share the .fla for the weather function?
    I understand the information you have presented. But it is
    beyond me to pull it in to the flash file.

    thanks,
    jD

  35. JD on MX says:

    Davidson’s weather

    Davidson’s weather: Mike Davidson writes of how he had to interpret and improve the raw info given in a weather web service. On one level it’s a story about a particular operation, but on another level it’s a story about…

  36. The Lazyman’s Window

    While I was attempting to calm myself down from the denial I received from my past ISSN application, I ended up coming across Mike Davidson and his blog. And well, wouldn’t you know, but Mike has setup a PHP script which allows one to display a fairl…

Shared
Humanity's deep future:

A group of researchers at the Future of Humanity Institute talk about where our race may be going and how artificial intelligence could save or kill us all.

Steve Jobs speaks about the future at the International Design Conference in 1983:

31 years later, it’s safe to say this is one of the most prescient speeches about technology ever delivered. Jobs covers wireless networking, tablets, Google StreetView, Siri, and the App Store (among other things) many years before their proliferation. A fantastic listen.

How to travel around the world for a year:

Great advice for when you finally find the time.

LiveSurface:

A fantastic app for prototyping your design work onto real world objects like billboards, book covers, and coffee cups. This seems like just as great of a tool for people learning design as it does for experts.

50 problems in 50 days:

One man’s attempt to solve 50 problems in 50 days using only great design. Some good startup ideas in here…

How to Do Philosophy:

If you’ve ever suspected that most classical philosophy is a colossal waste of time, Paul Graham tells you why you’re probably right.

TIME: Why Medical Bills Are Killing Us:

Stephen Brill follows the money to uncover the pinnacle of corruption that is the U.S. Health Care system. A must-read article if there ever was one.

DIY Dot Org:

A beautifully designed site full of fun and challenging DIY projects. I could spend months on here.

The Steve Jobs Video Archive:

A collection of over 250 Steve Jobs videos in biographical order

Self-portraits from an artist under the influence of 48 different psychoactive drug combos.

Water Wigs are pretty amazing.

David Pogue proposes to his girlfriend by creating a fake movie trailer about them and then getting a theater to play it before a real movie. Beautiful and totally awesome.

Jonah Peretti's letter to BuzzFeed’s employees:

If you’re wondering what a excellent blueprint for a modern media company looks like, look no further than Buzzfeed CEO Jonah Peretti’s latest email to his employees. In it, Peretti explains a lot of his company’s virtues, the most important being a relentless focus on always providing what’s best for the user. Vox Media (operators of The Verge) is the only other company I can think of which approaches this level of reform and execution.

The Covers Project:

I love this so much: a cross-referenceable database of cover songs, searchable by song or artist. Slowed down, acoustic covers — no matter the song — are so enjoyable to me that I wish it was a requirement to play one at every show. If you like them as much as I do, make sure to check out M. Ward’s Let’s Dance or Sun Kil Moon’s entire album of Modest Mouse covers.

“More and more people in this country no longer make or do anything tangible; if your job wasn’t performed by a cat or a boa constrictor in a Richard Scarry book I’m not sure I believe it’s necessary. I can’t help but wonder whether all this histrionic exhaustion isn’t a way of covering up the fact that most of what we do doesn’t matter.”
- Tim Kreider’s denunciation of the cult of busyness is excellent. (via jimray)