Argon CLI Setup Tool

I’ll create the GitHub repo once I include the “adding the device to the product” and also migrate to a Flask App interface. If/when I do that, I’ll share it back here or maybe just create a new post sharing all the details.

In the meantime… here is the 3/4 baked Python script I use today and just use the Command Line as the interface. I’d appreciate any feedback/ideas on how to make this even easier. If I end up doing hundreds of devices, I may try and setup a raspberry PI with cheap touch screen that I could do it all easily from my “workbench” area instead of “office” area. All in time…

import os
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
import json, requests

#Enter Particle Product IDs (These are not my actual IDs)
sandbox = '12345'
growth = '12345'

#Read sensative configuration parameters, tokens, etc. via OS Environment Variables. 
SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI')
PARTICLE_TOKEN = os.environ.get('PARTICLE_TOKEN')

#Update this line based on where to add the device (either to SandBox or Growth Plan)
PARTICLE_PRODUCTID = sandbox

#Connect to the database...
engine = create_engine(SQLALCHEMY_DATABASE_URI, echo=False)
Base = declarative_base()
Session = sessionmaker(bind=engine)
session = Session()

###############################################################
#  Various functions used elsewhere are defined Here
###############################################################

#  This function calls a stored procedure that exists on the SQL database. 
#  This specific stored procedure is used to add a device to the DB and initialize all tables for that device. 
def exec_procedure(session, proc_name, params):
    sql_params = ",".join(["@{0}={1}".format(name, value) for name, value in params.items()])
    sql_string = """
        DECLARE @return_value int;
        EXEC    @return_value = [dbo].[{proc_name}] {params};
        SELECT 'Return Value' = @return_value;
    """.format(proc_name=proc_name, params=sql_params)
    session.execute(sql_string)
    return "true"


###############################################################
# STEP 1: Scan the Particle Device QR
###############################################################
print('Scan Particle Device QR Code:')
ParticleQR_Full = input()
ParticleSerial = ParticleQR_Full[0:15]

#Look up the device_id from Particle.
#Device ID is needed as it is the primary key to the DB and all device settings and data storage. 
#The barcode just has the device serial number. 
data = {
    'access_token': PARTICLE_TOKEN
}

response = requests. get('https://api.particle.io/v1/serial_numbers/'+ParticleSerial+'?access_token='+PARTICLE_TOKEN)
dictFromServer = response.json()
device_id = dictFromServer['device_id']
print("The Device ID is: "+ device_id)


###############################################################
#Step 2: Scan the device claim code (10 digit hexadecimal unique to my product)
###############################################################
print('Now Scan the devices claim code: ')
ClaimCode_Full = input()
if (len(ClaimCode_Full) > 12):
  ClaimCode = ClaimCode_Full[-10:]
else:
  ClaimCode = ClaimCode_Full

print("The Claim Code is: "+ ClaimCode)

#Uncomment or Comment out the type of device this is (used in the SQL Database). 
#This allows the same firmware to be used for different devices with different sensors attatched, 
#This is sent to the device via function call so the device knows what it is AND used in the front end to hide/show 
#differnet settings/screens based on what type of sesnors/actuators is wired to it. 
deviceFeatures = 1   #Cellular, Sesnor1, Sensor2, Relay1
# deviceFeatures = 2   #Cellular, Sensor1
# deviceFeatures = 3   #Cellular, Relay1
# deviceFeatures = 4   #Cellular, widget10
#...
print("The Selected Feature of this device is: " + str(deviceFeatures))


###############################################################
#Step 3: Execute the stored procedure to add the device to my SQL database
###############################################################
params = {
    'NewDeviceID': '"'+device_id+'"',
    'NewDeviceSerialNum': '"'+ClaimCode+'"',
    'NewDevice_features_id' : deviceFeatures 
}
print(params)
exec_procedure(session, 'AddNewDevice', params)
session.commit()


###############################################################
#Step 4: Claim the device to a single Admin account within the product
###############################################################
data = {
    'access_token': PARTICLE_TOKEN,
    'id':device_id
}

response = requests.post('https://api.particle.io/v1/devices', data=data)
dictFromServer = response.json()
print(dictFromServer)


###############################################################
#Step 5: update the device notes and device name to provide more context to the devices in the console
#Note: when a customer associates a device with their account through the web app, this updates again to include that user in the notes and device name is updated
###############################################################
notes = {"status":"unclaimed"}
name = ClaimCode + '_unclaimed'

data = {
    'notes': json.dumps(notes),
    'name': name,
    'access_token': PARTICLE_TOKEN
}

response = requests.put('https://api.particle.io/v1/products/'+PARTICLE_PRODUCTID+'/devices/'+ device_id, data=data)
dictFromServer = response.json()
print(dictFromServer)
 

###############################################################
#Step 6: Flash the latest and greatest Hex File to the device
# ###############################################################
os.chdir(r"C:\Users\Particle\hex")
os.system("nrfjprog -f NRF52 --program Boron_V27.hex --chiperase --reset")



#General Enhancements needed to this process:
#1) Why not just add the device to the product using this script too. That way I don't need to do that in advance. 
#2) Create a basic Python Flask Web app around this to provide a better user interface
1 Like