Commit 10020e6f9de32ad992778232c09faafef7fe6458

Authored by Igor Kulikov
1 parent 554e6a2d

TB-70: RPC widgets: improve led indicator widget behaviour.

... ... @@ -96,9 +96,9 @@
96 96 "templateHtml": "<tb-led-indicator ctx='ctx'></tb-led-indicator>",
97 97 "templateCss": "",
98 98 "controllerScript": "self.onInit = function() {\n var scope = self.ctx.$scope;\n scope.ctx = self.ctx;\n}\n\nself.onResize = function() {\n if (self.ctx.resize) {\n self.ctx.resize();\n }\n}\n\nself.onDestroy = function() {\n}\n",
99   - "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"title\": {\n \"title\": \"LED title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"ledColor\": {\n \"title\": \"LED Color\",\n \"type\": \"string\",\n \"default\": \"green\"\n },\n \"getValueMethod\": {\n \"title\": \"Get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"valuePollingInterval\": {\n \"title\": \"Value polling interval (ms)\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout (ms)\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"getValueMethod\", \"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n {\n \"key\": \"ledColor\",\n \"type\": \"color\"\n },\n \"getValueMethod\",\n \"valuePollingInterval\",\n \"requestTimeout\"\n ]\n}",
  99 + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"title\": {\n \"title\": \"LED title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"ledColor\": {\n \"title\": \"LED Color\",\n \"type\": \"string\",\n \"default\": \"green\"\n },\n \"scheckStatusMethod\": {\n \"title\": \"Check device status method\",\n \"type\": \"string\",\n \"default\": \"checkStatus\"\n },\n \"valueAttribute\": {\n \"title\": \"Device attribute containing led status value\",\n \"type\": \"string\",\n \"default\": \"value\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout (ms)\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"scheckStatusMethod\", \"valueAttribute\", \"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n {\n \"key\": \"ledColor\",\n \"type\": \"color\"\n },\n \"scheckStatusMethod\",\n \"valueAttribute\",\n \"requestTimeout\"\n ]\n}",
100 100 "dataKeySettingsSchema": "{}\n",
101   - "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":true,\"getValueMethod\":\"getValue\",\"title\":\"Led indicator\",\"ledColor\":\"#4caf50\",\"valuePollingInterval\":500},\"title\":\"Led indicator\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}"
  101 + "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":true,\"title\":\"Led indicator\",\"ledColor\":\"#4caf50\",\"scheckStatusMethod\":\"checkStatus\",\"valueAttribute\":\"value\"},\"title\":\"Led indicator\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}"
