Skip to content

Commit

Permalink
Merge pull request #98 from particle-iot/feature/mesh_api
Browse files Browse the repository at this point in the history
Mesh network management API
  • Loading branch information
sergeuz authored Feb 26, 2019
2 parents 30d10e9 + 4ada7d4 commit bde65f6
Show file tree
Hide file tree
Showing 2 changed files with 233 additions and 0 deletions.
108 changes: 108 additions & 0 deletions src/Particle.js
Original file line number Diff line number Diff line change
Expand Up @@ -1329,6 +1329,114 @@ class Particle {
return this.get(`/v1/serial_numbers/${serialNumber}`, auth, undefined, context);
}

/**
* Create a mesh network
* @param {Object} options Options for this API call
* @param {String} options.name Network name
* @param {String} options.deviceId Gateway device ID
* @param {String} [options.iccid] ICCID of the active SIM card (only for cellular gateway devices)
* @param {String} options.auth Access token
* @param {Object} [options.context] Request context
* @return {Promise<Object>}
*/
createMeshNetwork({ name, deviceId, iccid, auth, context }) {
return this.post('/v1/networks', { name, device_id: deviceId, iccid }, auth, context);
}

/**
* Remove a mesh network.
* @param {Object} options Options for this API call
* @param {String} options.networkId Network ID or name
* @param {String} options.auth Access token
* @param {Object} [options.context] Request context
* @return {Promise<Object>}
*/
removeMeshNetwork({ networkId, auth, context }) {
return this.delete(`/v1/networks/${networkId}`, undefined, auth, context);
}

/**
* List all mesh networks
* @param {Object} options Options for this API call
* @param {String} options.auth Access token
* @param {Number} [options.page] Current page of results
* @param {Number} [options.perPage] Records per page
* @param {Object} [options.context] Request context
* @return {Promise<Object>}
*/
listMeshNetworks({ auth, context, page, perPage }) {
const query = page ? { page, per_page: perPage } : undefined;
return this.get('/v1/networks', auth, query, context);
}

/**
* Get information about a mesh network.
* @param {Object} options Options for this API call
* @param {String} options.networkId Network ID or name
* @param {String} options.auth Access token
* @param {Object} [options.context] Request context
* @return {Promise<Object>}
*/
getMeshNetwork({ networkId, auth, context }) {
return this.get(`/v1/networks/${networkId}`, auth, undefined, context);
}

/**
* Modify a mesh network.
* @param {Object} options Options for this API call
* @param {String} options.networkId Network ID or name
* @param {String} options.action 'add-device', 'remove-device', 'gateway-enable' or 'gateway-disable'
* @param {String} options.deviceId Device ID
* @param {String} options.auth Access token
* @param {Object} [options.context] Request context
* @return {Promise<Object>}
*/
updateMeshNetwork({ networkId, action, deviceId, auth, context }) {
return this.put(`/v1/networks/${networkId}`, { action, device_id: deviceId }, auth, context);
}

/**
* Add a device to a mesh network.
* @param {Object} options Options for this API call
* @param {String} options.networkId Network ID or name
* @param {String} options.deviceId Device ID
* @param {String} options.auth Access token
* @param {Object} [options.context] Request context
* @return {Promise<Object>}
*/
addMeshNetworkDevice({ networkId, deviceId, auth, context }) {
return this.updateMeshNetwork({ action: 'add-device', networkId, deviceId, auth, context });
}

/**
* Remove a device from a mesh network.
* @param {Object} options Options for this API call
* @param {String} options.networkId Network ID or name
* @param {String} options.deviceId Device ID
* @param {String} options.auth Access token
* @param {Object} [options.context] Request context
* @return {Promise<Object>}
*/
removeMeshNetworkDevice({ networkId, deviceId, auth, context }) {
return this.updateMeshNetwork({ action: 'remove-device', networkId, deviceId, auth, context });
}

/**
* List all devices of a mesh network.
* @param {Object} options Options for this API call
* @param {String} options.networkId Network ID or name
* @param {String} options.auth Access token
* @param {Number} [options.role] Device role: 'gateway' or 'node'
* @param {Number} [options.page] Current page of results
* @param {Number} [options.perPage] Records per page
* @param {Object} [options.context] Request context
* @return {Promise<Object>}
*/
listMeshNetworkDevices({ networkId, auth, role, page, perPage, context }) {
const query = (role || page) ? { role, page, per_page: perPage } : undefined;
return this.get(`/v1/networks/${networkId}/devices`, auth, query, context);
}


/**
* API URI to access a device
Expand Down
125 changes: 125 additions & 0 deletions test/Particle.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ const props = {
},
otp: '123456',
mfaToken: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
networkId: '65535'
};

const product = 'ze-product-v1';
Expand Down Expand Up @@ -1827,6 +1828,130 @@ describe('ParticleAPI', () => {
});
});
});

describe('.createMeshNetwork', () => {
it('generates request', () => {
return api.createMeshNetwork(props).then((results) => {
results.should.match({
method: 'post',
uri: '/v1/networks',
auth: props.auth,
data: {
name: props.name,
device_id: props.deviceId,
iccid: props.iccid
}
});
});
});
});

describe('.removeMeshNetwork', () => {
it('generates request', () => {
return api.removeMeshNetwork(props).then((results) => {
results.should.match({
method: 'delete',
uri: `/v1/networks/${props.networkId}`,
auth: props.auth
});
});
});
});

describe('.listMeshNetworks', () => {
it('generates request', () => {
return api.listMeshNetworks(props).then((results) => {
results.should.match({
method: 'get',
uri: '/v1/networks',
auth: props.auth,
query: {
page: props.page,
per_page: props.perPage
}
});
});
});
});

describe('.getMeshNetwork', () => {
it('generates request', () => {
return api.getMeshNetwork(props).then((results) => {
results.should.match({
method: 'get',
uri: `/v1/networks/${props.networkId}`,
auth: props.auth
});
});
});
});

describe('.updateMeshNetwork', () => {
it('generates request', () => {
const p = Object.assign(props, { action: 'test' });
return api.updateMeshNetwork(p).then((results) => {
results.should.match({
method: 'put',
uri: `/v1/networks/${p.networkId}`,
auth: p.auth,
data: {
action: p.action,
device_id: p.deviceId
}
});
});
});
});

describe('.addMeshNetworkDevice', () => {
it('generates request', () => {
return api.addMeshNetworkDevice(props).then((results) => {
results.should.match({
method: 'put',
uri: `/v1/networks/${props.networkId}`,
auth: props.auth,
data: {
action: 'add-device',
device_id: props.deviceId
}
});
});
});
});

describe('.removeMeshNetworkDevice', () => {
it('generates request', () => {
return api.removeMeshNetworkDevice(props).then((results) => {
results.should.match({
method: 'put',
uri: `/v1/networks/${props.networkId}`,
auth: props.auth,
data: {
action: 'remove-device',
device_id: props.deviceId
}
});
});
});
});

describe('.listMeshNetworkDevices', () => {
it('generates request', () => {
const p = Object.assign({ role: 'node' }, props);
return api.listMeshNetworkDevices(p).then((results) => {
results.should.match({
method: 'get',
uri: `/v1/networks/${props.networkId}/devices`,
auth: p.auth,
query: {
role: p.role,
page: p.page,
per_page: p.perPage
}
});
});
});
});
});

describe('backwards-compatibility function aliases', () => {
Expand Down

0 comments on commit bde65f6

Please sign in to comment.