Weather Underground - End of Service announcement

The current API will be discontinued per 12/31/2018.

It’s a shame as it’s the only V2 addon which supports forecasts as far as i’m aware.

The writing has been on the wall for quite awhile when they discontinued new user signups for API keys.

For developers who use WU API data for non-commercial purposes, you will have access to a new plan for a personal use, low call volume API. Stay tuned for more details as we build this out.

So there is some hope that there will be an API available but of course new API means new binding implementation.

I messed around with data from NOAA a few months ago. Maybe I’ll pick that work up again, though NOAA will probably be more appropriate for those in North America.

Agreed. I’d also say the IBM acquisition was a sign that things likely would change at some point.

For developers who use WU API data for non-commercial purposes, you will have access to a new plan for a personal use, low call volume API. Stay tuned for more details as we build this out.

I am curious what this means exactly.

If you are a Personal Weather Station owner, you will receive more information about our plan to offer free access to the data you provide to Weather Underground. We’ll reach out once that plan has been finalized.

Let’s see. I give them data from the technology that I bought. They then monetize that data. Then they give me free access to that data. Gee, how nice of them. I don’t think so.


I’m using OpenWeatherMap and it is providing at least some forecast values:

2018-09-14 08:03:14.080 [DEBUG] [nal.provider.AbstractWeatherProvider] - OPENWEATHERMAP[home]: Weather[Temperature[current=8.64,min=7.0,max=10.0,feel=9.306901501401088,dewpoint=<null>],Atmosphere[humidity=100,visibility=<null>,pressure=1021.0,pressureTrend=down,ozone=<null>,uvIndex=<null>],Clouds[percent=90],Condition[text=Nebel,lastUpdate=Fri Sep 14 08:03:14 CEST 2018,observationTime=Fri Sep 14 07:20:00 CEST 2018,id=741,icon=50d,commonId=fog],Precipitation[rain=0.0,snow=0.0,probability=<null>,total=<null>],Wind[speed=5.399999995680001,direction=SSE,degree=160,gust=<null>,chill=<null>],Station[name=Paderborn,id=<null>,latitude=51.7191,longitude=8.7544,altitude=<null>],<null>]
2018-09-14 08:03:14.084 [DEBUG] [nal.provider.AbstractWeatherProvider] - OPENWEATHERMAP[home]: Forecast[day=0,Temperature[current=<null>,min=8.4,max=20.12,feel=<null>,dewpoint=<null>],Atmosphere[humidity=63,visibility=<null>,pressure=1001.79,pressureTrend=<null>,ozone=<null>,uvIndex=<null>],Clouds[percent=8],Condition[text=Klarer Himmel,lastUpdate=Fri Sep 14 08:03:14 CEST 2018,observationTime=Fri Sep 14 13:00:00 CEST 2018,id=800,icon=02d,commonId=sunny],Precipitation[rain=0.0,snow=0.0,probability=<null>,total=<null>],Wind[speed=5.1119999959104,direction=S,degree=169,gust=<null>,chill=<null>],Station[name=<null>,id=<null>,latitude=<null>,longitude=<null>,altitude=<null>],<null>]
2018-09-14 08:03:14.088 [DEBUG] [nal.provider.AbstractWeatherProvider] - OPENWEATHERMAP[home]: Forecast[day=1,Temperature[current=<null>,min=6.18,max=17.89,feel=<null>,dewpoint=<null>],Atmosphere[humidity=60,visibility=<null>,pressure=1003.65,pressureTrend=<null>,ozone=<null>,uvIndex=<null>],Clouds[percent=0],Condition[text=Leichter Regen,lastUpdate=Fri Sep 14 08:03:14 CEST 2018,observationTime=Sat Sep 15 13:00:00 CEST 2018,id=500,icon=10d,commonId=few-showers],Precipitation[rain=0.61,snow=0.0,probability=<null>,total=<null>],Wind[speed=22.211999982230402,direction=W,degree=265,gust=<null>,chill=<null>],Station[name=<null>,id=<null>,latitude=<null>,longitude=<null>,altitude=<null>],<null>]

Does anyone have recommendations on migrating from Wunderground to another service?

I’m moving to OpenWeatherMap. First attempts are looking very good. With 2.4 there ist even a brand new binding.

They just announced that old Wunderground API will continue working until 2019-02-15.
For PWS owners there will be a new free API with following features:

  • Current observations from the PWS network
  • 5 day daily forecast
  • PWS historical data
  • PWS lookup by geocode, zip code and location
  • Call volume: 1500/day, 30/minute

API docs

For posting PWS data:

  • Wunderground
  • OpenWeatherMap
  • WeatherCloud (no public API but you can get the API docs after contacting them, I just received them)

For getting weather data:

  • OpenWeatherMap
  • DarkSky (1000 free calls per day, Java libraries available)
  • Aerisweather (PWSWeather belongs to it and seems like they are going to offer free services soon for PWS data uploaders)
  • Wunderground/IBM Weather (new free API TBA for PWS uploaders)
  • plus various commercial services

The question is, which one of those free APIs is able to offer a reliable forecast. I guess it will be a mix of multiple APIs to get useful information.

My API key finally crapped out today. I guess I got few more days out of it than they announced. It was nice while it lasted.

Hi bitwalker
I have a PWS and working weather underground connection.
Can you please explain how can I get the api key so I can yue the wunderground binding in the future?

To the best of my knowledge, after February 15, the wunderground binding will no longer work, even if you are uploading your PWS data to wunderground. As I understand it, they will allow PWS users to access another service using an API that’s not compatible with the API that the binding currently uses. If this is the case, which I think it is based on the emails I got from them, it will require significant rework to the wunderground binding, or possibly a brand new binding.

1 Like

Here’s the content of the last email I got.

We’d like to reiterate a few things and let you know of a few small timing changes as we move closer to the previously announced retirement of the Weather Underground API:

  • Based on the response to the previous announcement as we neared year end, we have extended the retirement date to February 15, 2019 to allow you more transition time.
  • All Weather Underground API keys will stop working on February 15, 2019 unless otherwise agreed upon with Weather Underground.
  • All credit card charges for existing Weather Underground API subscriptions will stop on December 26, 2018.

Personal Weather Station (PWS) owners/contributors will continue to be eligible for a free replacement API service selected from our IBM/Weather Company standard offerings that contain:

  • Current observations from the PWS network
  • 5 day daily forecast
  • PWS historical data
  • PWS lookup by geocode, zip code and location
  • Call volume: 1500/day, 30/minute

You can check out our PWS contributor replacement API documentation here.

thank you

FYI, I got this email today from Weather Underground.

Let me thank you for being such a wonderful, patient group. As we approach the closing date for the Weather Underground API on February 15, 2019, several of you have asked for updates. So I want to share with you what I know at this moment.

  1. We are hoping that the gateway for obtaining keys on the new API will open on February 15, 2019. In order to provide PWS uploaders with time to transition their API calls, all current WU API keys that are linked to a PWS will stay open through Friday, March 1, 2019. That gives you two full weeks to sign up for a new key and change your calls.

  2. For those who already use the WU API, not all API keys are linked to the PWS. If you used two different email addresses when setting up the PWS and API key, they may not be connected. If you are concerned that they are not connected, please contact me and let me check. If they are not, I can make sure they are connected in my database so that your key is not shut off. I have verified whether the API key sent to me is safe or not, and if not, put it in the protected key list. You will receive a second email from me if your key is among this group.

  3. I continue to maintain an email list for news about the transition to the new API for PWS owners. If you know others who would like me to add them to the list, please have them email me with their PWS id, which I use to verify that you are eligible for the PWS API.

The link to the most recent update on the Forum, with links to documentation and details about data:

Darksky seems promising, currently converting my http calls to the darksky json format

For all PWS owner, who dont want to send actual values for free to The Weather Company or have trouble to get the own data back: Here is my solution (running on a RaspPi).

Quick overview:
Grab data direct from the PWS and publish the values via MQTT (and send the values to TWC optional).
I use dnsmasq to tell the PWS, that has the IP of my RaspPi. So the PWS will connect to the RaspPi instead and here I have a faked web resource, which is called from the PWS. I get the data direct from the stream and publish the values using MQTT. The advantage is, that now I have real time data inside OH (previously there was an interval of 10 minutes).


  • Running MQTT server in the local network
  • Running PiHole on the RaspPi
  • Known IP of the PWS in the local network

Step by step solution:


  • Restart the PiHole-DNS and grab the Request from the PWS to the Wunderground

pihole restartdns
tcpdump -i eth0 | grep IP-OF-THE-PWS

  • The result looks like this snipped (Pass, StationID and IP’s are masked)