102 102 }
103 103 }
104 104 ]
... ...
... ... @@ -43,13 +43,23 @@ function LedIndicator() {
43 43 }
44 44
45 45 /*@ngInject*/
46   -function LedIndicatorController($element, $scope, $timeout) {
  46 +function LedIndicatorController($element, $scope, $timeout, utils, types) {
47 47 let vm = this;
48 48
49 49 vm.showTitle = false;
50 50 vm.value = false;
51 51 vm.error = '';
52 52
  53 + const checkStatusPollingInterval = 10000;
  54 +
  55 + vm.subscriptionOptions = {
  56 + callbacks: {
  57 + onDataUpdated: onDataUpdated,
  58 + onDataUpdateError: onDataUpdateError,
  59 + dataLoading: () => {}
  60 + }
  61 + };
  62 +
53 63 var led = angular.element('.led', $element),
54 64 ledContainer = angular.element('#led-container', $element),
55 65 textMeasure = angular.element('#text-measure', $element),
... ... @@ -66,8 +76,11 @@ function LedIndicatorController($element, $scope, $timeout) {
66 76
67 77 $scope.$on('$destroy', () => {
68 78 vm.destroyed = true;
69   - if (vm.requestValueTimeoutHandle) {
70   - $timeout.cancel(vm.requestValueTimeoutHandle);
  79 + if (vm.checkStatusTimeoutHandle) {
  80 + $timeout.cancel(vm.checkStatusTimeoutHandle);
  81 + }
  82 + if (vm.subscription) {
  83 + vm.ctx.subscriptionApi.removeSubscription(vm.subscription.id);
71 84 }
72 85 });
73 86
... ... @@ -80,6 +93,8 @@ function LedIndicatorController($element, $scope, $timeout) {
80 93
81 94 var origColor = angular.isDefined(vm.ctx.settings.ledColor) ? vm.ctx.settings.ledColor : 'green';
82 95
  96 + vm.valueAttribute = angular.isDefined(vm.ctx.settings.valueAttribute) ? vm.ctx.settings.valueAttribute : 'value';
  97 +
83 98 vm.ledColor = tinycolor(origColor).brighten(30).toHexString();
84 99 vm.ledMiddleColor = tinycolor(origColor).toHexString();
85 100 vm.disabledColor = tinycolor(origColor).darken(40).toHexString();
... ... @@ -101,19 +116,15 @@ function LedIndicatorController($element, $scope, $timeout) {
101 116 if (vm.ctx.settings.requestTimeout) {
102 117 vm.requestTimeout = vm.ctx.settings.requestTimeout;
103 118 }
104   - vm.valuePollingInterval = 500;
105   - if (vm.ctx.settings.valuePollingInterval) {
106   - vm.valuePollingInterval = vm.ctx.settings.valuePollingInterval;
107   - }
108   - vm.getValueMethod = 'getValue';
109   - if (vm.ctx.settings.getValueMethod && vm.ctx.settings.getValueMethod.length) {
110   - vm.getValueMethod = vm.ctx.settings.getValueMethod;
  119 + vm.checkStatusMethod = 'checkStatus';
  120 + if (vm.ctx.settings.checkStatusMethod && vm.ctx.settings.checkStatusMethod.length) {
  121 + vm.checkStatusMethod = vm.ctx.settings.checkStatusMethod;
111 122 }
112 123 if (!rpcEnabled) {
113 124 onError('Target device is not set!');
114 125 } else {
115 126 if (!vm.isSimulated) {
116   - rpcRequestValue();
  127 + rpcCheckStatus();
117 128 }
118 129 }
119 130 }
... ... @@ -173,29 +184,86 @@ function LedIndicatorController($element, $scope, $timeout) {
173 184 return textMeasure.width();
174 185 }
175 186
176   - function rpcRequestValue() {
  187 + function rpcCheckStatus() {
177 188 if (vm.destroyed) {
178 189 return;
179 190 }
180 191 vm.error = '';
181   - vm.ctx.controlApi.sendTwoWayCommand(vm.getValueMethod, null, vm.requestTimeout).then(
  192 + vm.ctx.controlApi.sendTwoWayCommand(vm.checkStatusMethod, null, vm.requestTimeout).then(
182 193 (responseBody) => {
183   - var newValue = responseBody ? true : false;
184   - setValue(newValue);
185   - if (vm.requestValueTimeoutHandle) {
186   - $timeout.cancel(vm.requestValueTimeoutHandle);
  194 + var status = responseBody ? true : false;
  195 + if (status) {
  196 + if (vm.checkStatusTimeoutHandle) {
  197 + $timeout.cancel(vm.checkStatusTimeoutHandle);
  198 + vm.checkStatusTimeoutHandle = null;
  199 + }
  200 + subscribeForValue();
  201 + } else {
  202 + var errorText = 'Unknown device status!';
  203 + onError(errorText);
  204 + if (vm.checkStatusTimeoutHandle) {
  205 + $timeout.cancel(vm.checkStatusTimeoutHandle);
  206 + }
  207 + vm.checkStatusTimeoutHandle = $timeout(rpcCheckStatus, checkStatusPollingInterval);
187 208 }
188   - vm.requestValueTimeoutHandle = $timeout(rpcRequestValue, vm.valuePollingInterval);
189 209 },
190 210 () => {
191 211 var errorText = vm.ctx.defaultSubscription.rpcErrorText;
192 212 onError(errorText);
193   - if (vm.requestValueTimeoutHandle) {
194   - $timeout.cancel(vm.requestValueTimeoutHandle);
  213 + if (vm.checkStatusTimeoutHandle) {
  214 + $timeout.cancel(vm.checkStatusTimeoutHandle);
195 215 }
196   - vm.requestValueTimeoutHandle = $timeout(rpcRequestValue, vm.valuePollingInterval);
  216 + vm.checkStatusTimeoutHandle = $timeout(rpcCheckStatus, checkStatusPollingInterval);
  217 + }
  218 + );
  219 + }
  220 +
  221 + function subscribeForValue() {
  222 + var subscriptionsInfo = [{
  223 + type: types.datasourceType.entity,
  224 + entityType: types.entityType.device,
  225 + entityId: vm.ctx.defaultSubscription.targetDeviceId,
  226 + attributes: [
  227 + {name: vm.valueAttribute}
  228 + ]
  229 + }];
  230 + vm.ctx.subscriptionApi.createSubscriptionFromInfo (
  231 + types.widgetType.latest.value, subscriptionsInfo, vm.subscriptionOptions, false, true).then(
  232 + function(subscription) {
  233 + vm.subscription = subscription;
197 234 }
198 235 );
199 236 }
200 237
  238 + function onDataUpdated(subscription, apply) {
  239 + var value = false;
  240 + var data = subscription.data;
  241 + if (data.length) {
  242 + var keyData = data[0];
  243 + if (keyData && keyData.data && keyData.data[0]) {
  244 + var attrValue = keyData.data[0][1];
  245 + if (attrValue) {
  246 + var parsed = null;
  247 + try {
  248 + parsed = angular.fromJson(attrValue);
  249 + } catch (e){/**/}
  250 + value = parsed ? true : false;
  251 + }
  252 + }
  253 + }
  254 + setValue(value);
  255 + if (apply) {
  256 + $scope.$digest();
  257 + }
  258 + }
  259 +
  260 + function onDataUpdateError(subscription, e) {
  261 + var exceptionData = utils.parseException(e);
  262 + var errorText = exceptionData.name;
  263 + if (exceptionData.message) {
  264 + errorText += ': ' + exceptionData.message;
  265 + }
  266 + onError(errorText);
  267 + }
  268 +
201 269 }
... ...