Setting and reading Thing variables via the Python API

I would like to be able to read from and write to the variables of a Thing using the Python API and have a question.

The API documentation here doesn't mention device variables at all, but does talk about properties under the PROPERTIESV2 section.

Are these the correct methods to read and write variables? I.e. are properties and variables equivalent?

It turns out that the PROPERTIESV2 section of the API is the right one for setting and reading Thing variables, but the examples don't work. So below are working Python examples of how to change the value of a Thing variable and how to fetch the value of a Thing variable. I've tested them on Windows running Python 3.10.2 and a Raspberry Pi 4b running 3.8.0. The documentation says it should run on Python 3.7+, but it failed on 3.7.3 on the Raspberry Pi 4b.

If you should want to perform back-to-back write then read, leave a good time between the two. With a 10 second gap I was getting the wrong value 25% of the time. Even with a 15 second gap, I was still getting errors at a rate of 1.5%. Apart from that potential gotcha it seems to work ok.

For these to work you need to install 3 modules into your Python environment: 'arduino-iot-client', 'requests-oauthlib' and 'openapi_client'.

Write to a Thing variable; a Boolean called 'led_state'. Uses the 'properties_v2_publish' method of the 'propertiesV2API'.

import iot_api_client as iot
from openapi_client.rest import ApiException
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session

###################################################################################
# Secret keys and stuff
###################################################################################
CLIENT_ID     = "VVVVVVVVVVVVVVVVVVVV"
CLIENT_SECRET = "WWWWWWWWWWWWWWWWWWWW"
THING_ID      = "XXXXXXXXXXXXXXXXXXXX"
DEVICE_ID     = "YYYYYYYYYYYYYYYYYYYY"
PROPERTY_ID   = "ZZZZZZZZZZZZZZZZZZZZ"  # led_state

###################################################################################
# Generate an access token
# Follows example from:
# https://github.com/arduino/iot-client-py/blob/master/example/main.py
###################################################################################
# Setup the OAuth2 session that'll be used to request the server an access token
oauth_client = BackendApplicationClient(client_id=CLIENT_ID)
token_url = "https://api2.arduino.cc/iot/v1/clients/token"
oauth = OAuth2Session(client=oauth_client)

# This will fire an actual HTTP call to the server to exchange client_id and
# client_secret with a fresh access token
token = oauth.fetch_token(
    token_url=token_url,
    client_id=CLIENT_ID,
    client_secret=CLIENT_SECRET,
    include_client_id=True,
    audience="https://api2.arduino.cc/iot",
)

# If we get here we got the token, print its expiration time
print("Got a token, expires in {} seconds".format(token.get("expires_in")))

######################################################################
# Publish a property of my Thing.
# Follows example from Aduino IoT API documentation:
# https://www.arduino.cc/reference/en/iot/api/#api-PropertiesV2-propertiesV2Publish
######################################################################

# Now we setup the iot-api Python client, first of all create a
# configuration object. The access token goes in the config object.
client_config = iot.Configuration(host="https://api2.arduino.cc/iot")
# client_config.debug = True
client_config.access_token = token.get("access_token")
# Create the iot-api Python client with the given configuration
client = iot.ApiClient(client_config)

properties = iot.PropertiesV2Api(client)

# Send a Boolean to led_state
# If the device is specified the property is published as if the device doing it
# and the Thing itself doesn't pick up the new value, even though it shows in the dashboard.
# By not specifying the device, the property is published as if by third party
# and dashboard and device pick up the change
#propertyValue = {"device_id": DEVICE_ID, "value": True}
propertyValue = {"value": True}

try: 
    # publish properties_v2
    properties.properties_v2_publish(THING_ID, PROPERTY_ID, propertyValue)
except ApiException as e:
    print("Exception when calling PropertiesV2Api->propertiesV2Publish: %s\n" % e)

# Send a number to my_int
propertyValue = {"device_id": DEVICE_ID, "value": 123}


Reading a Thing variable uses the 'properties_v2_show' method of the 'propertiesV2API'. This accesses the same Boolean, 'led_state'.

from pprint import pprint
import iot_api_client as iot
from openapi_client.rest import ApiException
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session
import json

###################################################################################
# Secret keys and stuff
###################################################################################
CLIENT_ID     = "VVVVVVVVVVVVVVVVVVVV"
CLIENT_SECRET = "WWWWWWWWWWWWWWWWWWWW"
THING_ID      = "XXXXXXXXXXXXXXXXXXXX"
DEVICE_ID     = "YYYYYYYYYYYYYYYYYYYY"
PROPERTY_ID   = "ZZZZZZZZZZZZZZZZZZZZ"  # led_state

###################################################################################
# Generate an access token
# Follows example from:
# https://github.com/arduino/iot-client-py/blob/master/example/main.py
###################################################################################
# Setup the OAuth2 session that'll be used to request the server an access token
oauth_client = BackendApplicationClient(client_id=CLIENT_ID)
token_url = "https://api2.arduino.cc/iot/v1/clients/token"
oauth = OAuth2Session(client=oauth_client)

# This will fire an actual HTTP call to the server to exchange client_id and
# client_secret with a fresh access token
token = oauth.fetch_token(
    token_url=token_url,
    client_id=CLIENT_ID,
    client_secret=CLIENT_SECRET,
    include_client_id=True,
    audience="https://api2.arduino.cc/iot",
)

# If we get here we got the token, print its expiration time
print("Got a token, expires in {} seconds\n".format(token.get("expires_in")))

######################################################################
# Show a property of my Thing.
# Follows example from Aduino IoT API documentation:
# https://www.arduino.cc/reference/en/iot/api/#api-PropertiesV2-propertiesV2Show
######################################################################

# Now we setup the iot-api Python client, first of all create a
# configuration object. The access token goes in the config object.
client_config = iot.Configuration(host="https://api2.arduino.cc/iot")
# client_config.debug = True
client_config.access_token = token.get("access_token")
# Create the iot-api Python client with the given configuration
client = iot.ApiClient(client_config)

properties = iot.PropertiesV2Api(client)

try:
    # show properties_v2
    api_response = properties.properties_v2_show(THING_ID, PROPERTY_ID)
    # This prints out the whole response
    pprint(api_response)
    # This shows how to extract the last_value
    print("\nVaraible {} = {}".format(api_response.variable_name, api_response.last_value))
except ApiException as e:
    print("Exception when calling PropertiesV2Api->propertiesV2Show: %s\n" % e)

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.