Claiming Electron Device

So I am stumped at this process. The reference docs are lacking in a huge way.

Here is my dilema:

I have a personal Electron that I have already claimed and have used for some other projects. I have recently added this device to the product I have created. So it shows up in the devices list under the products and shows me as the owner. But in customers I don’t show up. I have done some API calls and added myself as a customer.

Do I have to unclaim completely before I can use a claim code generated for the product? How Do I claim it? Do I have to use an App on a cell phone? Like the Particle App?

Is there way to input the device id and claim code in the UI I am creating on Node based web app?

I have to make this process for lack of a better term “ARMY Proof”, as other people that are not tech savvy in the military will have to claim the devices with little help from me.

1 Like

I could technically integrate the JavaScript SDK couldn’t I?

I was reading the claim devices section in the SDK. all it wants is a token and device id. So basically I create a user store their email, password and tokens in my db. Then route to another page where the user types in the number from the SIM card the hit submit. Which the SDK promise route to the device setup. In this case we don’t need WiFi. We wait. And at some point lock device and flash?

@callen -- I've been in your exact place.

First, you have to unclaim the devices from your developer account.

Then claim the devices (see below) with your customer access token.

Here's what I got from @jeiden a few months back when I asked the same question:

You can use the POST /v1/devices endpoint to claim an electron to a customer. Docs: https://docs.particle.io/reference/api/#claim-a-device

  • You need to make sure the electron is online when hitting this endpoint
  • The electron should not be owned by anyone else (unclaimed)
  • You should use a customer access token when you hit this endpoint
curl -H "Authorization: Bearer cust_access_token" https://api.particle.io/v1/devices -d id=12345678901234567890
2 Likes

@brandongoode Thanks for the information you shared. Now the device ID is this found on the sim card or the box somewhere? I don’t have one handy and forgot to look this morning prior to departing for work.

This endpoint will associate this device to a product right?

The device ID is the particle ID. You can find it using the particle CLI utility:

particle identify

The device cannot be claimed via the SIM ICCID. Although I asked for the feature too. Again from @jeiden:

I just looked into this, and I believe you have just discovered a current limitation -- ICCID claim codes are only accepted by the developer endpoint (v1/device_claims), not the product specific endpoint.

@jeiden -- Any update on this?

@brandongoode so using the particle cli means plugging the electron in with USB and running the command to identify.

So in theory in my application I could have a form on the web app to allow a user to copy then paste that ID and then use this in part of my $http requests for claiming.

Yes – you’re correct. For my users, that means I have to print it to a label and attach it to the product.

No updates as of now. Continue to use the method posted above until we work on adding ICCIDs to product claiming

Even having the ID printed and placed inside the box is a clever move. Or a barcode to scan within the Particle App.

Okay so here’s my dumb repetitive question.

I can make a form that will allow the customer to type in the device id and grab their token from session storage and send it to the end point with a claim code. Did I miss anything? This will done using an $http request in the API routes on my node application.

You never send the claim code to the endpoint. Here’s the exact code I have running on my web server:

const PARTICLE_AUTH_URL = 'https://' + process.env.PARTICLE_AUTH + '@api.particle.io';
const PARTICLE_URL = 'https://api.particle.io';


function * particleAuthReq(ctx) {
  var token = yield token.bind(ctx)();

  if(token.code) {
    throw new Error(token + '');
  }

  return request.defaults({
    baseUrl: PARTICLE_URL,
    headers: {
      'Authorization:': 'Bearer ' + token.access_token
    },
    json: true
  });

}

function * rename(ctx, authReq, particle, name) {


  var resp = yield authReq({
    uri: '/v1/devices/' + particle.id,
    method: 'PUT',
    body: {
      name: name
    }
  });

  if(resp.statusCode !== 200) {
    ctx.log.warn({rsp: resp}, 'Faild to renam particle');
    throw new Error('Failed to rename particle');
  }
}

function * create() {

  var particle = {id: this.data.id, userId: this.user.id};

  this.log.info({particle: particle}, 'create particle');

  var authReq = yield particleAuthReq(this);

  var resp = yield authReq.get('/v1/devices/' + particle.id);

  if(resp.statusCode !== 200) {
    this.log.info({particle: particle}, 'particle not claimed - claiming');
    yield authReq.post('/v1/devices', {body: {id: particle.id}});
    resp = yield authReq.get('/v1/devices/' + particle.id);
  }


  if(resp.statusCode !== 200) {
    this.log.warn({rsp: resp}, 'Failed to get device from particle.io');
    return {
      code: 500,
      message: 'Failed to create particle'
    };
  }

  var _particle = resp.body;

  if(this.data.name) {
    this.log.info({particle: particle}, 'naming particle');

    yield rename(this, authReq, particle, this.data.name);

    _particle.name = this.data.name;
  }

  particle = yield Particle.create({
    userId: this.user.id,
    id: _particle.id,
    gatewayId: this.gateway.id,
    cellular: _particle.cellular,
    connected: _particle.connected,
    lastHeard: _particle.last_heard,
    lastIPAddress: _particle.last_ip_address,
    lastIccid: _particle.last_iccid,
    imei: _particle.imei,
    name: _particle.name,
    platfromId: _particle.platfrom_id,
    productId: _particle.product_id,
    status: _particle.status
  });

  this.log.info({particle: particle}, 'particle created');

  return {particle: particles.normalize(particle)};
}

function * token() {
  var query = Gateway.queryOne('userId').eq(this.user.id);
  query.filter('type').eq('particle');


  var gateways = yield Gateway.query('userId').eq(this.user.id).exec();
  var gateway;

  gateways.forEach(function(g) {
    if(g.type === 'particle') {
      gateway = g;
    }
  });

  if(!gateway) {
    var createUserResp = yield request.post({
      url: PARTICLE_AUTH_URL + '/v1/orgs/'+ PARTICLE_ORG + '/customers',
      form: {
        email: this.user.email,
        no_password: true
      }
    });
    if(createUserResp.statusCode >= 300) {
      this.log.error({rsp: createUserResp}, 'Faild to create user on particle');
      return {
        code: 500,
        message: 'Failed to create particle token'
      };
    }
    gateway = yield Gateway.create({
      userId: this.user.id,
      name: 'Automate Green',
      type: 'particle',
      status: {state: 'Active'}
    });

  }

  this.gateway = gateway;

  var tokenResp = yield request.post({
    url: PARTICLE_AUTH_URL + '/oauth/token',
    form: {
      scope: 'customer=' + this.user.email,
      grant_type: 'client_credentials'
    }
  });

  if(tokenResp.statusCode >= 300) {
    this.log.error({rsp: tokenResp}, 'Faild to get particle token');
    return {
      code: 500,
      message: 'Failed to create particle token'
    };
  }

  return JSON.parse(tokenResp.body);
}

Do you really have to have the Electron turned on before sending the POST for the device ID? Why doesn’t the particle cloud save the device ID and save the access token, where the connection can be made regardless of whether or not the Electron is turned on?

@doughtz – Yes and it’s a real pain to explain to an end user.

Thanks for sharing your code. I would love to see a full web app example that provides an interface for claiming a device via the particle api. Right now, I am struggling to decide how to manage user authorizations for a product we are developing. Many devices will be owned by a single organization, and each device will have a number of users, while each user will have access to a number of the devices. My choices appear to be to either claim all the Electrons to a single corporate customer account (and manage user-device associations in the database) or to create a new account for each device (and store credentials in the database, along with device info).

Any suggestions?
Is there a limit to how many sign-ins can be active at a time with one particle.io account?

1 Like