MarkDH102
Posts: 673
Joined: Fri Feb 13, 2015 3:18 pm

New weather API from the MetOffice (worldwide)

Tue Jan 21, 2020 4:26 pm

I've seen a few posts on here regarding getting weather information.
The Metoffice (UK) now provides such information for worldwide locations.

https://metoffice.apiconnect.ibmcloud.c ... roduction/

I have written a small snippet of Python that will pull back rain/wind/temperature and a weather 'code' on the hourly spot data if anyone is interested...
The latitude and longitude I use are for my area of Astley in Worcestershire (UK)
YOU WILL HAVE TO CHANGE THE KEYS FOR YOUR OWN FOR THIS TO WORK!!!

Code: Select all

# Mark Hollingworth
# 18-1-20
# Version 2
# Make use of the new MetOffice DataHub api
# Up to 360 requests per day (free)
# Up to 10000 per month (free)

import time
import requests
import curses
import sys
import http.client
import json

conn = http.client.HTTPSConnection("api-metoffice.apiconnect.ibmcloud.com")

# Replace these with your key and secret
headers = {
    'x-ibm-client-id': "YOUR_CLIENT_ID",
    'x-ibm-client-secret': "YOUR_CLIENT_SECRET",
    'accept': "application/json"
}

def getWeatherNewAPI():
    # No error
    retVal = 0

    key.addstr(5, 0, "Temp (C)")
    key.addstr(5, 10, "Code")
    key.addstr(5, 20, "Wind (mph)")
    key.addstr(5, 40, "Rain (%)")
    key.addstr(5, 50, "Time (UTC)")

    if 0 == 0 : #try :
        # Replace latitude and longiture with your own
        conn.request("GET", "/metoffice/production/v0/forecasts/point/hourly?excludeParameterMetadata=false&includeLocationName=true&latitude=52.29098&longitude=-2.3374", headers=headers)

        res = conn.getresponse()
        data = res.read()

        data_decoded = data.decode("utf-8")
        f = open("temp.txt", "w")
        f.write(data_decoded)
        f.close()

        data_dict = json.loads(data_decoded)
        if not isinstance(data_dict, dict) :
            key.addstr(14, 0, "Not successfully converted into a dictionary - check API key")
            retVal = 3
        else :
            location = (data_dict['features'][0]['properties']['location']['name'])

            key.addstr(12, 0, "Location found is : {}".format(location))

            time0 = (data_dict['features'][0]['properties']['timeSeries'][0]['time'])
            windSpeed0 = (data_dict['features'][0]['properties']['timeSeries'][0]['windSpeed10m'])
            temperature0 = (data_dict['features'][0]['properties']['timeSeries'][0]['screenTemperature'])
            probofrain0 = (data_dict['features'][0]['properties']['timeSeries'][0]['probOfPrecipitation'])
            swc0 = (data_dict['features'][0]['properties']['timeSeries'][0]['significantWeatherCode'])

            key.addstr(6, 0, "{}".format(temperature0))
            key.addstr(6, 10, "{}".format(swc0))
            # Convert m/s to mph
            key.addstr(6, 20, "{}".format(int(float(windSpeed0 * 2.23694))))
            key.addstr(6, 40, "{}".format(probofrain0))
            key.addstr(6, 50, "{}".format(time0))

            time1 = (data_dict['features'][0]['properties']['timeSeries'][1]['time'])
            windspeed1 = (data_dict['features'][0]['properties']['timeSeries'][1]['windSpeed10m'])
            temperature1 = (data_dict['features'][0]['properties']['timeSeries'][1]['screenTemperature'])
            probofrain1 = (data_dict['features'][0]['properties']['timeSeries'][1]['probOfPrecipitation'])
            swc1 = (data_dict['features'][0]['properties']['timeSeries'][1]['significantWeatherCode'])

            key.addstr(7, 0, "{}".format(temperature1))
            key.addstr(7, 10, "{}".format(swc1))
            # Convert m/s to mph
            key.addstr(7, 20, "{}".format(int(float(windspeed1 * 2.23694))))
            key.addstr(7, 40, "{}".format(probofrain1))
            key.addstr(7, 50, "{}".format(time1))

            time2 = (data_dict['features'][0]['properties']['timeSeries'][2]['time'])
            windspeed2 = (data_dict['features'][0]['properties']['timeSeries'][2]['windSpeed10m'])
            temperature2 = (data_dict['features'][0]['properties']['timeSeries'][2]['screenTemperature'])
            probofrain2 = (data_dict['features'][0]['properties']['timeSeries'][2]['probOfPrecipitation'])
            swc2 = (data_dict['features'][0]['properties']['timeSeries'][2]['significantWeatherCode'])

            key.addstr(8, 0, "{}".format(temperature2))
            key.addstr(8, 10, "{}".format(swc2))
            # Convert m/s to mph
            key.addstr(8, 20, "{}".format(int(float(windspeed2 * 2.23694))))
            key.addstr(8, 40, "{}".format(probofrain2))
            key.addstr(8, 50, "{}".format(time2))

            time3 = (data_dict['features'][0]['properties']['timeSeries'][3]['time'])
            windspeed3 = (data_dict['features'][0]['properties']['timeSeries'][3]['windSpeed10m'])
            temperature3 = (data_dict['features'][0]['properties']['timeSeries'][3]['screenTemperature'])
            probofrain3 = (data_dict['features'][0]['properties']['timeSeries'][3]['probOfPrecipitation'])
            swc3 = (data_dict['features'][0]['properties']['timeSeries'][3]['significantWeatherCode'])
    
            key.addstr(9, 0, "{}".format(temperature3))
            key.addstr(9, 10, "{}".format(swc3))
            # Convert m/s to mph
            key.addstr(9, 20, "{}".format(int(float(windspeed3 * 2.23694))))
            key.addstr(9, 40, "{}".format(probofrain3))
            key.addstr(9, 50, "{}".format(time1))
    """
    except (requests.ConnectionError, requests.Timeout, requests.RequestException):
        # Presumably , no internet connection...
        retVal = 1
    except :
        retVal = 2
        key.addstr(14, 0, "Unknown Error! {}".format(sys.exc_info()[0]))
    """
    return retVal