14:16:59.806268 IP pi.domain > IP-OF-THE-PWS.4096: 16393* 1/0/0 A IP-OF-THE-RASPPI (59)
14:17:00.670179 IP IP-OF-THE-PWS.4096 > pi.domain: 61110+ A? (43)
14:17:00.671110 IP pi.domain > IP-OF-THE-PWS.4096: 61110* 1/0/0 A IP-OF-THE-RASPPI (59)
14:17:00.674636 IP IP-OF-THE-PWS.33793 > pi.http: Flags [S], seq 635269079, win 5840, options [mss 1460], length 0
14:17:00.674746 IP pi.http > IP-OF-THE-PWS.33793: Flags [S.], seq 129840048, ack 635269080, win 29200, options [mss 1460], length 0
14:17:00.682486 IP IP-OF-THE-PWS.33793 > pi.http: Flags [P.], seq 1:524, ack 1, win 5840, length 523: HTTP: GET /weatherstation/updateweatherstation.php?ID=STATIONID&PASSWORD=**********&indoortempf=69.8&tempf=62.2&dewptf=51.6&windchillf=62.2&indoorhumidity=43&humidity=68&windspeedmph=1.8&windgustmph=2.2&winddir=206&absbaromin=28.61&baromin=29.47&rainin=0.00&dailyrainin=0.00&weeklyrainin=0.01&monthlyrainin=0.03&yearlyrainin=-9999&solarradiation=110.10&UV=1&dateutc=2019-4-8%2012:16:55&softwaretype=EasyWeatherV1.1.4&action=updateraw&realtime=1&rtfreq=5 HTTP/1.0
14:17:00.682598 IP pi.http > IP-OF-THE-PWS.33793: Flags [.], ack 524, win 30016, length 0
14:17:00.689531 IP pi.http > IP-OF-THE-PWS.33793: Flags [P.], seq 1:179, ack 524, win 30016, length 178: HTTP: HTTP/1.0 200 OK

  • Create or edit the file /etc/lighttpd/external.conf on the RaspPi and add the next lines
    $HTTP[“host”] == “” {
    # Undo Pi-hole Javascript Redirect
    url.rewrite = ("^(?!.)…js$" => “.*.js”)
    # root website
    server.document-root = “/var/www/html/”
  • Create or edit the file /etc/dnsmasq.d/customRedirect.conf on the RaspPi and add one line


  • Create or edit the file /etc/customRedirect.list on the RaspPi and add one line IP-OF-THE-RASPPI

  • Create the file /var/www/html/weatherstation/updateweatherstation.php with the next content:


    $WunderGroundIP = “”;

    $MOSQUITTO_IP = “”;
    $MOSQUITTO_PORT = 1883;
    $MOSQUITTO_USER = “User”;
    $MOSQUITTO_PASS = “Pass”;
    $MOSQUITTO_PATH = “state/wunderground/current/”;

    $ID = $_GET[‘ID’];
    $tempO = $_GET[‘tempf’];
    $tempI = $_GET[‘indoortempf’];
    $dewpt = $_GET[‘dewptf’];
    $windChill = $_GET[‘windchillf’];
    $humidityI = $_GET[‘indoorhumidity’];
    $humidityO = $_GET[‘humidity’];
    $windSpeed = $_GET[‘windspeedmph’];
    $windGustSpeed = $_GET[‘windgustmph’];
    $windDir2 = $_GET[‘winddir’];
    $absBaroMin = $_GET[‘absbaromin’];
    $baroMin = $_GET[‘baromin’];
    $rain = $_GET[‘rainin’];
    $dailyRain = $_GET[‘dailyrainin’];
    $weeklyRain = $_GET[‘weeklyrainin’];
    $monthlyRain = $_GET[‘monthlyrainin’];
    $yearlyRain = $_GET[‘yearlyrainin’];
    $solar = $_GET[‘solarradiation’];
    $UV = $_GET[‘UV’];

    $strCmd = 'mosquitto_pub -h ’ . $MOSQUITTO_IP . ’ -p ’ . $MOSQUITTO_PORT . ’ -u ’ . $MOSQUITTO_USER . ’ -P ’ . $MOSQUITTO_PASS . ’ -t ’ . $MOSQUITTO_PATH;
    shell_exec ($strCmd . ‘tempO -m "’ . ($tempO-32)*5/9 . ‘"’);
    shell_exec ($strCmd . ‘tempI -m "’ . ($tempI-32)*5/9 . ‘"’);
    shell_exec ($strCmd . ‘solar -m "’ . $solar . ‘"’);
    shell_exec ($strCmd . ‘dewpt -m "’ . ($dewpt-32)*5/9 . ‘"’);
    shell_exec ($strCmd . ‘windChill -m "’ . ($windChill-32)*5/9 . ‘"’);
    shell_exec ($strCmd . ‘humidityO -m "’ . $humidityO . ‘"’);
    shell_exec ($strCmd . ‘humidityI -m "’ . $humidityI . ‘"’);
    shell_exec ($strCmd . ‘windSpeed -m "’ . $windSpeed*1.609 . ‘"’);
    shell_exec ($strCmd . ‘windGustSpeed -m "’ . $windGustSpeed*1.609 . ‘"’);
    shell_exec ($strCmd . ‘windDir2 -m "’ . $windDir2 . ‘"’);
    if ($windDir2 > 0 && $windDir2 < 23) {
    $windDir = “Nord”;
    } else if ($windDir2 > 23 && $windDir2 < 68) {
    $windDir = “Nord-Ost”;
    } else if ($windDir2 > 68 && $windDir2 < 113) {
    $windDir = “Ost”;
    } else if ($windDir2 > 113 && $windDir2 < 158) {
    $windDir = “Süd-Ost”;
    } else if ($windDir2 > 158 && $windDir2 < 203) {
    $windDir = “Süd”;
    } else if ($windDir2 > 203 && $windDir2 < 248) {
    $windDir = “Süd-West”;
    } else if ($windDir2 > 248 && $windDir2 < 293) {
    $windDir = “West”;
    } else if ($windDir2 > 293 && $windDir2 < 338) {
    $windDir = “Nord-West”;
    } else if ($windDir2 > 338 && $windDir2 < 361) {
    $windDir = “Nord”;
    shell_exec ($strCmd . ‘windDir -m "’ . $windDir . ‘"’);
    shell_exec ($strCmd . ‘absBaroMin -m "’ . $absBaroMin*33.8638815789 . ‘"’);
    shell_exec ($strCmd . ‘baroMin -m "’ . $baroMin*33.8638815789 . ‘"’);
    shell_exec ($strCmd . ‘rain -m "’ . $rain . ‘"’);
    shell_exec ($strCmd . ‘dailyRain -m "’ . $dailyRain . ‘"’);
    shell_exec ($strCmd . ‘weeklyRain -m "’ . $weeklyRain . ‘"’);
    shell_exec ($strCmd . ‘monthlyRain -m "’ . $monthlyRain . ‘"’);
    shell_exec ($strCmd . ‘yearlyRain -m "’ . $yearlyRain . ‘"’);
    shell_exec ($strCmd . ‘UV -m "’ . $UV . ‘"’);

    $strURL = $WunderGroundIP . “/weatherstation/updateweatherstation.php”;
    $strURL .= $_SERVER[‘QUERY_STRING’];

    // file_get_contents ($strURL);
    echo “success”;


  • If you want to send the PWS data to TWC too, then uncomment the line with file_get_contents.


If you got a new API-KEY from The Weather Company: Here is a small PHP-Code to call the new api (described here ) and convert the result to MQTT-Posts.

I run this code via cron job every 30 minutes (the interval, that IBM provide).


$MOSQUITTO_PATH = "state/wunderground/fc_";

function MQTTsend ($mqttSubPath, $mqttSubName, $value) {
  $strPath = $GLOBALS['MOSQUITTO_PATH'] . $mqttSubPath . "/";
  $strCmd = 'mosquitto_pub -h ' . $GLOBALS['MOSQUITTO_IP'] . ' -p ' . $GLOBALS['MOSQUITTO_PORT'] . ' -u ' . $GLOBALS['MOSQUITTO_USER'] . ' -P ' . $GLOBALS['MOSQUITTO_PASS'] . ' -t ' . $strPath;

  shell_exec ($strCmd . $mqttSubName . ' -m "' . $value . '"');

$strForecast = file_get_contents ("******************");
$arrJSON = json_decode ($strForecast, TRUE);
$arrCommonKeys = array ('temperatureMax', 'temperatureMin', 'dayOfWeek', 'narrative', 'qpf', 'qpfSnow', 'moonPhase', 'moonPhaseCode', 'moonPhaseDay', 'moonriseTimeLocal', 'moonsetTimeLocal', 'sunsetTimeLocal', 'sunriseTimeLocal');
$arrDaypartKeys = array ('dayOrNight', 'cloudCover', 'daypartName', 'iconCode', 'iconCodeExtend', 'narrative', 'precipChance', 'precipType', 'qpf', 'qpfSnow', 'qualifierPhrase', 'qualifierCode', 'relativeHumidity', 'snowRange', 'temperature', 'temperatureHeatIndex', 'temperatureWindChill', 'thunderCategory', 'thunderIndex', 'uvDescription', 'uvIndex', 'windDirection', 'windDirectionCardinal', 'windPhrase', 'windSpeed', 'wxPhraseLong', 'wxPhraseShort');

for ($i = 0; $i < 6; $i++) {

  foreach ($arrCommonKeys as $k) {
    MQTTsend ($i, $k, $arrJSON[$k][$i]);

$arrJSON = $arrJSON['daypart'][0];

for ($i = 0; $i < 12; $i++) {

  $strSubPath = $arrJSON['dayOrNight'][$i] . floor ($i / 2);
  foreach ($arrDaypartKeys as $k) {
    MQTTsend ($strSubPath, $k, $arrJSON[$k][$i]);


The common forecast values are in MQTT path state/wunderground/fc_X (X = 0-6 = Today-5 days in future). The detailed forecasts are in MQTT path state/wunderground/fc_DX or state/wunderground/fc_NX (D=Day, N=Night, X = 0-6 = Today-5 days in future). Here is a snippet from the MQTT-log:

state/wunderground/fc_0/temperatureMax 5
state/wunderground/fc_0/temperatureMin -1
state/wunderground/fc_0/dayOfWeek Freitag
state/wunderground/fc_0/narrative Bedeckt. Höchsttemperaturen 4 bis 6C und Tiefsttemperaturen -2 bis 0C.
state/wunderground/fc_0/qpf 0
state/wunderground/fc_0/qpfSnow 0
state/wunderground/fc_0/moonPhase erstes Viertel
state/wunderground/fc_0/moonPhaseCode FQ
state/wunderground/fc_0/moonPhaseDay 7
state/wunderground/fc_0/moonriseTimeLocal 2019-04-12T10:59:48+0200
state/wunderground/fc_0/moonsetTimeLocal 2019-04-12T02:36:37+0200
state/wunderground/fc_0/sunsetTimeLocal 2019-04-12T19:56:44+0200
state/wunderground/fc_0/sunriseTimeLocal 2019-04-12T06:18:59+0200
state/wunderground/fc_1/temperatureMax 7
state/wunderground/fc_1/temperatureMin 1
state/wunderground/fc_1/dayOfWeek Samstag
… Snipp …
state/wunderground/fc_D0/temperature 5
state/wunderground/fc_D0/temperatureHeatIndex 5
state/wunderground/fc_D0/temperatureWindChill -2
state/wunderground/fc_D0/thunderCategory (null)
state/wunderground/fc_D0/thunderIndex 0
state/wunderground/fc_D0/uvDescription Niedrig
state/wunderground/fc_D0/uvIndex 1
state/wunderground/fc_D0/windDirection 45
state/wunderground/fc_D0/windDirectionCardinal NO
state/wunderground/fc_D0/windPhrase Wind aus NO mit 10 bis 15 km/h.
state/wunderground/fc_D0/windSpeed 15
state/wunderground/fc_D0/wxPhraseLong Bedeckt
state/wunderground/fc_D0/wxPhraseShort (null)
state/wunderground/fc_N0/dayOrNight N
state/wunderground/fc_N0/cloudCover 70
state/wunderground/fc_N0/daypartName Heute Abend
state/wunderground/fc_N0/iconCode 29
state/wunderground/fc_N0/iconCodeExtend 9000
state/wunderground/fc_N0/narrative Über Nacht aufklarend. Tiefsttemperatur -1C. Wind aus NO mit 10 bis 15 km/h.
state/wunderground/fc_N0/precipChance 10
… Snipp …
state/wunderground/fc_N1/windSpeed 16
state/wunderground/fc_N1/wxPhraseLong Später Regen/Schneefall
state/wunderground/fc_N1/wxPhraseShort (null)
state/wunderground/fc_D2/dayOrNight D
state/wunderground/fc_D2/cloudCover 97
state/wunderground/fc_D2/daypartName Sonntag
state/wunderground/fc_D2/iconCode 5

Have fun.

I probably should’ve posted this link to my new Weather Company binding sooner, but here it is in case anyone is interested in trying it out. At some point, when the queue of new binding PRs dies down a bit, I’ll submit it for inclusion in the distro.