AccuWeather API Python Code

Here is a quick and dirty snippet of Python code to get you started with the AccuWeather API. Note that it offers no fault tolerance, optimization, or other things you might expect to find in finished software and only extracts a small subset of the data available in the JSON data.

import json
import time
import urllib.request

API = YOUR_API
LOCATION_ID = LOCATION



def get_weather(api, location_id):
    url = 'http://dataservice.accuweather.com/currentconditions/v1/%s?apikey=%s&details=true' % (location_id, api)
    print(url)
    with urllib.request.urlopen(url) as url:
        data = json.loads(url.read().decode())
    print(data)
    return (data[0]['Temperature']['Imperial']['Value'],
            data[0]['RelativeHumidity'],
            data[0]['Wind']['Direction']['Degrees'],
            data[0]['Wind']['Speed']['Imperial']['Value'],
            data[0]['UVIndex'],
            data[0]['CloudCover'],
            data[0]['Pressure']['Metric']['Value'],
            data[0]['Precip1hr']['Metric']['Value'],
            data)


timestamp = time.time()

temperature, humidity, wind_bearing, wind_speed, uv_index, cloud_cover, pressure, precipitation, raw \
    = get_weather(API, LOCATION_ID)

 

Advertisements

AccuWeather API

First up in my series on weather APIs is the one from AccuWeather.

There are a few really great things about this API–or rather this set of APIs–but first let me tell you about the downsides. Accuweather doesn’t use a standardized system for locations so, as far as I can tell, there isn’t a way to simply input Lat/Lon coordinates. Instead your first stop on any journey has to be with their location finding API. Not only is this counter-intuitive, but since they only provide 40 free hits to their API a day, having to make regular checks for different locations could quickly eat up your allotment. Furthermore since forecast, current conditions, and indexes are all separate APIs, you are likely to be making a lot more calls than you would with a service like Darksky. I don’t mean to complain–after all they do offer access for free and 40 API calls is more than enough for the average hobbyist–but it seems stingy in comparison to most other services.

On the other hand, the API provides a superb data set that is easy to navigate and is clearly described in their documentation. Just take a look at their current conditions API which is well documented and includes all sorts of numbers that I didn’t even know were things–honestly did you know what “wet bulb temperature” was before reading that page? Similarly the forecast API offers things like pollen and air pollution information which must APIs lack.

Importantly AccuWeather does not suffer from the “disappearing metric” problem which plagues many APIs–more on this later.

The AccuWeather API may be right for you if your needs are limited to a single location and only a few updates a day. But if your location needs are more complex or want minute-by-minute updates. Also I think that AccuWeather only outputs to JSON, so if you are an XML head you are out of luck. For my particular use–graphing weather data for general interest and to compare to internal sensor data–AccuWeather works well and may come the closest to being an all-in-one solution. I just really wish that they supported more options for location input.

In my next post, I will share some example Python code which will show you how easy it is to get up and running with this API.

 

MQTT Cookbook: Round-trip Time

Most MQTT brokers provide statistics on what they are doing (number of messages sent etc.) but do not provide meaningful information about how well the broker and client are performing. To gather that sort of information you need to consider the entire chain between the client and the broker. Although there may be several different ways to approach this, the simplest is to measure the round-trip time or RTT. In the case of MQTT that means measuring how long it takes from the publication of a message to its distribution to subscribers.

Thankfully the loose coupling between publishers and subscribers in MQTT allows the same client to be both. This allows us to measure the entire chain in a few lines of code.

import paho.mqtt.client as mqtt
from time import time, sleep
import uuid

INTERVAL = 1
QOS = 0


def on_connect(client, userdata, flags, rc):
    client.subscribe(topic)
    client.publish(topic, time(), qos=QOS)


def on_message(client, userdata, message):
    msg = message.payload.decode('utf-8')
    rtt = time() - float(msg)
    rtt_array.append(rtt)
    rtt_max = max(rtt_array)
    rtt_average = sum(rtt_array) / len(rtt_array)
    rtt_min = min(rtt_array)
    print('Current: %s' % rtt)
    print('Maximum: %s' % rtt_max)
    print('Average: %s' % rtt_average)
    print('Minimum: %s' % rtt_min)
    sleep(INTERVAL)
    client.publish(topic, time(), qos=QOS)


def on_log(client, userdata, level, buf):
    print(level, buf)


rtt_array = []
topic = str(uuid.uuid4())
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.on_log = on_log
client.connect("test.mosquitto.org")
client.loop_forever()

 