# Start of the main code

key = curses.initscr()
curses.noecho()
key.keypad(1)
key.nodelay(1)
key.clear()

quitPressed = 0
intReqCount = 1

# This is the main loop - do forever
while (quitPressed == 0) :
    # Start with "not good", getWeatherNewAPI() returns 0 if data is good
    goodData = 1
    doReq = False
    # Check between 6AM and 8PM	
    if ( (time.localtime().tm_hour >= 6) and (time.localtime().tm_hour < 20) ) :
        doReq = True
        key.addstr(0, 0, "")
        key.clrtoeol()
        key.addstr(0, 0, "Performing request")
        key.refresh()
        intReqCount += 1
        goodData = getWeatherNewAPI()

    if doReq == False :
        key.clear()
        key.addstr(2, 0, "Not in checking time zone")
        everythingOff()
        intReqCount = 0
    else :
        key.addstr(2, 0, "")
        key.clrtoeol()
        key.addstr(2, 0, "Request count {} ".format(intReqCount))
        key.refresh()

    # Now go to sleep for approx 15 minutes - but keep checking for q/o/s keys
    key.addstr(0, 0, "")
    key.clrtoeol()
    key.addstr(0, 0, "Press <q to Quit> <o/s to Override/Stop Override> ")
    key.refresh()

    c = 0
    while (c != 900) :
        c += 1
        if goodData != 0 :
            # Force a new request for data in 30s
            c = 870
            goodData = 0

        time.sleep(1)

        k = key.getch()
        if k > -1 :
            if k == ord('q') :
                quitPressed = 1
                break
    key.clear()

key.keypad(0)
curses.echo()
curses.endwin()

User avatar
neilgl
Posts: 6840
Joined: Sun Jan 26, 2014 8:36 pm
Location: Near The National Museum of Computing

Re: New weather API from the MetOffice (worldwide)

Wed Jan 22, 2020 10:35 am

Thanks

Return to “General discussion”