diff --git a/src/Particle.js b/src/Particle.js index d5aab27..85e696b 100644 --- a/src/Particle.js +++ b/src/Particle.js @@ -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} + */ + 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} + */ + 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} + */ + 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} + */ + 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} + */ + 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} + */ + 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} + */ + 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} + */ + 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 diff --git a/test/Particle.spec.js b/test/Particle.spec.js index ba2f664..b716694 100644 --- a/test/Particle.spec.js +++ b/test/Particle.spec.js @@ -85,6 +85,7 @@ const props = { }, otp: '123456', mfaToken: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + networkId: '65535' }; const product = 'ze-product-v1'; @@ -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', () => {