Python code to access basic cayenne API

this python code enables you to access the basic cayenne API request.

Requirements:
Install request https://2.python-requests.org//en/master/user/install/#install

on running the code, it will prompt you:

  1. For a new user or an existing user.
    Enter 1 for new and 2 for an existing user.
    if a new user then it will prompt to enter:
  • client_id ----> APP key from the cayenne dashboard.
  • client_secret ----> APP secret from the cayenne dashboard.
  • username ----> Email_id for your account.
  • password ----> Password of your account.
  • mqtt_username ----> Your account MQTT username.
  • mqtt_password ----> Your account MQTT password.
    Next, it will get the access_token and mqtt_token.
    All these credentials will be stored in the credentials.ini.
    If an existing user then this info will be gathered from credentials.ini
  1. Enter the number to get the info.
    1 = Get new Access Token
    2 = Get new Mqtt Token
    3 = Get latest sensor data
    4 = Get sensor history data
    5 = Publish data

Get new Access Token
This function gets the access_token for the https://platform.mydevices.com/ endpoint:

def get_access_token(client_id, client_secret, username, password):
        response = requests.post('https://accounts.mydevices.com/auth/realms/cayenne/protocol/openid-connect/token',
                data={'grant_type':'password',
                'client_id':client_id,
                'client_secret':client_secret,
                'username':username,
                'password':password },
                headers={'content-type':'application/x-www-form-urlencoded'})
        payload = response.json()
        access_token = payload['access_token']
        print('Access_Token = ' + access_token)
        config['DEFAULT']['access_token'] = access_token
        with open('credentials.ini', 'w') as configfile:
                config.write(configfile)
        return (access_token)

Get new MQTT Token
This function gets the mqtt_token for the https://api.mydevices.com

def get_mqtt_token(mqtt_username, mqtt_password ):
        string = mqtt_username + ':' + mqtt_password
        print(string)
        data = base64.b64encode(string.encode())
        mqtt_token = data.decode("utf-8")
        config['DEFAULT']['mqtt_token'] = mqtt_token
        with open('credentials.ini', 'w') as configfile:
                config.write(configfile)
        return (mqtt_token)

Get latest sensor data
This function gets the latest sensor data published for the respective sensor_id.
You will need to add the device_id and the sensor_id for the widget you need to get the latest data.

def get_latest_history(access_token, device_id, sensor_id):
        bearer = 'Bearer '+ access_token
        URL = 'https://platform.mydevices.com/v1.1/telemetry/'+device_id+'/sensors/'+sensor_id+'/summaries?type=latest'
        response = requests.get(URL,
                headers={'authorization': bearer},)
        payload = response.json()
        data = payload[0]['v']
        print ('Data history = %d' %data)

Get sensor history data
This function gets the history data of the respective sensor_id.
You will need to add the device_id and the sensor_id for the widget you need to get the latest data.
Also the duration of the historical period.

def get_history(access_token, device_id, sensor_id):
        list = []
        duration = input("Enter the history duration. example: 1month or 2month or 3month and so on ")
        bearer = 'Bearer '+ access_token
        URL = 'https://platform.mydevices.com/v1.1/telemetry/'+device_id+'/sensors/'+sensor_id+'/summaries?endDateLatest=true&type='+duration
        response = requests.get(URL,
                headers={'authorization': bearer},)
        history_list = response.json()
        for item in history_list:
                #print(item['v'])
                list.append(item['v'])
        print(list)
        print()

Publish data
This function is used to publish data.
You need the add the following when prompted:

  • device_id ----> the device_id to which you want to publish data.
  • channel ----> MQTT channel of the widget to publish data.
  • value ----> data value you need to publish.
  • unit and type ----> Data types for Cayenne MQTT API

def publish_data(mqtt_token):
            device_id  = input ("Enter your Device_ID:  ")
            URL = 'https://api.mydevices.com/things/'+device_id+'/data'
            channel  = int(input("Enter channel:  "))
            value  = int(input("Enter value:  "))
            unit = input ("Enter unit:  ")
            type  = input ("Enter type:  ")
            basic = 'Basic '+mqtt_token
            headers= {'authorization': basic,
    		'content-type': 'application/json'}
            data = [{'value': value,
                     'channel': channel,
                      'unit': unit,
                      'type' : type
                    }]
            response = requests.post(URL, json=data, headers=headers)
            print(response)

You can edit the respective function for your need.
The code needs improvements and will be working on it or someone can contribute to it.

import requests

import base64

import configparser
config = configparser.ConfigParser()


def get_mqtt_token(mqtt_username, mqtt_password ):
        string = mqtt_username + ':' + mqtt_password
        print(string)
        data = base64.b64encode(string.encode())
        mqtt_token = data.decode("utf-8")
        config['DEFAULT']['mqtt_token'] = mqtt_token
        with open('credentials.ini', 'w') as configfile:
                config.write(configfile)
        return (mqtt_token)

def get_access_token(client_id, client_secret, username, password):
        response = requests.post('https://accounts.mydevices.com/auth/realms/cayenne/protocol/openid-connect/token',
                data={'grant_type':'password',
                'client_id':client_id,
                'client_secret':client_secret,
                'username':username,
                'password':password },
                headers={'content-type':'application/x-www-form-urlencoded'})
        payload = response.json()
        access_token = payload['access_token']
        print('Access_Token = ' + access_token)
        config['DEFAULT']['access_token'] = access_token
        with open('credentials.ini', 'w') as configfile:
                config.write(configfile)
        return (access_token)

def get_latest_history(access_token, device_id, sensor_id):
        bearer = 'Bearer '+ access_token
        URL = 'https://platform.mydevices.com/v1.1/telemetry/'+device_id+'/sensors/'+sensor_id+'/summaries?type=latest'
        response = requests.get(URL,
                headers={'authorization': bearer},)
        payload = response.json()
        data = payload[0]['v']
        print ('Data history = %d' %data)

def get_user_credentials():
        client_id  = input ("Enter your client_id:  ")
        client_secret  = input ("Enter your client_Secret:  ")
        username = input ("Enter your Username:  ")
        password  = input ("Enter your Password:  ")
        mqtt_username = input("Enter your MQTT Username")
        mqtt_password = input("Enter your MQTT Password")
        config['DEFAULT']['client_id'] = client_id
        config['DEFAULT']['client_secret'] = client_secret
        config['DEFAULT']['username'] = username
        config['DEFAULT']['password'] = password
        config['DEFAULT']['mqtt_username'] = mqtt_username
        config['DEFAULT']['mqtt_password'] = mqtt_password

        with open('credentials.ini', 'w') as configfile:
                config.write(configfile)
        return client_id, client_secret, username, password, mqtt_username, mqtt_password;


def get_device_info():
        device_id  = input ("Enter your Device_ID:  ")
        sensor_id  = input ("Enter your Sensor_ID:  ")
        return device_id, sensor_id;

def get_client_data():
        config.read('credentials.ini')
        client_id = config['DEFAULT']['client_id']
        client_secret = config['DEFAULT']['client_secret']
        username = config['DEFAULT']['username']
        password = config['DEFAULT']['password']
        access_token = config['DEFAULT']['access_token']
        mqtt_token = config['DEFAULT']['mqtt_token']
        mqtt_username = config['DEFAULT']['mqtt_username']
        mqtt_password = config['DEFAULT']['mqtt_password']
        return client_id, client_secret, username, password, access_token, mqtt_token, mqtt_username, mqtt_password;

def get_history(access_token, device_id, sensor_id):
        list = []
        duration = input("Enter the history duration. example: 1month or 2month or 3month and so on ")
        bearer = 'Bearer '+ access_token
        URL = 'https://platform.mydevices.com/v1.1/telemetry/'+device_id+'/sensors/'+sensor_id+'/summaries?endDateLatest=true&type='+duration
        response = requests.get(URL,
                headers={'authorization': bearer},)
        history_list = response.json()
        for item in history_list:
                #print(item['v'])
                list.append(item['v'])
        print(list)
        print()

def publish_data(mqtt_token):
        device_id  = input ("Enter your Device_ID:  ")
        URL = 'https://api.mydevices.com/things/'+device_id+'/data'
        channel  = int(input("Enter channel:  "))
        value  = int(input("Enter value:  "))
        unit = input ("Enter unit:  ")
        type  = input ("Enter type:  ")
        basic = 'Basic '+mqtt_token
        headers= {'authorization': basic,
		'content-type': 'application/json'}
        data = [{'value': value,
                 'channel': channel,
                  'unit': unit,
                  'type' : type
                }]
        response = requests.post(URL, json=data, headers=headers)
        print(response)
x = 0

while True:
        if x == 0:
                print ("/////////////////////////////////////////////////")
                print ("")
                print ("WELCOME TO CAYENNE API")
                print (" 1 = For new number ")
                print (" 2 = Existing USer")
                user_input = int(input("Enter the appropriate number "))
                if user_input == 1 :
                        client_id, client_secret, username, password = get_user_credentials()
                        print ("Welcome" + username)
                        access_token = get_access_token(client_id, client_secret, username, password)
#                        mqtt_token = get_mqtt_token(username, password)
                elif  user_input == 2:
                        client_id, client_secret, username, password, access_token, mqtt_token, mqtt_username, mqtt_password = get_client_data()
                        print ("Welcome back " + username)
                x = 1

        if x == 1:
                print ("/////////////////////////////////////////////////")
                print (" 1 = Get new Access Token")
                print (" 2 = Get new Mqtt Token")
                print (" 3 = Get latest sensor data")
                print (" 4 = Get sensor history data")
                print (" 5 = Publish data")
                get_input = int(input("Enter the appropriate number "))
                if get_input == 1:
                        access_token = get_access_token(client_id, client_secret, username, password)
                elif get_input == 2:
                        mqtt_token = get_mqtt_token(mqtt_username, mqtt_password)
                elif get_input == 3:
                        device_id, sensor_id = get_device_info()
                        get_latest_history(access_token, device_id, sensor_id)
                elif get_input == 4:
                        device_id, sensor_id = get_device_info()
                        get_history(access_token, device_id, sensor_id)
                elif get_input == 5:
                        publish_data(mqtt_token)
3 Likes

Thanks for your answer. However, is there a simple way to subscribe to a channel using cayenne-client ?

Otherwise, two question using this library :

Where can I find the client_secret ?
The URL “https://accounts.mydevices.com/auth/realms/cayenne/protocol/openid-connect/token” seems not working anymore, what’s the correct URL ?

Thanks

Patrick

it works absolutely fine for me. if you don’t know how to find the client secret and id, how will get the access token response.

This code doesn’t allow you to subscribe to one channel only.
I don’t want to receive all channel info. Just the one I subscribe. Otherwise overloaded.
And what about the URL. Is it correct or not ?

what does it do then?

Thanks. I can find the client id but not the client secret on dashboard. Can you help me ?
Thanks for you help.

have a look at this topic to know more about cayenne api How to access Cayenne API using Insomnia, Node-red and Thunkable

this code allows to subscribe to data from cayenne:

def on_message(message):
    print("message received: " + str(message))
    # If there is an error processing the message return an error string, otherwise return nothing.

Dear Shramik,

My complete code works find as Gateway with Yoctopuce meteo station .

As soon as I start another session to read only the values (from another Rasp), It doesn’t works.

Connected with result code 0

SUB v1/de45f460-fbe1-11e8-a08c-c5a286f8c00d/things/dd2255f0-0376-11e9-809d-0f8fe4c30267/cmd/+

PUB v1/de45f460-fbe1-11e8-a08c-c5a286f8c00d/things/dd2255f0-0376-11e9-809d-0f8fe4c30267/sys/model

Python

PUB v1/de45f460-fbe1-11e8-a08c-c5a286f8c00d/things/dd2255f0-0376-11e9-809d-0f8fe4c30267/sys/version

1.1.0

Disconnected with result code 1

The reader : DOESN’T RECEIVE ANY VALUES

import cayenne.client

import time

Cayenne authentication info. This should be obtained from the Cayenne Dashboard.

MQTT_USERNAME = “”

MQTT_PASSWORD = “”

MQTT_CLIENT_ID = “dd2255f0-0376-11e9-809d-0f8fe4c30267”

MQTT_SERVER = “mqtt.mydevices.com

MQTT_PORT = 1883

SECURE_MQTT_PORT = 8883

The callback for when a message is received from Cayenne.

def on_message(message):

print("message received: " + str(message))

def on_connect(message):

