Create device using gRPC

@Reine_ABOU_SLEIMAN Reine did you get this to work?

Here is my Python script to import form Excel .xlsx file
Updated to add Tags which need to be in JSON format {“foo”:“Bar”}

################################################################################################################################
#  V0.1 - Added support for tags which need to be JSON strin
#  Python script to import Devices to an CS v4 Application from Excel .xlsx file
#  requires uuid of application/device profile you can get from UI/Console
#  E.g. application id: FFFFFF-b8bf-47c3-bcb1-686bc2fcAAA & device profile id:   
#  
#  I can't find away to test if device entery exsists via get grpc.StatusCode.ALREADY_EXISTS: 
#  but grpc.StatusCode.INTERNAL: fires if Device exsists so that will have to surfice
#  Applogies to any Pro Devloper this was put together by a scrippter!!
#
#  Excel cols:
#  dev_eui | application_id | device_profile_id | name | description | network_key | application_key | is_disabled | tags
#  tag example: {"loc":"ii@St_Albans@GF@Study","device_details":"manf_Elsys,model_EMS,sn_174747,hw:_v1.1,fw:_v3","notes":" ..."}
################################################################################################################################
import openpyxl
import json
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,tags):
        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
        self.tags            = tags

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,i 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,i.value)
            out.append(DeviceImportRecord(a.value,b.value,c.value,d.value,e.value,f.value,g.value,h.value,i.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                     
            req.device.tags.update(json.loads(dev.tags))
            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.')
    try:
        req = api.CreateDeviceKeysRequest()
        for dev in devices:
            print('creating keys for device DevEUI:',dev.DevEUI)
            req.device_keys.dev_eui = str(dev.DevEUI)
            req.device_keys.nwk_key = str(dev.NetworkKey)
            req.device_keys.app_key = str(dev.ApplicationKey)
            resp = client.CreateKeys(req, metadata=auth_token)
    except  grpc.RpcError as e:
        print('error:',type(e))

    return None

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

Excel file

2 Likes