The script might seem a bit odd unless you understand how the call backs are structured in MQTT. The program flow goes something like this:

  1. The client connects to the broker triggering on_connect
  2. The client subscribes to the randomly determined topic
  3. The client publishes to the randomly determined topic
  4. The reception of the message that the client published triggers the on_message callback.
  5. The payload of the message is the time the message was sent which is then compared to the current time to get the RTT
  6. The RTT is added to the list rtt_array and used to calculate average, maximum, and minimum.
  7. After sleeping for INTERVAL seconds, a new message is published to the the topic returning the script to step 3.

As this script runs indefinitely you will have to break it manually by hitting CTRL+C. Also, the preset interval is pretty short (1 second), you will likely want to extend that to 10 or 60 if you are running this for more than a short burst.

Right now the script is configured to connect to the test.mosquitto.org server but it can easily be adapted to connect to your local broker.

Another interesting use of this script is that it makes it simple to test the performance consequences of using higher QoS settings. I notice around a 50% performance hit at QoS 2.

That’s pretty much it. If anyone has suggestions about how to improve it, tell me about them in the comments.

WeMos D1 Mini First Impressions

Just got a $3 WeMos D1 Mini in the mail and I thought I would share a few very quick thoughts about it.

  1. This thing is tiny. It’s funny I knew it was small, but it still amazes me that you can squeeze effectively a small computer in the space of  a couple of postage stamps.
  2. The fit and finish seems pretty good for a $3 board. What an age we live in!
  3. Loading Micropython took longer than it should have but that may have been user error. This tutorial is pretty good.
  4. The LED turns on when the pin is low and off when the pin is high. Huh?
  5. Micropython is pretty awesome so far. I’m sure Arduino is more efficient but with 160 Mhz of process power and a couple of megs of space, I’m not worrying!
  6. Connecting with screen works but not picocom? Weirdness.
  7. The machine library in MicroPython is pretty handy, a good replacement for a lot of the Arduino built-ins.
  8. There is no consensus about how to capitalize Micropython. Is it micropython, Micropython, MicroPython, etc. This frustrates the copy editor in me.
  9. Wait… do I just pull the plug to turn this thing off? That feels wrong but I guess it is what I always did with my other ESP8266 boards… But it feels weird not to shut down something that has an interactive prompt.

Alright, those are some quick thoughts, more later.

MQTT Cookbook: Thingspeak to MQTT

One of the most common problems in IoT is the need to bridge between two different infrastructures. It is a long story, but I ran into a situation where I needed to bridge a pre-existing ESP8266 connected to Thingspeak with my broader MQTT network. Thankfully, hacking together a quick bridge between the two services proved fairly easy.

import requests
import paho.mqtt.client as mqtt

CHANNEL =
API = ""

def get_thingspeak_field(channel, api, field):
    _url = 'https://api.thingspeak.com/channels/%s/fields/%s.json?api_key=%s&results=1' % (channel, field, api)
    _r = requests.get(_url).json()
    return _r['feeds'][0]['field%s' % field]


def on_connect(client, userdata, flags, rc):
    client.publish('thingspeak/field1', field1)
    client.publish('thingspeak/field2', field2)
    client.disconnect()


def on_log(client, userdata, level, buf):
    print(level, buf)


field1 = get_thingspeak_field(CHANNEL, API, 1)
field2 = get_thingspeak_field(CHANNEL, API, 2)
client = mqtt.Client()
client.on_connect = on_connect
client.on_log = on_log
client.connect("test.mosquitto.org", 1883, 60)
client.loop_forever()

 

The code is fairly self-explanatory but lets walk through it. There is a Thingspeak library for Python but it is actually easier to just import requests and make a standard API request. To facilitate this I wrote a simple function which takes the channel, api key, and the field that you want to read. After reading the fields it connects to an MQTT broker–currently the Mosquitto test broker–and publishes the fields.

Simple as that! Now you can hook your Thingspeak and MQTT infrastructures together in any way you want.

MQTT Cookbook: Logging Activity

It’s been a while since I actually posted here. Between finishing my Ph.D., the frustrations of the academic job market, and working on my book, I haven’t had nearly as much time for hobbies. But I have recently been learning about MQTT and have decided to post some simple “recipe” style Python scripts that would have helped me when I was just starting out.

The first script was inspired by the sudden upsurge of questions on Stack Exchange (such as this one and this one) which deal with logging activity on an MQTT topic. Since Mosquitto (and most other brokers) do not include a database to store messages, you have to implement logging on top of MQTT.

The simplest way to do this is simply to print the output of a topic to a text file. For testing purposes I am using the Mosquitto test broker and a few of the server’s internal metrics.

Continue reading “MQTT Cookbook: Logging Activity”