UNPKG

thingsboard_api

Version:

Thingsboard REST API implementation

535 lines (460 loc) 17.2 kB
const axios = require('axios'); // base entity types const possibleEntityTypes = { "device": "DEVICE", "asset": "ASSET", "view": "ENTITY_VIEW", }; // Get object id based on device name, and entityType async function getObjectID(entityName, entityType, tokenFlag = false) { if (((typeof entityType === "undefined") || (entityType === null)) || ((typeof entityName === "undefined") || (entityName === null))) { return { error: true, message: 'getObjectID(), Error: entityType or entityName are not defined or null!' }; } let url = ''; entityName = encodeURI(entityName); entityName = entityName.replace("&", "%26") switch (entityType.toUpperCase()) { case possibleEntityTypes.device: url = `http://${process.env.TB_HOST}:${process.env.TB_PORT}/api/tenant/devices?deviceName=${entityName}` break; case possibleEntityTypes.asset: url = `http://${process.env.TB_HOST}:${process.env.TB_PORT}/api/tenant/assets?assetName=${entityName}`; break; case possibleEntityTypes.view: url = `http://${process.env.TB_HOST}:${process.env.TB_PORT}/api/tenant/entityViews?entityViewName=${entityName}`; break; default: return { error: true, message: `getObjectID(), Unknown entity type: ${entityType} !` }; } try { const response = await axios(url, { headers: { 'Content-Type': 'application/json', 'X-Authorization': 'Bearer ' + process.env[tokenRand+'TB_TOKEN'] } }); // if we don't want to get token, // return only id if (!tokenFlag) { return response.data.id.id; } // If token exist and type is device if ((tokenFlag) && (entityType.toUpperCase() === possibleEntityTypes.device)) { const token = await getDeviceToken(response.data.id.id); if (!token) { // error during get token return { error: true, message: `getObjectID(), Error: get token error! Name = ${entityName} ID = ${response.data.id.id}` } } // return complete obj return { id: response.data.id.id, name: response.data.name, type: response.data.id.entityType, device_token: token, }; } } catch (err) { return { error: true, message: `getObjectID(), Error while getting data from server: ${err}` } } } // Get all possible object keys async function getAllObjectKeys(id, entityType) { if (((entityType === null) || (typeof entityType == 'undefined')) || ((typeof id === 'undefined') || (id === null))) { return { error: true, message: `getAllObjectKeys(), Error: type or id are not defined or null!` }; } const url = `http://${process.env.TB_HOST}:${process.env.TB_PORT}/api/plugins/telemetry/${entityType.toUpperCase()}/${id}/keys/attributes`; try { const response = await axios(url, { method: 'get', headers: { 'Content-Type': 'application/json', 'X-Authorization': 'Bearer ' + process.env[tokenRand+'TB_TOKEN'] } }); return response.data } catch (err) { return { error: true, message: `getAllObjectKeys(), Request error: ${err}` } } } /** * If keys - null - trying to get all attributes * @param {String} name * @param {String} type * @param {String} keys */ async function objectIDandKeys(name, type, keys = null, telemetryFlag = null) { if (((typeof name === "undefined") || (name === null)) || ((typeof type === "undefined") || (type === null))) { return { error: true, message: `objectIDandKeys(), Error: type or name are not defined or null!` } } const id = await getObjectID(name, type); // error while getting id if (id.error) { return { error: true, message: id.message }; } let attributeKeys = keys; if (attributeKeys === null) { attributeKeys = await getAllObjectKeys(id, type); if (attributeKeys.error) { return { error: true, message: `Error while getting keys ${attributeKeys.message}` }; } } let url = ''; if (telemetryFlag) { // get telemetry data with keys and vals url = `http://${process.env.TB_HOST}:${process.env.TB_PORT}/api/plugins/telemetry/${type.toUpperCase()}/${id}/values/timeseries`; } // get keys and their values by default if ((telemetryFlag === null) || !(telemetryFlag)) { url = `http://${process.env.TB_HOST}:${process.env.TB_PORT}/api/plugins/telemetry/${type.toUpperCase()}/${id}/values/attributes?keys=${attributeKeys}`; } try { const response = await axios(url, { method: 'get', headers: { 'Content-Type': 'application/json', 'X-Authorization': 'Bearer ' + process.env[tokenRand+'TB_TOKEN'] } }); const payload = response.data; if (payload.length === 0) { return { error: true, message: `objectIDandKeys(), Error: empty response payload!` }; } // if we want to recieve only data with certain key if (telemetryFlag && payload) { if (!(keys in payload)) { return { error: true, message: `Key ${keys} is not found in telemetry of object!` }; } if (payload[keys].length === 1) { return { data: payload[keys][0].value, id: id, } } } const result = { id: id, name: name, type: type, } // assign attribute keys and its values to object for (let i = 0; i < payload.length; i++) { result[payload[i].key] = payload[i].value } return result } catch (err) { return { error: true, message: `objectIDandKeys(), Error: ${err}` } } } async function getObjectKeys(id, type, keys = null) { if (((typeof id === "undefined") || (id === null)) || ((typeof type === "undefined") || (type === null))) { return { error: true, message: "getObjectKeys(), Error: type or id are not defined or null!" } } let attributeKeys = keys; if (attributeKeys === null) { attributeKeys = await getAllObjectKeys(id, type); // error while getting attributeKeys if (attributeKeys.error) { return { error: true, message: `Get keys error: ${attributeKeys.message }` }; } } const url = `http://${process.env.TB_HOST}:${process.env.TB_PORT}/api/plugins/telemetry/${type.toUpperCase()}/${id}/values/attributes?keys=${attributeKeys}` try { const response = await axios(url, { method: 'get', headers: { 'Content-Type': 'application/json', 'X-Authorization': 'Bearer ' + process.env[tokenRand+'TB_TOKEN'] } }); const payload = response.data; if (payload.length === 0) { return []; } const result = { id: id, type: type, } for (let i = 0; i < payload.length; i++) { result[payload[i].key] = payload[i].value } return result } catch (err) { return { error: true, message: `getObjectKeys(), ${err}` } } } async function getObjectTelemetry(id, type, keys = null, startTS, endTS, limit) { if (((typeof id === "undefined") || (id === null)) || ((typeof type === "undefined") || (type === null))) { return { error: true, message: "getObjectKeys(), Error: type or id are not defined or null!" } } let telemetryKeys = keys; if (telemetryKeys === null) { return { error: true, message: `Get keys error: keys are null` }; } const url = `http://${process.env.TB_HOST}:${process.env.TB_PORT}/api/plugins/telemetry/${type.toUpperCase()}/${id}/values/timeseries?keys=${telemetryKeys}&limit=${limit}&startTs=${startTS}&endTs=${endTS}` try { const response = await axios(url, { method: 'get', headers: { 'Content-Type': 'application/json', 'X-Authorization': 'Bearer ' + process.env[tokenRand+'TB_TOKEN'] } }); const payload = response.data; if (payload.length === 0) { return []; } const result = { id: id, type: type, } for (let key in payload) { result[key] = payload[key] } return result } catch (err) { return { error: true, message: `getObjectKeys(), ${err}` } } } async function allObjectsIDbyType(customType, tbType, tokenFlag = false) { if (((typeof customType === "undefined") || (customType === null)) || ((typeof tbType === "undefined") || (tbType === null))) { return { error: true, message: 'allObjectsIDbyType(), Error: customType or tbType are not defined or null!' }; } let url = ''; switch (tbType.toUpperCase()) { case possibleEntityTypes.asset: url = `http://${process.env.TB_HOST}:${process.env.TB_PORT}/api/tenant/assets?type=${encodeURI(customType)}&pageSize=999999999&page=0` break; case possibleEntityTypes.device: url = `http://${process.env.TB_HOST}:${process.env.TB_PORT}/api/tenant/devices?type=${encodeURI(customType)}&pageSize=999999999&page=0` break; case possibleEntityTypes.view: url = `http://${process.env.TB_HOST}:${process.env.TB_PORT}/api/tenant/entityViews?type=${encodeURI(customType)}&pageSize=999999999&page=0` break; default: return { error: true, message: `allObjectsIDbyType(), Error: Get unknown TB type ${tbType}; Custom type ${customType}` }; } if (url.length === 0) { return { error: true, message: `allObjectsIDbyType(), Error: URL is empty!` }; } try { const response = await axios(url, { method: 'get', headers: { 'Content-Type': 'application/json', 'X-Authorization': 'Bearer ' + process.env[tokenRand+'TB_TOKEN'] } }); const payload = response.data.data; if (payload.length === 0) { return { error: true, message: `allObjectsIDbyType(), Not found objects for Custom type ${customType} & TB type ${tbType}` }; } let result = []; for (let i = 0; i < payload.length; i++) { result.push({ id: payload[i].id.id, name: payload[i].name, type: payload[i].type, entityType: payload[i].id.entityType }); } // Set device token for response if it's device and tokenFlag is true if (tokenFlag && tbType.toUpperCase() === possibleEntityTypes.device) { for (let i = 0; i < result.length; i++) { const token = await getDeviceToken(result[i].id); if (token.error) { continue; } result[i].deviceToken = token; } } return result; } catch (err) { return { error: true, message: `allObjectsIDbyType(), Error: ${err}` } } } /** * If keys - null - trying to get all attributes * @param {String} name * @param {String} entity_type asset/device/entity_view * @param {String} keys */ async function allObjectsIDandKeysByType(customType, entityType, keys = null) { if (((typeof customType === "undefined") || (customType === null)) || ((typeof entityType === "undefined") || (entityType === null))) { return { error: true, message: `allObjectsIDandKeysByType(), Error: customType or entityType are not defined or null!` }; } const ids = await allObjectsIDbyType(customType, entityType); if (ids.error) { return { error: true, message: `Get ids by custom type error: ${ids.message}` }; } const result = []; for (let i = 0; i < ids.length; i++) { let object = await getObjectKeys(ids[i].id, entityType, keys); // skip assigning keys to object in case if error! if (object.error) { continue; } if(object.name){ object.attr_name = object.name } object.name = ids[i].name result.push(object) } // In case of keys not found, return ids of objects with names and types if (result.length === 0) { return ids; } return result } /** * @param {String} name * @param {String} entity_type asset/device/entity_view * @param {String} direction 'to'||'from'. to = childs, from = parents * @param {Integer} level int if 0 or null - all levels */ // by default set max level async function getRelations(name, entity_type, direction, level = 3,id=null) { // if (level === 0) // level = 3 if(id === null) id = await getObjectID(name, entity_type); if (id.error) { return { "error": true, "message": id.message } } const relDirection = direction.toLowerCase() let url = ""; switch (relDirection) { case "to": url = "http://" + process.env.TB_HOST + ':' + process.env.TB_PORT + "/api/relations/info?fromId=" + id + "&fromType=" + entity_type.toUpperCase(); break; case "from": url = "http://" + process.env.TB_HOST + ':' + process.env.TB_PORT + "/api/relations/info?toId=" + id + "&toType=" + entity_type.toUpperCase(); break; default: return { "error": true, "message": `getRelations(), Error: get incorrect direction ${relDirection}` }; } if (url.length === 0) { return { "error": true, "message": "getRelations(), Error: request url length = 0! Can't get relations!" } } try { let response = await axios(url, { method: 'get', headers: { 'Content-Type': 'application/json', 'X-Authorization': 'Bearer ' + process.env[tokenRand+'TB_TOKEN'] } }); //2ceacf40-78d3-11ea-a1c7-d1e730c27b32 //2ce83730-78d3-11ea-a1c7-d1e730c27b32 //http://84.201.141.244:8080/api/relations/info?fromId=2ceacf40-78d3-11ea-a1c7-d1e730c27b32&fromType=ENTITY_VIEW const payload = response.data; if (payload.length === 0) { return { "error": true, "message": "getRelations(), Error: empty relations data response!" } } var answer = [] for (let i = 0; i < payload.length; i++) { answer.push({ id: payload[i][direction].id, name: payload[i][direction + 'Name'], entity_type: payload[i][direction].entityType }) } if (level === 1) { return answer } /* for(let i=0; i< answer.length; i++){ //answer[i].childs = [] for (let ii=level; ii>0; ii--){ //console.log(answer[i]) answer[i].childs = await getRelations(answer[i].name,answer[i].entity_type,direction,ii) //console.log(answer[i].childs ) } } */ for (let i = 0; i < answer.length; i++) { answer[i].childs = await getRelations(answer[i].name, answer[i].entity_type, direction, 1); // go to next item on error! Discuss it in future! if (answer[i].childs.error) { continue; } } if (level === 2) { return answer } for (let i = 0; i < answer.length; i++) { for (let ii = 0; ii < answer[i].childs.length; ii++) { answer[i].childs[ii].childs = await getRelations(answer[i].childs[ii].name, answer[i].childs[ii].entity_type, direction, 1); // go to next item on error! Discuss it in future! if (answer[i].childs[ii].childs.error) { continue; } } } return answer } catch (err) { return { "error": true, "message": `getRelations(), ${err}` } } } async function getDeviceToken(deviceId) { if ((typeof deviceId === "undefined") || (deviceId === null)) { return { "error": true, "message": "getDeviceToken(), Error: deviceId is not defined or null!" } } const tokenUrl = "http://" + process.env.TB_HOST + ':' + process.env.TB_PORT + `/api/device/${deviceId}/credentials`; const credentials = { "method": 'get', "url": tokenUrl, "headers": { 'Content-Type': 'application/json', 'X-Authorization': 'Bearer ' + process.env[tokenRand+'TB_TOKEN'] } }; try { const response = await axios(credentials); if (response.status === 200) { const token = response.data.credentialsId; return token; } } catch (err) { return { "error": true, "message": `getDeviceToken(), ${err}` } } } async function getTenants(tenantID) { const tokenUrl = "http://" + process.env.TB_HOST + ':' + process.env.TB_PORT + `/api/tenant/${tenantID}/users?pageSize=99999&page=0`; const credentials = { "method": 'get', "url": tokenUrl, "headers": { 'Content-Type': 'application/json', 'X-Authorization': 'Bearer ' + process.env.TB_SYSADMIN_TOKEN } }; try { const response = await axios(credentials); if (response.status === 200) { let tenants = [] for(let i in response.data.data){ tenants.push(response.data.data[i].email) } return tenants; } } catch (err) { return { "error": true, "message": `getDeviceToken(), ${err}` } } } module.exports = { objectID: getObjectID, objectIDandKeys: objectIDandKeys, allObjectsIDbyType: allObjectsIDbyType, allObjectsIDandKeysByType: allObjectsIDandKeysByType, relations: getRelations, getDeviceToken: getDeviceToken, getObjectKeys: getObjectKeys, getAllObjectKeys: getAllObjectKeys, getObjectTelemetry, getTenants };