383 lines
14 KiB
JavaScript
383 lines
14 KiB
JavaScript
/*
|
|
* Copyright © 2016 The Thingsboard Authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
import thingsboardTypes from '../common/types.constant';
|
|
|
|
export default angular.module('thingsboard.api.device', [thingsboardTypes])
|
|
.factory('deviceService', DeviceService)
|
|
.name;
|
|
|
|
/*@ngInject*/
|
|
function DeviceService($http, $q, $filter, telemetryWebsocketService, types) {
|
|
|
|
|
|
var deviceAttributesSubscriptionMap = {};
|
|
|
|
var service = {
|
|
assignDeviceToCustomer: assignDeviceToCustomer,
|
|
deleteDevice: deleteDevice,
|
|
getCustomerDevices: getCustomerDevices,
|
|
getDevice: getDevice,
|
|
getDeviceCredentials: getDeviceCredentials,
|
|
getDeviceKeys: getDeviceKeys,
|
|
getDeviceTimeseriesValues: getDeviceTimeseriesValues,
|
|
getTenantDevices: getTenantDevices,
|
|
saveDevice: saveDevice,
|
|
saveDeviceCredentials: saveDeviceCredentials,
|
|
unassignDeviceFromCustomer: unassignDeviceFromCustomer,
|
|
getDeviceAttributes: getDeviceAttributes,
|
|
subscribeForDeviceAttributes: subscribeForDeviceAttributes,
|
|
unsubscribeForDeviceAttributes: unsubscribeForDeviceAttributes,
|
|
saveDeviceAttributes: saveDeviceAttributes,
|
|
deleteDeviceAttributes: deleteDeviceAttributes,
|
|
sendOneWayRpcCommand: sendOneWayRpcCommand,
|
|
sendTwoWayRpcCommand: sendTwoWayRpcCommand
|
|
}
|
|
|
|
return service;
|
|
|
|
function getTenantDevices(pageLink) {
|
|
var deferred = $q.defer();
|
|
var url = '/api/tenant/devices?limit=' + pageLink.limit;
|
|
if (angular.isDefined(pageLink.textSearch)) {
|
|
url += '&textSearch=' + pageLink.textSearch;
|
|
}
|
|
if (angular.isDefined(pageLink.idOffset)) {
|
|
url += '&idOffset=' + pageLink.idOffset;
|
|
}
|
|
if (angular.isDefined(pageLink.textOffset)) {
|
|
url += '&textOffset=' + pageLink.textOffset;
|
|
}
|
|
$http.get(url, null).then(function success(response) {
|
|
deferred.resolve(response.data);
|
|
}, function fail() {
|
|
deferred.reject();
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function getCustomerDevices(customerId, pageLink) {
|
|
var deferred = $q.defer();
|
|
var url = '/api/customer/' + customerId + '/devices?limit=' + pageLink.limit;
|
|
if (angular.isDefined(pageLink.textSearch)) {
|
|
url += '&textSearch=' + pageLink.textSearch;
|
|
}
|
|
if (angular.isDefined(pageLink.idOffset)) {
|
|
url += '&idOffset=' + pageLink.idOffset;
|
|
}
|
|
if (angular.isDefined(pageLink.textOffset)) {
|
|
url += '&textOffset=' + pageLink.textOffset;
|
|
}
|
|
$http.get(url, null).then(function success(response) {
|
|
deferred.resolve(response.data);
|
|
}, function fail() {
|
|
deferred.reject();
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function getDevice(deviceId) {
|
|
var deferred = $q.defer();
|
|
var url = '/api/device/' + deviceId;
|
|
$http.get(url, null).then(function success(response) {
|
|
deferred.resolve(response.data);
|
|
}, function fail(response) {
|
|
deferred.reject(response.data);
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function saveDevice(device) {
|
|
var deferred = $q.defer();
|
|
var url = '/api/device';
|
|
$http.post(url, device).then(function success(response) {
|
|
deferred.resolve(response.data);
|
|
}, function fail(response) {
|
|
deferred.reject(response.data);
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function deleteDevice(deviceId) {
|
|
var deferred = $q.defer();
|
|
var url = '/api/device/' + deviceId;
|
|
$http.delete(url).then(function success() {
|
|
deferred.resolve();
|
|
}, function fail(response) {
|
|
deferred.reject(response.data);
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function getDeviceCredentials(deviceId) {
|
|
var deferred = $q.defer();
|
|
var url = '/api/device/' + deviceId + '/credentials';
|
|
$http.get(url, null).then(function success(response) {
|
|
deferred.resolve(response.data);
|
|
}, function fail(response) {
|
|
deferred.reject(response.data);
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function saveDeviceCredentials(deviceCredentials) {
|
|
var deferred = $q.defer();
|
|
var url = '/api/device/credentials';
|
|
$http.post(url, deviceCredentials).then(function success(response) {
|
|
deferred.resolve(response.data);
|
|
}, function fail(response) {
|
|
deferred.reject(response.data);
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function assignDeviceToCustomer(customerId, deviceId) {
|
|
var deferred = $q.defer();
|
|
var url = '/api/customer/' + customerId + '/device/' + deviceId;
|
|
$http.post(url, null).then(function success() {
|
|
deferred.resolve();
|
|
}, function fail(response) {
|
|
deferred.reject(response.data);
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function unassignDeviceFromCustomer(deviceId) {
|
|
var deferred = $q.defer();
|
|
var url = '/api/customer/device/' + deviceId;
|
|
$http.delete(url).then(function success() {
|
|
deferred.resolve();
|
|
}, function fail(response) {
|
|
deferred.reject(response.data);
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function getDeviceKeys(deviceId, query, type) {
|
|
var deferred = $q.defer();
|
|
var url = '/api/plugins/telemetry/' + deviceId + '/keys/';
|
|
if (type === types.dataKeyType.timeseries) {
|
|
url += 'timeseries';
|
|
} else if (type === types.dataKeyType.attribute) {
|
|
url += 'attributes';
|
|
}
|
|
$http.get(url, null).then(function success(response) {
|
|
var result = [];
|
|
if (response.data) {
|
|
if (query) {
|
|
var dataKeys = response.data;
|
|
var lowercaseQuery = angular.lowercase(query);
|
|
for (var i in dataKeys) {
|
|
if (angular.lowercase(dataKeys[i]).indexOf(lowercaseQuery) === 0) {
|
|
result.push(dataKeys[i]);
|
|
}
|
|
}
|
|
} else {
|
|
result = response.data;
|
|
}
|
|
}
|
|
deferred.resolve(result);
|
|
}, function fail(response) {
|
|
deferred.reject(response.data);
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function getDeviceTimeseriesValues(deviceId, keys, startTs, endTs, limit) {
|
|
var deferred = $q.defer();
|
|
var url = '/api/plugins/telemetry/' + deviceId + '/values/timeseries';
|
|
url += '?keys=' + keys;
|
|
url += '&startTs=' + startTs;
|
|
url += '&endTs=' + endTs;
|
|
if (angular.isDefined(limit)) {
|
|
url += '&limit=' + limit;
|
|
}
|
|
$http.get(url, null).then(function success(response) {
|
|
deferred.resolve(response.data);
|
|
}, function fail(response) {
|
|
deferred.reject(response.data);
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function processDeviceAttributes(attributes, query, deferred, successCallback, update) {
|
|
attributes = $filter('orderBy')(attributes, query.order);
|
|
if (query.search != null) {
|
|
attributes = $filter('filter')(attributes, {key: query.search});
|
|
}
|
|
var responseData = {
|
|
count: attributes.length
|
|
}
|
|
var startIndex = query.limit * (query.page - 1);
|
|
responseData.data = attributes.slice(startIndex, startIndex + query.limit);
|
|
successCallback(responseData, update);
|
|
if (deferred) {
|
|
deferred.resolve();
|
|
}
|
|
}
|
|
|
|
function getDeviceAttributes(deviceId, attributeScope, query, successCallback) {
|
|
var deferred = $q.defer();
|
|
var subscriptionId = deviceId + attributeScope;
|
|
var das = deviceAttributesSubscriptionMap[subscriptionId];
|
|
if (das) {
|
|
if (das.attributes) {
|
|
processDeviceAttributes(das.attributes, query, deferred, successCallback);
|
|
das.subscriptionCallback = function(attributes) {
|
|
processDeviceAttributes(attributes, query, null, successCallback, true);
|
|
}
|
|
} else {
|
|
das.subscriptionCallback = function(attributes) {
|
|
processDeviceAttributes(attributes, query, deferred, successCallback);
|
|
das.subscriptionCallback = function(attributes) {
|
|
processDeviceAttributes(attributes, query, null, successCallback, true);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
var url = '/api/plugins/telemetry/' + deviceId + '/values/attributes/' + attributeScope;
|
|
$http.get(url, null).then(function success(response) {
|
|
processDeviceAttributes(response.data, query, deferred, successCallback);
|
|
}, function fail() {
|
|
deferred.reject();
|
|
});
|
|
}
|
|
return deferred;
|
|
}
|
|
|
|
function onSubscriptionData(data, subscriptionId) {
|
|
var deviceAttributesSubscription = deviceAttributesSubscriptionMap[subscriptionId];
|
|
if (deviceAttributesSubscription) {
|
|
if (!deviceAttributesSubscription.attributes) {
|
|
deviceAttributesSubscription.attributes = [];
|
|
deviceAttributesSubscription.keys = {};
|
|
}
|
|
var attributes = deviceAttributesSubscription.attributes;
|
|
var keys = deviceAttributesSubscription.keys;
|
|
for (var key in data) {
|
|
var index = keys[key];
|
|
var attribute;
|
|
if (index > -1) {
|
|
attribute = attributes[index];
|
|
} else {
|
|
attribute = {
|
|
key: key
|
|
};
|
|
index = attributes.push(attribute)-1;
|
|
keys[key] = index;
|
|
}
|
|
var attrData = data[key][0];
|
|
attribute.lastUpdateTs = attrData[0];
|
|
attribute.value = attrData[1];
|
|
}
|
|
if (deviceAttributesSubscription.subscriptionCallback) {
|
|
deviceAttributesSubscription.subscriptionCallback(attributes);
|
|
}
|
|
}
|
|
}
|
|
|
|
function subscribeForDeviceAttributes(deviceId, attributeScope) {
|
|
var subscriptionId = deviceId + attributeScope;
|
|
var deviceAttributesSubscription = deviceAttributesSubscriptionMap[subscriptionId];
|
|
if (!deviceAttributesSubscription) {
|
|
var subscriptionCommand = {
|
|
deviceId: deviceId,
|
|
scope: attributeScope
|
|
};
|
|
|
|
var type = attributeScope === types.latestTelemetry.value ?
|
|
types.dataKeyType.timeseries : types.dataKeyType.attribute;
|
|
|
|
var subscriber = {
|
|
subscriptionCommand: subscriptionCommand,
|
|
type: type,
|
|
onData: function (data) {
|
|
onSubscriptionData(data, subscriptionId);
|
|
}
|
|
};
|
|
telemetryWebsocketService.subscribe(subscriber);
|
|
deviceAttributesSubscription = {
|
|
subscriber: subscriber,
|
|
attributes: null
|
|
}
|
|
deviceAttributesSubscriptionMap[subscriptionId] = deviceAttributesSubscription;
|
|
}
|
|
return subscriptionId;
|
|
}
|
|
function unsubscribeForDeviceAttributes(subscriptionId) {
|
|
var deviceAttributesSubscription = deviceAttributesSubscriptionMap[subscriptionId];
|
|
if (deviceAttributesSubscription) {
|
|
telemetryWebsocketService.unsubscribe(deviceAttributesSubscription.subscriber);
|
|
delete deviceAttributesSubscriptionMap[subscriptionId];
|
|
}
|
|
}
|
|
|
|
function saveDeviceAttributes(deviceId, attributeScope, attributes) {
|
|
var deferred = $q.defer();
|
|
var attributesData = {};
|
|
for (var a in attributes) {
|
|
attributesData[attributes[a].key] = attributes[a].value;
|
|
}
|
|
var url = '/api/plugins/telemetry/' + deviceId + '/' + attributeScope;
|
|
$http.post(url, attributesData).then(function success(response) {
|
|
deferred.resolve(response.data);
|
|
}, function fail(response) {
|
|
deferred.reject(response.data);
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function deleteDeviceAttributes(deviceId, attributeScope, attributes) {
|
|
var deferred = $q.defer();
|
|
var keys = '';
|
|
for (var i = 0; i < attributes.length; i++) {
|
|
if (i > 0) {
|
|
keys += ',';
|
|
}
|
|
keys += attributes[i].key;
|
|
}
|
|
var url = '/api/plugins/telemetry/' + deviceId + '/' + attributeScope + '?keys=' + keys;
|
|
$http.delete(url).then(function success() {
|
|
deferred.resolve();
|
|
}, function fail() {
|
|
deferred.reject();
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function sendOneWayRpcCommand(deviceId, requestBody) {
|
|
var deferred = $q.defer();
|
|
var url = '/api/plugins/rpc/oneway/' + deviceId;
|
|
$http.post(url, requestBody).then(function success(response) {
|
|
deferred.resolve(response.data);
|
|
}, function fail(rejection) {
|
|
deferred.reject(rejection);
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
function sendTwoWayRpcCommand(deviceId, requestBody) {
|
|
var deferred = $q.defer();
|
|
var url = '/api/plugins/rpc/twoway/' + deviceId;
|
|
$http.post(url, requestBody).then(function success(response) {
|
|
deferred.resolve(response.data);
|
|
}, function fail(rejection) {
|
|
deferred.reject(rejection);
|
|
});
|
|
return deferred.promise;
|
|
}
|
|
|
|
}
|