AllThingsTalk Python SDK

AllThingsTalk Python SDK is designed to offer easy programmatic access to AllThingsTalk Platform. You can use it to implement AllThingsTalk devices on you computer, or on an embedded device like a Raspberry PI.

Here’s a very simple example to whet your appetite:

import random
import time

from allthingstalk import Client, Device, IntegerAsset

class RandomDevice(Device):
    random_number = IntegerAsset()

client = Client('your_device_token')
device = RandomDevice(client=client, id='your_device_id')

while True:
    device.random_number = random.randint(1, 100)
    time.sleep(1)

This code creates an asset named random_number on the device identified by your_device_id, using your_device_token. When that’s done, it repeatedly sets the asset’s value to random numbers between 1 and 100.

Installation

AllThingsTalk Python SDK is a Python 3 library, so make sure you have Python 3 installed. Python 2 won’t work.

With PIP

To install AllThingsTalk Python SDK, run this command in your terminal of choice:

$ pip3 install allthingstalk

We recommend that you install the SDK inside a [Python Virtual Enviroment](https://realpython.com/blog/python/python-virtual-environments-a-primer/). In case you wish to install the package globally, you will probably need to prefix the command with sudo.

This is the preferred way of obtaining AllThingsTalk SDK.

From the source

Note

This is somewhat advanced. Don’t use if installing with PIP will do.

AllThingsTalk SDK is developed in the open on GitHub, where the code is always available.

You can clone the public repository with this command:

$ git clone git://github.com/allthingstalk/python-sdk.git

Or, download the tarball:

$ curl -OL https://github.com/allthingstalk/python-sdk/tarball/master
# optionally, zipball is also available (for Windows users).

Once you have a copy of the source, you can embed it in your own Python package, or install it into your site-packages easily with:

$ cd python-sdk
$ pip3 install .

Examples

If you are new to Python, or to IoT, we recommend our Experiments & Demos.

You can find examples in the examples directory. To get them to your computer or device, either clone the repository, or download the zip.

Tutorial

Some python knowledge is going to be required for using the SDK, but you should be OK with the basics. If you have no prior experience with programming in Python, you should check out The Python Tutorial.

Defining devices

Device definition takes design cues from Django models. If you are familiar with that - awesome, you’ll feel right at home - if not, don’t worry, you’ll be grokking them in no time. Let’s do another example and look at it more closely.

class WeatherStation(Device):
    temperature = NumberAsset(unit='°C')
    forecast = StringAsset(kind=Asset.VIRTUAL)
    reset = BooleanAsset(kind=Asset.ACTUATOR)

Each device you create will subclass AllThingsTalk Device. Device assets are defined as class attributes.

Note

In the examples, it’s assumed that all of allthingstalk is imported into the current package, i.e. from allthingstalk import *.

We’re defining a device called WeatherStation, which has three assets: temperature, forecast, and reset. At this moment, we are not concerning ourselves with how their values are going to be obtained, but how they are going to be modeled in AllThingsTalk Platform.

The assets in this example have different types: NumberAsset, StringAsset, and BooleanAsset. To see other available asset types, you can jump to Assets. To customize an asset’s name or title, see Asset.__init__. They are also of different kinds. Temperature is a SENSOR, which is the default asset kind, forecast is a VIRTUAL, and reset is an ACTUATOR.

Some asset types, like NumberAsset, can be configured with type specific properties - extras [1]. Here, we’re configuring temperature’s unit to '°C', so that there’s no ambiguity about the chosen temperature scale [2].

Connecting to the cloud

The WeatherStation we just defined won’t do anything on its own. It needs to be able to connect to the cloud and bind itself to a device resource identified by an id.

To make this happen, we need to use a client with a WeatherStation instance.

client = Client('your_token')
weather = WeatherStation(client=client, id=id)

Once weather is initialized, the SDK will take the assets from WeatherStation definition and use them to configure the device’s assets on the Platform. If id is not supplied, a new device will be created first.

Warning

Not all clients can create devices. In general, you shouldn’t assume that all of BaseClient methods will be implemented by a given client. Also, when using Client - which does implement most of the client methods - you should keep in mind that the supplied token might not offer sufficient permissions.

By default a AssetMismatchException will be thrown if there’s a type or kind mismatch between the existing assets on the Platform and the assets defined for the device identified by the same name. To overwrite existing assets, initialize the device with overwrite_assets=True

weather = WeatherStation(client=client, id=id, overwrite_assets=True)

Postponed connection

If you don’t want to connect immediately after creating a device, you can set connect argument to False, and use the device’s connect method to connect later. All the arguments available to Device initializers are available to connect as well.

weather = WeatherStation(client=client, id=id, connect=False)
...
# other code
...
weather.connect()

Adding assets

During device development, you might need to append assets to a device after it’s been created. Doing this is as simple as stopping the program, extending the device class with the needed assets (in this case humidity and alert) and restarting.

class WeatherStation(Device):
    temperature = NumberAsset(unit='°C')
    humidity = NumberAsset(unit='%')
    alert = BooleanAsset()
    forecast = StringAsset(kind=Asset.VIRTUAL)
    reset = BooleanAsset(kind=Asset.ACTUATOR)

Using invalid Python identifiers for asset names

In some cases, e.g. when using binary payloads, it might be beneficial to set asset names to integers. Since integers are not valid Python identifiers, you won’t be able to define them within the device class in the same way as other assets, nor use them to listen to feeds and commands. To make this work, you will have to use the name argument when defining your assets, as follows:

class ConstrainedDevice(Device):
    tilt = BooleanAsset(name='2')
    door = BooleanAsset(name='4')

device = ConstrainedDevice(client=..., id=...)
device.tilt = True  # will send data to asset named '2'

Publishing values

Once your device is connected, you’re ready to publish values to the Platform. To publish a value to an asset resource and set its state, simply assign the value to the corresponding field of your Device instance.

weather.temperature = 21.3
weather.humidity = 3.1
weather.alert = False

There is no special “device loop”. You can use pure Python and any of the awesome Python libraries to implement your business logic. For example, with GrovePi Temperature and Humidity Sensor Pro, you could implement the WeatherDevice for real as simply as:

...

while True:
    temperature, humidity = grovepi.dht(SENSOR_PIN, 1)
    weather.temperature = temperature
    weather.humidity = humidity
    time.sleep(1)

...

If you’d like to specify a custom timestamp when sending your sensor data, you can use AssetState

...
import datetime

timestamp = datetime.datetime.utcnow() + datetime.timedelta(days=1)
device.message = AssetState('Hello from the future!', timestamp)
...

Retrieving values

If you need to get an asset state from the cloud, for example after a power loss, you can query the corresponding field of your Device instance. An AssetState instance will be returned.

temperature_state = weather.temperature
print(temperature_state.value)
print(temperature_state.at)

Listening to commands

To listen for commands from reset actuator, do the following:

@WeatherStation.command.reset
def on_reset(device, value, at):
    reset_my_weather_station()

Listening to feeds

If you’d like to implement a separate program to listen to feeds coming from the weather station, specifically from temperature sensor:

@WeatherStation.feed.temperature
def on_reset(device, value, at):
    print('Received %s at %s' % (value, at))

API Reference

If you are looking for information on a specific function, class, or method, this part of the documentation is for you.

Footnotes

[1]Each predefined asset type maps to a predefined asset profile, which in turn maps to AllThingsTalk asset profiles.
[2]Defining the temperature scale is of course optional - the platform will work just fine without it. Nevertheless, specifying units for physical measures is a good practice, and as a bonsu, we’ll be able to see the unit on the Platform interface.