Back to post index

Generating weather forecast SMS messages using forecast.io and voip.ms
Tags: [Python] [forecast.io] [voip.ms]
Published: 05 Feb 2016 08:30

Gluing together the APIs of forecast.io and voip.ms with a bit of Python provides the ability to generate SMS messages containing the day’s weather forecast.

Register for an API key from forecast.io. Then, get the forecast with a simple GET request (filling in information like the API key and the desired location):

import json
import requests

url = "https://api.forecast.io/forecast/<apikey>/<lat>,<long>"
forecast_request = requests.get(url)
query = json.loads(forecast_request.text)

Generate your text message, remembering to keep it below 160 characters:

str_resp  = "It's %.1f C" % (query['currently']['temperature'])
str_resp += " (feels like %.1f C)." % (query['currently']['apparentTemperature'])

temp_list = [[x['temperature'], x['apparentTemperature']] for x in query['hourly']['data'][0:12]]
temp_list = sorted(temp_list, key=lambda x: x[1])

str_resp += " Low/high for next 12 hours is %.1f (%.1f) / %.1f (%.1f)." %(
		temp_list[0][0], temp_list[0][1],
		temp_list[-1][0], temp_list[-1][1],
		)

if len(str_resp + " " + query['hourly']['summary']) < 160:
	str_resp += " " + query['hourly']['summary']

This generates messages like the following:

It's -2.3 C (feels like -4.5 C). Low/high for next 12 hours is
-2.3 (-4.5) / 3.6 (-0.1). Flurries tonight.

To send this as an SMS using the voip.ms API, login and then go to their API page to generate an API password, enable the API, and enter the IP address you’ll be making requests from.

Then, provide parameters for their rest.php endpoint:

def send_sms(dst, text):
	voip_post = {
		"api_username" : "<your email>",
		"api_password" : "<your API key>",
		"method" : "sendSMS",
		"did" : "<your voip.ms DID with SMS enabled>",
		"dst" : dst,
		"message" : text
	}

	base_url = "https://voip.ms/api/v1/rest.php?"
	add_ons = []

	for k in voip_post.keys():
		add_ons.append(k + "=" + voip_post[k])

	url = base_url + "&".join(add_ons)

	voip_result = requests.get(url)
	voip_result = voip_result.text
	voip_result = json.loads(voip_result)

	# optionally check voip_result fields here

This creates a URL that will resemble

rest.php?api_username=test@fake.com&api_password=testpostpleaseignore&method=sendSMS&...

(Note that I had trouble using very long API keys - my working API password is 25 characters. I didn’t binary search the upper limit or anything, just chopped my 64 character password arbitrarily)

And that’s all that is required. I call the complete Python script using cron every morning: