Create device using gRPC

Hello,

I have a problem with chirpstack v4: I am trying to create a device using gRPC to an existing application that I created manually and it has an ID “application id: 47024c85-9559-46a0-ad0d-dbf1b16bde45”.

My python file is :

import os
import sys

import grpc
from chirpstack_api.as_pb.external import api

# Configuration.

# This must point to the API interface.
server = "localhost:8081"

# The API token (retrieved using the web-interface).
api_token = "...."

if __name__ == "__main__":
  # Connect without using TLS.
  channel = grpc.insecure_channel(server)

  client = api.DeviceServiceStub(channel)

  # Define the API key meta-data.
  auth_token = [("authorization", "Bearer %s" % api_token)]

  # Construct request.
  try:
  	req = api.CreateDeviceRequest()
  	req.device.dev_eui = 'f4fbcdb6545e5e3b'
  	req.device.name = 'device2'
  	req.device.description = 'A new device via grpc'
  	req.device.application_id = int('525548505299565345575353574552549748459710048100451009810249984954981001015253')
  	req.device.device_profile_id = 'Prof A'
  	req.device.skip_f_cnt_check = False
  	req.device.is_disabled = True
  	#req.device.variables = 'ras'
  	#req.device.variables.value = 'ras'
  	#req.device.tags = 'ras'
  	#req.device.tags.value = 'ras'
  	resp = client.Create(req, metadata=auth_token)
  except Exception as e:
  	print('<><><> Exception <><><> ' + str(e))

I have an error with the variable “req.device.application_id” that must be an integer.

Thank you in advance.

App id in v4 should be uuid instead?

Yes but I didn’t understand how I can get the UUID of an application that I created manually.

The UUID of any device, application, device profile, etc. are created automatically by ChirpStack. They will be included in the response when you create them, but you can also pull them via the API (list endpoint) or the web UI.

  1. So the UUID of this application is “4e07ce27-1d3e-4f51-8eb4-862e08dddfd5” ?

  1. If yes, when I’m trying to use it in my code :
import os
import sys

import grpc
from chirpstack_api.as_pb.external import api

# Configuration.

# This must point to the API interface.
server = "localhost:8081"

# The API token (retrieved using the web-interface).
api_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJjaGlycHN0YWNrIiwiaXNzIjoiY2hpcnBzdGFjayIsInN1YiI6IjY1OTViODVjLWQ1ZTYtNGZhMi04YzQ2LWY0MWQ1Y2E2NjZhZSIsInR5cCI6ImtleSJ9.fyP9Pxm0zSEdjmRwn4x1_lnB97Bq2wcvibSEQLGQ__M"

if __name__ == "__main__":
  # Connect without using TLS.
  channel = grpc.insecure_channel(server)

  # Device-queue API client.
  client = api.DeviceServiceStub(channel)

  # Define the API key meta-data.
  auth_token = [("authorization", "Bearer %s" % api_token)]

  # Construct request.
  try:
  	req = api.CreateDeviceRequest()
  	req.device.dev_eui = 'f4fbcdb6545e5e3b'
  	req.device.name = 'device2'
  	req.device.description = 'A new device via grpc'
  	req.device.application_id = "4e07ce27-1d3e-4f51-8eb4-862e08dddfd5"
  	req.device.device_profile_id = 'Prof A'
  	req.device.skip_f_cnt_check = False
  	req.device.is_disabled = True
  	resp = client.Create(req, metadata=auth_token)
  except Exception as e:
  	print('<><><> Exception <><><> ' + str(e))

  
  # Print the downlink frame-counter value.
    #print(resp.device)
  print('------- End OF TEST')
  1. I’m getting this error :

Cannot set api.Device.application_id to ‘4e07ce27-1d3e-4f51-8eb4-862e08dddfd5’: ‘4e07ce27-1d3e-4f51-8eb4-862e08dddfd5’ has type <type ‘str’>, but expected one of: (<type ‘int’>, <type ‘long’>)

Your Chirpstack instance is v4, but the Python API you’re trying to use is v3 (which previously used integer application IDs). Take a look here:

https://www.chirpstack.io/docs/chirpstack/api/python-examples.html

I used the same example as https://www.chirpstack.io/docs/chirpstack/api/python-examples.html with a function for device creation.

Do you have an example for the function that I am looking for (create a device using Python API v4) ?

@Reine_ABOU_SLEIMAN Reine did you get this to work?

Here is my Python script to import form Excel .xlsx file

#############################################################################################################
#  Python script to import Devices to a CS v4 Application from Excel .xlsx file                             #
#  cols: dev_eui|application_id|device_profile_id|name|description|network_key|application_key|disabled     #
#  It skips first row so you can keep col headings                                                          #
#                                                                                                           #
#  Requires uuid of application/device profile you can get from UI/Console                                  #
#  E.g. application id: FFFFFF-b8bf-47c3-bcb1-686bc2fcAAA & device profile id:                              #
#  Can't get grpc.StatusCode.ALREADY_EXISTS: to fire but grpc.StatusCode.INTERNAL: fires if Device exsists  #
#  Applogies to any Pro Devloper this was put together by a scrippter!!                                     #
#############################################################################################################
import openpyxl
from   chirpstack_api import api
import grpc

class DeviceImportRecord:
    def __init__(self, dev_eui, application_id, device_profile_id, name, description, network_key, application_key,is_disabled):
        self.DevEUI          = dev_eui
        self.ApplicationID   = application_id
        self.DeviceProfileID = device_profile_id
        self.Name            = name
        self.Description     = description
        self.NetworkKey      = network_key
        self.ApplicationKey  = application_key
        self.is_disabled     = is_disabled

def get_device_import_list(file: str) -> list[DeviceImportRecord]:
    out = []
    try:
        wb = openpyxl.load_workbook(file)
    except Exception as e:
        print("open excel file error",e)
        return []

    sheet = wb.active
    rw_no = 0   
    rows = sheet.iter_rows(min_row=1,max_row=sheet.max_row)
    for a,b,c,d,e,f,g,h in rows:
        if rw_no > 0:
            print('importing rw:',rw_no,':',a.value,b.value,c.value,d.value,e.value,f.value,g.value,h.value)
            out.append(DeviceImportRecord(a.value,b.value,c.value,d.value,e.value,f.value,g.value,h.value))
        rw_no += 1
    
    return out

def import_devices(devices):
    server  = "localhost:8080"
    api_token = "Your API token"

    channel = grpc.insecure_channel(server)
    client  = api.DeviceServiceStub(channel)
    auth_token = [("authorization", "Bearer %s" % api_token)]
    
    try:
        req = api.CreateDeviceRequest()
        for dev in devices:
            print('creating Device with DevEUI:',dev.DevEUI)
            req.device.dev_eui           = str(dev.DevEUI)
            req.device.name              = str(dev.Name)
            req.device.description       = str(dev.Description)
            req.device.application_id    = str(dev.ApplicationID)
            req.device.device_profile_id = str(dev.DeviceProfileID)
            req.device.is_disabled       = dev.is_disabled
            resp = client.Create(req, metadata=auth_token)
    except grpc.RpcError as e:
        #print('error:',type(e))
        if e.code() == grpc.StatusCode.INTERNAL:
            print('import error device',dev.DevEUI,' import aborted! Check Device my already exsist.')

    return None

if __name__ == "__main__":
    dev_list = get_device_import_list('/your path to/device_import.xlsx')
    import_devices(dev_list)

Excel file