TB-39: UI: Add Gateway flag. (#44)
* TB-39: UI: Add Gateway flag. * TB-39: UI: Update package version.
This commit is contained in:
parent
31b248922e
commit
7c6cdb148c
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thingsboard",
|
||||
"private": true,
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.0",
|
||||
"description": "Thingsboard UI",
|
||||
"licenses": [
|
||||
{
|
||||
|
||||
@ -52,6 +52,11 @@ const apiProxy = httpProxy.createProxyServer({
|
||||
}
|
||||
});
|
||||
|
||||
apiProxy.on('error', function (err, req, res) {
|
||||
console.warn('API proxy error: ' + err);
|
||||
res.end('Error.');
|
||||
});
|
||||
|
||||
console.info(`Forwarding API requests to http://${forwardHost}:${forwardPort}`);
|
||||
|
||||
app.all('/api/*', (req, res) => {
|
||||
|
||||
@ -256,6 +256,9 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
|
||||
type: types.dataKeyType.timeseries,
|
||||
onData: function (data) {
|
||||
onData(data, types.dataKeyType.timeseries);
|
||||
},
|
||||
onReconnected: function() {
|
||||
onReconnected();
|
||||
}
|
||||
};
|
||||
|
||||
@ -278,6 +281,9 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
|
||||
type: types.dataKeyType.timeseries,
|
||||
onData: function (data) {
|
||||
onData(data, types.dataKeyType.timeseries);
|
||||
},
|
||||
onReconnected: function() {
|
||||
onReconnected();
|
||||
}
|
||||
};
|
||||
|
||||
@ -299,6 +305,9 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
|
||||
type: types.dataKeyType.attribute,
|
||||
onData: function (data) {
|
||||
onData(data, types.dataKeyType.attribute);
|
||||
},
|
||||
onReconnected: function() {
|
||||
onReconnected();
|
||||
}
|
||||
};
|
||||
|
||||
@ -428,6 +437,25 @@ function DatasourceSubscription(datasourceSubscription, telemetryWebsocketServic
|
||||
}
|
||||
}
|
||||
|
||||
function onReconnected() {
|
||||
if (datasourceType === types.datasourceType.device) {
|
||||
for (var key in dataKeys) {
|
||||
var dataKeysList = dataKeys[key];
|
||||
for (var i = 0; i < dataKeysList.length; i++) {
|
||||
var dataKey = dataKeysList[i];
|
||||
var datasourceKey = key + '_' + i;
|
||||
datasourceData[datasourceKey] = [];
|
||||
for (var l in listeners) {
|
||||
var listener = listeners[l];
|
||||
listener.dataUpdated(datasourceData[datasourceKey],
|
||||
listener.datasourceIndex,
|
||||
dataKey.index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onData(sourceData, type) {
|
||||
for (var keyName in sourceData) {
|
||||
var keyData = sourceData[keyName];
|
||||
|
||||
@ -307,12 +307,12 @@ function DeviceService($http, $q, $filter, telemetryWebsocketService, types) {
|
||||
onSubscriptionData(data, subscriptionId);
|
||||
}
|
||||
};
|
||||
telemetryWebsocketService.subscribe(subscriber);
|
||||
deviceAttributesSubscription = {
|
||||
subscriber: subscriber,
|
||||
attributes: null
|
||||
}
|
||||
deviceAttributesSubscriptionMap[subscriptionId] = deviceAttributesSubscription;
|
||||
telemetryWebsocketService.subscribe(subscriber);
|
||||
}
|
||||
return subscriptionId;
|
||||
}
|
||||
|
||||
@ -20,11 +20,17 @@ export default angular.module('thingsboard.api.telemetryWebsocket', [thingsboard
|
||||
.factory('telemetryWebsocketService', TelemetryWebsocketService)
|
||||
.name;
|
||||
|
||||
const RECONNECT_INTERVAL = 5000;
|
||||
const WS_IDLE_TIMEOUT = 90000;
|
||||
|
||||
/*@ngInject*/
|
||||
function TelemetryWebsocketService($websocket, $timeout, $window, types, userService) {
|
||||
function TelemetryWebsocketService($rootScope, $websocket, $timeout, $window, types, userService) {
|
||||
|
||||
var isOpening = false,
|
||||
isOpened = false,
|
||||
isActive = false,
|
||||
isReconnect = false,
|
||||
reconnectSubscribers = [],
|
||||
lastCmdId = 0,
|
||||
subscribers = {},
|
||||
subscribersCount = 0,
|
||||
@ -36,7 +42,8 @@ function TelemetryWebsocketService($websocket, $timeout, $window, types, userSer
|
||||
telemetryUri,
|
||||
dataStream,
|
||||
location = $window.location,
|
||||
socketCloseTimer;
|
||||
socketCloseTimer,
|
||||
reconnectTimer;
|
||||
|
||||
if (location.protocol === "https:") {
|
||||
telemetryUri = "wss:";
|
||||
@ -46,11 +53,18 @@ function TelemetryWebsocketService($websocket, $timeout, $window, types, userSer
|
||||
telemetryUri += "//" + location.hostname + ":" + location.port;
|
||||
telemetryUri += "/api/ws/plugins/telemetry";
|
||||
|
||||
|
||||
var service = {
|
||||
subscribe: subscribe,
|
||||
unsubscribe: unsubscribe
|
||||
}
|
||||
|
||||
$rootScope.telemetryWsLogoutHandle = $rootScope.$on('unauthenticated', function (event, doLogout) {
|
||||
if (doLogout) {
|
||||
reset(true);
|
||||
}
|
||||
});
|
||||
|
||||
return service;
|
||||
|
||||
function publishCommands () {
|
||||
@ -74,12 +88,42 @@ function TelemetryWebsocketService($websocket, $timeout, $window, types, userSer
|
||||
function onOpen () {
|
||||
isOpening = false;
|
||||
isOpened = true;
|
||||
if (reconnectTimer) {
|
||||
$timeout.cancel(reconnectTimer);
|
||||
reconnectTimer = null;
|
||||
}
|
||||
if (isReconnect) {
|
||||
isReconnect = false;
|
||||
for (var r in reconnectSubscribers) {
|
||||
var reconnectSubscriber = reconnectSubscribers[r];
|
||||
if (reconnectSubscriber.onReconnected) {
|
||||
reconnectSubscriber.onReconnected();
|
||||
}
|
||||
subscribe(reconnectSubscriber);
|
||||
}
|
||||
reconnectSubscribers = [];
|
||||
} else {
|
||||
publishCommands();
|
||||
}
|
||||
}
|
||||
|
||||
function onClose () {
|
||||
isOpening = false;
|
||||
isOpened = false;
|
||||
if (isActive) {
|
||||
if (!isReconnect) {
|
||||
reconnectSubscribers = [];
|
||||
for (var id in subscribers) {
|
||||
reconnectSubscribers.push(subscribers[id]);
|
||||
}
|
||||
reset(false);
|
||||
isReconnect = true;
|
||||
}
|
||||
if (reconnectTimer) {
|
||||
$timeout.cancel(reconnectTimer);
|
||||
}
|
||||
reconnectTimer = $timeout(tryOpenSocket, RECONNECT_INTERVAL, false);
|
||||
}
|
||||
}
|
||||
|
||||
function onMessage (message) {
|
||||
@ -137,28 +181,60 @@ function TelemetryWebsocketService($websocket, $timeout, $window, types, userSer
|
||||
function checkToClose () {
|
||||
if (subscribersCount === 0 && isOpened) {
|
||||
if (!socketCloseTimer) {
|
||||
socketCloseTimer = $timeout(closeSocket, 90000, false);
|
||||
socketCloseTimer = $timeout(closeSocket, WS_IDLE_TIMEOUT, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function tryOpenSocket () {
|
||||
isActive = true;
|
||||
if (!isOpened && !isOpening) {
|
||||
isOpening = true;
|
||||
dataStream = $websocket(telemetryUri + '?token=' + userService.getJwtToken());
|
||||
if (userService.isJwtTokenValid()) {
|
||||
openSocket(userService.getJwtToken());
|
||||
} else {
|
||||
userService.refreshJwtToken().then(function success() {
|
||||
openSocket(userService.getJwtToken());
|
||||
}, function fail() {
|
||||
isOpening = false;
|
||||
$rootScope.$broadcast('unauthenticated');
|
||||
});
|
||||
}
|
||||
}
|
||||
if (socketCloseTimer) {
|
||||
$timeout.cancel(socketCloseTimer);
|
||||
socketCloseTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
function openSocket(token) {
|
||||
dataStream = $websocket(telemetryUri + '?token=' + token);
|
||||
dataStream.onError(onError);
|
||||
dataStream.onOpen(onOpen);
|
||||
dataStream.onClose(onClose);
|
||||
dataStream.onMessage(onMessage);
|
||||
}
|
||||
if (socketCloseTimer) {
|
||||
$timeout.cancel(socketCloseTimer);
|
||||
}
|
||||
}
|
||||
|
||||
function closeSocket() {
|
||||
isActive = false;
|
||||
if (isOpened) {
|
||||
dataStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
function reset(closeSocket) {
|
||||
if (socketCloseTimer) {
|
||||
$timeout.cancel(socketCloseTimer);
|
||||
socketCloseTimer = null;
|
||||
}
|
||||
lastCmdId = 0;
|
||||
subscribers = {};
|
||||
subscribersCount = 0;
|
||||
cmdsWrapper.tsSubCmds = [];
|
||||
cmdsWrapper.historyCmds = [];
|
||||
cmdsWrapper.attrSubCmds = [];
|
||||
if (closeSocket) {
|
||||
closeSocket();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,6 +147,12 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS
|
||||
scope.subscriptionId = newSubscriptionId;
|
||||
}
|
||||
|
||||
scope.$on('$destroy', function() {
|
||||
if (scope.subscriptionId) {
|
||||
deviceService.unsubscribeForDeviceAttributes(scope.subscriptionId);
|
||||
}
|
||||
});
|
||||
|
||||
scope.editAttribute = function($event, attribute) {
|
||||
if (!scope.attributeScope.clientSide) {
|
||||
$event.stopPropagation();
|
||||
|
||||
@ -59,6 +59,11 @@
|
||||
<div translate ng-message="required">device.name-required</div>
|
||||
</div>
|
||||
</md-input-container>
|
||||
<md-input-container class="md-block">
|
||||
<md-checkbox ng-disabled="loading || !isEdit" flex aria-label="{{ 'device.is-gateway' | translate }}"
|
||||
ng-model="device.additionalInfo.gateway">{{ 'device.is-gateway' | translate }}
|
||||
</md-checkbox>
|
||||
</md-input-container>
|
||||
<md-input-container class="md-block">
|
||||
<label translate>device.description</label>
|
||||
<textarea ng-model="device.additionalInfo.description" rows="2"></textarea>
|
||||
|
||||
@ -32,11 +32,13 @@ export default function DeviceDirective($compile, $templateCache, toast, $transl
|
||||
|
||||
scope.$watch('device', function(newVal) {
|
||||
if (newVal) {
|
||||
if (scope.device.id) {
|
||||
deviceService.getDeviceCredentials(scope.device.id.id).then(
|
||||
function success(credentials) {
|
||||
scope.deviceCredentials = credentials;
|
||||
}
|
||||
);
|
||||
}
|
||||
if (scope.device.customerId && scope.device.customerId.id !== types.id.nullUid) {
|
||||
scope.isAssignedToCustomer = true;
|
||||
customerService.getCustomer(scope.device.customerId.id).then(
|
||||
|
||||
@ -323,7 +323,8 @@
|
||||
"accessTokenCopiedMessage": "Device access token has been copied to clipboard",
|
||||
"assignedToCustomer": "Assigned to customer",
|
||||
"unable-delete-device-alias-title": "Unable to delete device alias",
|
||||
"unable-delete-device-alias-text": "Device alias '{{deviceAlias}}' can't be deleted as it used by the following widget(s):<br/>{{widgetsList}}"
|
||||
"unable-delete-device-alias-text": "Device alias '{{deviceAlias}}' can't be deleted as it used by the following widget(s):<br/>{{widgetsList}}",
|
||||
"is-gateway": "Is gateway"
|
||||
},
|
||||
"dialog": {
|
||||
"close": "Close dialog"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user