print("mqtt client connected : " + str(message))

def on_disconnect(message):

print("mqtt client disconnected: " + str(message))

print(“…starting IoT Gateway…”)

client = cayenne.client.CayenneMQTTClient()

client.on_connect = on_connect

client.on_message = on_message

client.on_disconnect = on_disconnect

client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID)

client.loop_forever()

The Gateway (Raspeberry to Yoctopuce) : WORKS FIND

-- coding: utf-8 --

import time

import cayenne.client

from yoctopuce.yocto_api import *

from yoctopuce.yocto_humidity import *

from yoctopuce.yocto_temperature import *

from yoctopuce.yocto_pressure import *

from yoctopuce.yocto_relay import *

from yoctopuce.yocto_lightsensor import *

from yoctopuce.yocto_display import *

import logging

logging.basicConfig(filename=‘iotgw.log’,level=logging.INFO,format=‘%(asctime)s %(message)s’, datefmt=‘%m/%d/%Y %I:%M:%S %p’)

logging.info(‘— Starting Logging info for IoT Gateway—’)

Cayenne authentication info. This should be obtained from the Cayenne Dashboard.

MQTT_USERNAME = “”

MQTT_PASSWORD = “”

MQTT_CLIENT_ID = “dd2255f0-0376-11e9-809d-0f8fe4c30267”

MQTT_SERVER = “mqtt.mydevices.com

MQTT_PORT = 1883 # 8883 = secure mqtt port otherwise 1883

MQTT_SUBSCRIBE_CHANNEL = “2”

publish0 = ‘v1/’+ MQTT_USERNAME + ‘/things/’+ MQTT_CLIENT_ID +‘/data/0’

publish1 = ‘v1/’+ MQTT_USERNAME + ‘/things/’+ MQTT_CLIENT_ID +‘/data/1’

publish2 = ‘v1/’+ MQTT_USERNAME + ‘/things/’+ MQTT_CLIENT_ID +‘/data/7’

subscribe2 = ‘v1/’+ MQTT_USERNAME + ‘/things/’ + MQTT_CLIENT_ID + ‘/cmd/’ + MQTT_SUBSCRIBE_CHANNEL

Yoctopuce Wifi IP address.

YOCTO_IP_ADDRESS = “192.168.1.160”

logging.info(‘Yoctopuce IP address : %s’, YOCTO_IP_ADDRESS)

Cayenne widget information according to the Dashboard.

temperature = 1 # temperature Gauge

humidity = 3 # humidity graph

pressure = 4 # pressure Gauge

relay1 = 9 # radiateur

relay2 = 7 # LED

relay3 = 2 # Lumière

relay4 = 10 # non utilisé

delay = 300 # temps en secondes entre deux lectures des senseurs

let me guess, you have device A with client_id xyz publishing data to cayenne. Now you have a device B (which is a raspberry pi) that you want to use to subscribe to device A published data. So you are using the above code and using client_id xyz in MQTT_CLIENT_ID.
This won’t work, as you are trying to connect two devices with same MQTT_CLIENT_ID which is xyz . it will disconnect again and again. the only option here is to use cayenne API.

Ok clear now. Thanks.

Patrick

Hello,

I tried your code to test the API.

https://community.mydevices.com/t/python-code-to-access-basic-cayenne-api/12343

I receive the following error :

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File “/Users/ppinard/anaconda3/lib/python3.7/site-packages/requests/adapters.py”, line 445, in send

timeout=timeout

File “/Users/ppinard/anaconda3/lib/python3.7/site-packages/urllib3/connectionpool.py”, line 638, in urlopen

_stacktrace=sys.exc_info()[2])

File “/Users/ppinard/anaconda3/lib/python3.7/site-packages/urllib3/util/retry.py”, line 398, in increment

raise MaxRetryError(_pool, url, error or ResponseError(cause))

urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host=‘accounts.mydevices.com’, port=443): Max retries exceeded with url: /auth/realms/cayenne/protocol/openid-connect/token (Caused by SSLError(SSLError(“bad handshake: SysCallError(-1, ‘Unexpected EOF’)”)))

I didn’t change any lines. Could you help me to understand why the connexion is refused ?

Thanks

Patrick

can you private message me the code with your credentials added in it.