/*
* Copyright © 2016-2017 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 './led-indicator.scss';
import tinycolor from 'tinycolor2';
/* eslint-disable import/no-unresolved, import/default */
import ledIndicatorTemplate from './led-indicator.tpl.html';
/* eslint-enable import/no-unresolved, import/default */
export default angular.module('thingsboard.widgets.rpc.ledIndicator', [])
.directive('tbLedIndicator', LedIndicator)
.name;
/*@ngInject*/
function LedIndicator() {
return {
restrict: "E",
scope: true,
bindToController: {
ctx: '='
},
controller: LedIndicatorController,
controllerAs: 'vm',
templateUrl: ledIndicatorTemplate
};
}
/*@ngInject*/
function LedIndicatorController($element, $scope, $timeout) {
let vm = this;
vm.showTitle = false;
vm.value = false;
vm.error = '';
var led = angular.element('.led', $element),
ledContainer = angular.element('#led-container', $element),
textMeasure = angular.element('#text-measure', $element),
ledTitleContainer = angular.element('.title-container', $element),
ledTitle = angular.element('.led-title', $element),
ledErrorContainer = angular.element('.error-container', $element),
ledError = angular.element('.led-error', $element);
$scope.$watch('vm.ctx', () => {
if (vm.ctx) {
init();
}
});
$scope.$on('$destroy', () => {
vm.destroyed = true;
if (vm.requestValueTimeoutHandle) {
$timeout.cancel(vm.requestValueTimeoutHandle);
}
});
resize();
function init() {
vm.title = angular.isDefined(vm.ctx.settings.title) ? vm.ctx.settings.title : '';
vm.showTitle = vm.title && vm.title.length ? true : false;
var origColor = angular.isDefined(vm.ctx.settings.ledColor) ? vm.ctx.settings.ledColor : 'green';
vm.ledColor = tinycolor(origColor).brighten(30).toHexString();
vm.ledMiddleColor = tinycolor(origColor).toHexString();
vm.disabledColor = tinycolor(origColor).darken(40).toHexString();
vm.disabledMiddleColor = tinycolor(origColor).darken(60).toHexString();
vm.ctx.resize = resize;
$scope.$applyAsync(() => {
resize();
});
var initialValue = angular.isDefined(vm.ctx.settings.initialValue) ? vm.ctx.settings.initialValue : false;
setValue(initialValue, true);
var subscription = vm.ctx.defaultSubscription;
var rpcEnabled = subscription.rpcEnabled;
vm.isSimulated = $scope.widgetEditMode;
vm.requestTimeout = 500;
if (vm.ctx.settings.requestTimeout) {
vm.requestTimeout = vm.ctx.settings.requestTimeout;
}
vm.valuePollingInterval = 500;
if (vm.ctx.settings.valuePollingInterval) {
vm.valuePollingInterval = vm.ctx.settings.valuePollingInterval;
}
vm.getValueMethod = 'getValue';
if (vm.ctx.settings.getValueMethod && vm.ctx.settings.getValueMethod.length) {
vm.getValueMethod = vm.ctx.settings.getValueMethod;
}
if (!rpcEnabled) {
onError('Target device is not set!');
} else {
if (!vm.isSimulated) {
rpcRequestValue();
}
}
}
function resize() {
var width = ledContainer.width();
var height = ledContainer.height();
var size = Math.min(width, height);
led.css({width: size, height: size});
if (vm.showTitle) {
setFontSize(ledTitle, vm.title, ledTitleContainer.height() * 2 / 3, ledTitleContainer.width());
}
setFontSize(ledError, vm.error, ledErrorContainer.height(), ledErrorContainer.width());
}
function setValue(value, forceUpdate) {
if (vm.value != value || forceUpdate) {
vm.value = value;
updateColor();
}
}
function updateColor() {
var color = vm.value ? vm.ledColor : vm.disabledColor;
var middleColor = vm.value ? vm.ledMiddleColor : vm.disabledMiddleColor;
var boxShadow = `#000 0 -1px 6px 1px, inset ${middleColor} 0 -1px 8px, ${color} 0 3px 11px`;
led.css({'backgroundColor': color});
led.css({'boxShadow': boxShadow});
if (vm.value) {
led.removeClass( 'disabled' );
} else {
led.addClass( 'disabled' );
}
}
function onError(error) {
$scope.$applyAsync(() => {
vm.error = error;
setFontSize(ledError, vm.error, ledErrorContainer.height(), ledErrorContainer.width());
});
}
function setFontSize(element, text, fontSize, maxWidth) {
var textWidth = measureTextWidth(text, fontSize);
while (textWidth > maxWidth) {
fontSize--;
textWidth = measureTextWidth(text, fontSize);
}
element.css({'fontSize': fontSize+'px', 'lineHeight': fontSize+'px'});
}
function measureTextWidth(text, fontSize) {
textMeasure.css({'fontSize': fontSize+'px', 'lineHeight': fontSize+'px'});
textMeasure.text(text);
return textMeasure.width();
}
function rpcRequestValue() {
if (vm.destroyed) {
return;
}
vm.error = '';
vm.ctx.controlApi.sendTwoWayCommand(vm.getValueMethod, null, vm.requestTimeout).then(
(responseBody) => {
var newValue = responseBody ? true : false;
setValue(newValue);
if (vm.requestValueTimeoutHandle) {
$timeout.cancel(vm.requestValueTimeoutHandle);
}
vm.requestValueTimeoutHandle = $timeout(rpcRequestValue, vm.valuePollingInterval);
},
() => {
var errorText = vm.ctx.defaultSubscription.rpcErrorText;
onError(errorText);
if (vm.requestValueTimeoutHandle) {
$timeout.cancel(vm.requestValueTimeoutHandle);
}
vm.requestValueTimeoutHandle = $timeout(rpcRequestValue, vm.valuePollingInterval);
}
);
}
}