Commit c1e77ccad33e39408e1b228dc6efd76c3a473ff6
1 parent
28853c7d
UI: Improved configuration of RPC control widgets
Showing
5 changed files
with
258 additions
and
19 deletions
@@ -64,7 +64,7 @@ | @@ -64,7 +64,7 @@ | ||
64 | "templateHtml": "<tb-switch ctx='ctx'></tb-switch>", | 64 | "templateHtml": "<tb-switch ctx='ctx'></tb-switch>", |
65 | "templateCss": "", | 65 | "templateCss": "", |
66 | "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", | 66 | "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", |
67 | - "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\": \"Switch title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"showOnOffLabels\": {\n \"title\": \"Show on/off labels\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"getValueMethod\": {\n \"title\": \"Get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"setValueMethod\": {\n \"title\": \"Set value method\",\n \"type\": \"string\",\n \"default\": \"setValue\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"getValueMethod\", \"setValueMethod\", \"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n \"showOnOffLabels\",\n \"getValueMethod\",\n \"setValueMethod\",\n \"requestTimeout\"\n ]\n}", | 67 | + "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\": \"Switch title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"showOnOffLabels\": {\n \"title\": \"Show on/off labels\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"retrieveValueMethod\": {\n \"title\": \"Retrieve on/off value using method\",\n \"type\": \"string\",\n \"default\": \"rpc\"\n },\n \"valueKey\": {\n \"title\": \"Attribute/Timeseries value key (only when subscribe for attribute/timeseries method)\",\n \"type\": \"string\",\n \"default\": \"value\"\n },\n \"getValueMethod\": {\n \"title\": \"RPC get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"setValueMethod\": {\n \"title\": \"RPC set value method\",\n \"type\": \"string\",\n \"default\": \"setValue\"\n },\n \"parseValueFunction\": {\n \"title\": \"Parse value function, f(data), returns boolean\",\n \"type\": \"string\",\n \"default\": \"return data ? true : false;\"\n },\n \"convertValueFunction\": {\n \"title\": \"Convert value function, f(value), returns payload used by RPC set value method\",\n \"type\": \"string\",\n \"default\": \"return value;\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n \"showOnOffLabels\",\n {\n \"key\": \"retrieveValueMethod\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"none\",\n \"label\": \"Don't retrieve\"\n },\n {\n \"value\": \"rpc\",\n \"label\": \"Call RPC get value method\"\n },\n {\n \"value\": \"attribute\",\n \"label\": \"Subscribe for attribute\"\n },\n {\n \"value\": \"timeseries\",\n \"label\": \"Subscribe for timeseries\"\n }\n ]\n },\n \"valueKey\",\n \"getValueMethod\",\n \"setValueMethod\",\n {\n \"key\": \"parseValueFunction\",\n \"type\": \"javascript\"\n },\n {\n \"key\": \"convertValueFunction\",\n \"type\": \"javascript\"\n },\n \"requestTimeout\"\n ]\n}", |
68 | "dataKeySettingsSchema": "{}\n", | 68 | "dataKeySettingsSchema": "{}\n", |
69 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":false,\"getValueMethod\":\"getValue\",\"setValueMethod\":\"setValue\",\"showOnOffLabels\":true,\"title\":\"Switch control\"},\"title\":\"Switch Control\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}" | 69 | "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":false,\"getValueMethod\":\"getValue\",\"setValueMethod\":\"setValue\",\"showOnOffLabels\":true,\"title\":\"Switch control\"},\"title\":\"Switch Control\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}" |
70 | } | 70 | } |
@@ -80,9 +80,9 @@ | @@ -80,9 +80,9 @@ | ||
80 | "templateHtml": "<tb-round-switch ctx='ctx'></tb-round-switch>", | 80 | "templateHtml": "<tb-round-switch ctx='ctx'></tb-round-switch>", |
81 | "templateCss": "", | 81 | "templateCss": "", |
82 | "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", | 82 | "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", |
83 | - "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\": \"Switch title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"getValueMethod\": {\n \"title\": \"Get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"setValueMethod\": {\n \"title\": \"Set value method\",\n \"type\": \"string\",\n \"default\": \"setValue\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"getValueMethod\", \"setValueMethod\", \"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n \"getValueMethod\",\n \"setValueMethod\",\n \"requestTimeout\"\n ]\n}", | 83 | + "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\": \"Switch title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"retrieveValueMethod\": {\n \"title\": \"Retrieve on/off value using method\",\n \"type\": \"string\",\n \"default\": \"rpc\"\n },\n \"valueKey\": {\n \"title\": \"Attribute/Timeseries value key (only when subscribe for attribute/timeseries method)\",\n \"type\": \"string\",\n \"default\": \"value\"\n },\n \"getValueMethod\": {\n \"title\": \"RPC get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"setValueMethod\": {\n \"title\": \"RPC set value method\",\n \"type\": \"string\",\n \"default\": \"setValue\"\n },\n \"parseValueFunction\": {\n \"title\": \"Parse value function, f(data), returns boolean\",\n \"type\": \"string\",\n \"default\": \"return data ? true : false;\"\n },\n \"convertValueFunction\": {\n \"title\": \"Convert value function, f(value), returns payload used by RPC set value method\",\n \"type\": \"string\",\n \"default\": \"return value;\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n {\n \"key\": \"retrieveValueMethod\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"none\",\n \"label\": \"Don't retrieve\"\n },\n {\n \"value\": \"rpc\",\n \"label\": \"Call RPC get value method\"\n },\n {\n \"value\": \"attribute\",\n \"label\": \"Subscribe for attribute\"\n },\n {\n \"value\": \"timeseries\",\n \"label\": \"Subscribe for timeseries\"\n }\n ]\n },\n \"valueKey\",\n \"getValueMethod\",\n \"setValueMethod\",\n {\n \"key\": \"parseValueFunction\",\n \"type\": \"javascript\"\n },\n {\n \"key\": \"convertValueFunction\",\n \"type\": \"javascript\"\n },\n \"requestTimeout\"\n ]\n}", |
84 | "dataKeySettingsSchema": "{}\n", | 84 | "dataKeySettingsSchema": "{}\n", |
85 | - "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":false,\"getValueMethod\":\"getValue\",\"setValueMethod\":\"setValue\",\"showOnOffLabels\":true,\"title\":\"Round switch\"},\"title\":\"Round switch\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}" | 85 | + "defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":false,\"getValueMethod\":\"getValue\",\"setValueMethod\":\"setValue\",\"title\":\"Round switch\",\"retrieveValueMethod\":\"rpc\",\"valueKey\":\"value\",\"parseValueFunction\":\"return data ? true : false;\",\"convertValueFunction\":\"return value;\"},\"title\":\"Round switch\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}" |
86 | } | 86 | } |
87 | }, | 87 | }, |
88 | { | 88 | { |
@@ -96,9 +96,9 @@ | @@ -96,9 +96,9 @@ | ||
96 | "templateHtml": "<tb-led-indicator ctx='ctx'></tb-led-indicator>", | 96 | "templateHtml": "<tb-led-indicator ctx='ctx'></tb-led-indicator>", |
97 | "templateCss": "", | 97 | "templateCss": "", |
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", | 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 \"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}", | 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\": \"RPC check device status method\",\n \"type\": \"string\",\n \"default\": \"checkStatus\"\n },\n \"retrieveValueMethod\": {\n \"title\": \"Retrieve led status value using method\",\n \"type\": \"string\",\n \"default\": \"attribute\"\n },\n \"valueAttribute\": {\n \"title\": \"Device attribute/timeseries containing led status value\",\n \"type\": \"string\",\n \"default\": \"value\"\n },\n \"parseValueFunction\": {\n \"title\": \"Parse led status value function, f(data), returns boolean\",\n \"type\": \"string\",\n \"default\": \"return data ? true : false;\"\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 {\n \"key\": \"retrieveValueMethod\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"attribute\",\n \"label\": \"Subscribe for attribute\"\n },\n {\n \"value\": \"timeseries\",\n \"label\": \"Subscribe for timeseries\"\n }\n ]\n },\n \"valueAttribute\",\n {\n \"key\": \"parseValueFunction\",\n \"type\": \"javascript\"\n },\n \"requestTimeout\"\n ]\n}", |
100 | "dataKeySettingsSchema": "{}\n", | 100 | "dataKeySettingsSchema": "{}\n", |
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}" | 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\",\"retrieveValueMethod\":\"attribute\",\"parseValueFunction\":\"return data ? true : false;\"},\"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 | ] |
@@ -70,7 +70,7 @@ public class ThingsboardInstallService { | @@ -70,7 +70,7 @@ public class ThingsboardInstallService { | ||
70 | 70 | ||
71 | switch (upgradeFromVersion) { | 71 | switch (upgradeFromVersion) { |
72 | case "1.2.3": | 72 | case "1.2.3": |
73 | - log.info("Upgrading ThingsBoard from version {} to 1.3.0 ...", upgradeFromVersion); | 73 | + log.info("Upgrading ThingsBoard from version 1.2.3 to 1.3.0 ..."); |
74 | 74 | ||
75 | databaseUpgradeService.upgradeDatabase(upgradeFromVersion); | 75 | databaseUpgradeService.upgradeDatabase(upgradeFromVersion); |
76 | 76 | ||
@@ -84,6 +84,21 @@ public class ThingsboardInstallService { | @@ -84,6 +84,21 @@ public class ThingsboardInstallService { | ||
84 | systemDataLoaderService.deleteSystemWidgetBundle("gpio_widgets"); | 84 | systemDataLoaderService.deleteSystemWidgetBundle("gpio_widgets"); |
85 | systemDataLoaderService.deleteSystemWidgetBundle("alarm_widgets"); | 85 | systemDataLoaderService.deleteSystemWidgetBundle("alarm_widgets"); |
86 | 86 | ||
87 | + case "1.3.0": | ||
88 | + log.info("Upgrading ThingsBoard from version 1.3.0 to 1.3.1 ..."); | ||
89 | + | ||
90 | + log.info("Updating system data..."); | ||
91 | + | ||
92 | + systemDataLoaderService.deleteSystemWidgetBundle("charts"); | ||
93 | + systemDataLoaderService.deleteSystemWidgetBundle("cards"); | ||
94 | + systemDataLoaderService.deleteSystemWidgetBundle("maps"); | ||
95 | + systemDataLoaderService.deleteSystemWidgetBundle("analogue_gauges"); | ||
96 | + systemDataLoaderService.deleteSystemWidgetBundle("digital_gauges"); | ||
97 | + systemDataLoaderService.deleteSystemWidgetBundle("gpio_widgets"); | ||
98 | + systemDataLoaderService.deleteSystemWidgetBundle("alarm_widgets"); | ||
99 | + systemDataLoaderService.deleteSystemWidgetBundle("control_widgets"); | ||
100 | + systemDataLoaderService.deleteSystemWidgetBundle("maps_v2"); | ||
101 | + | ||
87 | systemDataLoaderService.loadSystemWidgets(); | 102 | systemDataLoaderService.loadSystemWidgets(); |
88 | 103 | ||
89 | break; | 104 | break; |
@@ -116,6 +116,20 @@ function LedIndicatorController($element, $scope, $timeout, utils, types) { | @@ -116,6 +116,20 @@ function LedIndicatorController($element, $scope, $timeout, utils, types) { | ||
116 | if (vm.ctx.settings.requestTimeout) { | 116 | if (vm.ctx.settings.requestTimeout) { |
117 | vm.requestTimeout = vm.ctx.settings.requestTimeout; | 117 | vm.requestTimeout = vm.ctx.settings.requestTimeout; |
118 | } | 118 | } |
119 | + vm.retrieveValueMethod = 'attribute'; | ||
120 | + if (vm.ctx.settings.retrieveValueMethod && vm.ctx.settings.retrieveValueMethod.length) { | ||
121 | + vm.retrieveValueMethod = vm.ctx.settings.retrieveValueMethod; | ||
122 | + } | ||
123 | + | ||
124 | + vm.parseValueFunction = (data) => data ? true : false; | ||
125 | + if (vm.ctx.settings.parseValueFunction && vm.ctx.settings.parseValueFunction.length) { | ||
126 | + try { | ||
127 | + vm.parseValueFunction = new Function('data', vm.ctx.settings.parseValueFunction); | ||
128 | + } catch (e) { | ||
129 | + vm.parseValueFunction = (data) => data ? true : false; | ||
130 | + } | ||
131 | + } | ||
132 | + | ||
119 | vm.checkStatusMethod = 'checkStatus'; | 133 | vm.checkStatusMethod = 'checkStatus'; |
120 | if (vm.ctx.settings.checkStatusMethod && vm.ctx.settings.checkStatusMethod.length) { | 134 | if (vm.ctx.settings.checkStatusMethod && vm.ctx.settings.checkStatusMethod.length) { |
121 | vm.checkStatusMethod = vm.ctx.settings.checkStatusMethod; | 135 | vm.checkStatusMethod = vm.ctx.settings.checkStatusMethod; |
@@ -222,11 +236,19 @@ function LedIndicatorController($element, $scope, $timeout, utils, types) { | @@ -222,11 +236,19 @@ function LedIndicatorController($element, $scope, $timeout, utils, types) { | ||
222 | var subscriptionsInfo = [{ | 236 | var subscriptionsInfo = [{ |
223 | type: types.datasourceType.entity, | 237 | type: types.datasourceType.entity, |
224 | entityType: types.entityType.device, | 238 | entityType: types.entityType.device, |
225 | - entityId: vm.ctx.defaultSubscription.targetDeviceId, | ||
226 | - attributes: [ | ||
227 | - {name: vm.valueAttribute} | ||
228 | - ] | 239 | + entityId: vm.ctx.defaultSubscription.targetDeviceId |
229 | }]; | 240 | }]; |
241 | + | ||
242 | + if (vm.retrieveValueMethod == 'attribute') { | ||
243 | + subscriptionsInfo[0].attributes = [ | ||
244 | + {name: vm.valueAttribute} | ||
245 | + ]; | ||
246 | + } else { | ||
247 | + subscriptionsInfo[0].timeseries = [ | ||
248 | + {name: vm.valueAttribute} | ||
249 | + ]; | ||
250 | + } | ||
251 | + | ||
230 | vm.ctx.subscriptionApi.createSubscriptionFromInfo ( | 252 | vm.ctx.subscriptionApi.createSubscriptionFromInfo ( |
231 | types.widgetType.latest.value, subscriptionsInfo, vm.subscriptionOptions, false, true).then( | 253 | types.widgetType.latest.value, subscriptionsInfo, vm.subscriptionOptions, false, true).then( |
232 | function(subscription) { | 254 | function(subscription) { |
@@ -245,7 +267,7 @@ function LedIndicatorController($element, $scope, $timeout, utils, types) { | @@ -245,7 +267,7 @@ function LedIndicatorController($element, $scope, $timeout, utils, types) { | ||
245 | if (attrValue) { | 267 | if (attrValue) { |
246 | var parsed = null; | 268 | var parsed = null; |
247 | try { | 269 | try { |
248 | - parsed = angular.fromJson(attrValue); | 270 | + parsed = vm.parseValueFunction(angular.fromJson(attrValue)); |
249 | } catch (e){/**/} | 271 | } catch (e){/**/} |
250 | value = parsed ? true : false; | 272 | value = parsed ? true : false; |
251 | } | 273 | } |
@@ -41,7 +41,7 @@ function RoundSwitch() { | @@ -41,7 +41,7 @@ function RoundSwitch() { | ||
41 | } | 41 | } |
42 | 42 | ||
43 | /*@ngInject*/ | 43 | /*@ngInject*/ |
44 | -function RoundSwitchController($element, $scope, utils) { | 44 | +function RoundSwitchController($element, $scope, utils, types) { |
45 | let vm = this; | 45 | let vm = this; |
46 | 46 | ||
47 | vm.showTitle = false; | 47 | vm.showTitle = false; |
@@ -64,12 +64,20 @@ function RoundSwitchController($element, $scope, utils) { | @@ -64,12 +64,20 @@ function RoundSwitchController($element, $scope, utils) { | ||
64 | onValue(); | 64 | onValue(); |
65 | }); | 65 | }); |
66 | 66 | ||
67 | + vm.valueSubscription = null; | ||
68 | + | ||
67 | $scope.$watch('vm.ctx', () => { | 69 | $scope.$watch('vm.ctx', () => { |
68 | if (vm.ctx) { | 70 | if (vm.ctx) { |
69 | init(); | 71 | init(); |
70 | } | 72 | } |
71 | }); | 73 | }); |
72 | 74 | ||
75 | + $scope.$on('$destroy', () => { | ||
76 | + if (vm.valueSubscription) { | ||
77 | + vm.ctx.subscriptionApi.removeSubscription(vm.valueSubscription.id); | ||
78 | + } | ||
79 | + }); | ||
80 | + | ||
73 | resize(); | 81 | resize(); |
74 | 82 | ||
75 | function init() { | 83 | function init() { |
@@ -92,6 +100,35 @@ function RoundSwitchController($element, $scope, utils) { | @@ -92,6 +100,35 @@ function RoundSwitchController($element, $scope, utils) { | ||
92 | if (vm.ctx.settings.requestTimeout) { | 100 | if (vm.ctx.settings.requestTimeout) { |
93 | vm.requestTimeout = vm.ctx.settings.requestTimeout; | 101 | vm.requestTimeout = vm.ctx.settings.requestTimeout; |
94 | } | 102 | } |
103 | + | ||
104 | + vm.retrieveValueMethod = 'rpc'; | ||
105 | + if (vm.ctx.settings.retrieveValueMethod && vm.ctx.settings.retrieveValueMethod.length) { | ||
106 | + vm.retrieveValueMethod = vm.ctx.settings.retrieveValueMethod; | ||
107 | + } | ||
108 | + | ||
109 | + vm.valueKey = 'value'; | ||
110 | + if (vm.ctx.settings.valueKey && vm.ctx.settings.valueKey.length) { | ||
111 | + vm.valueKey = vm.ctx.settings.valueKey; | ||
112 | + } | ||
113 | + | ||
114 | + vm.parseValueFunction = (data) => data ? true : false; | ||
115 | + if (vm.ctx.settings.parseValueFunction && vm.ctx.settings.parseValueFunction.length) { | ||
116 | + try { | ||
117 | + vm.parseValueFunction = new Function('data', vm.ctx.settings.parseValueFunction); | ||
118 | + } catch (e) { | ||
119 | + vm.parseValueFunction = (data) => data ? true : false; | ||
120 | + } | ||
121 | + } | ||
122 | + | ||
123 | + vm.convertValueFunction = (value) => value; | ||
124 | + if (vm.ctx.settings.convertValueFunction && vm.ctx.settings.convertValueFunction.length) { | ||
125 | + try { | ||
126 | + vm.convertValueFunction = new Function('value', vm.ctx.settings.convertValueFunction); | ||
127 | + } catch (e) { | ||
128 | + vm.convertValueFunction = (value) => value; | ||
129 | + } | ||
130 | + } | ||
131 | + | ||
95 | vm.getValueMethod = 'getValue'; | 132 | vm.getValueMethod = 'getValue'; |
96 | if (vm.ctx.settings.getValueMethod && vm.ctx.settings.getValueMethod.length) { | 133 | if (vm.ctx.settings.getValueMethod && vm.ctx.settings.getValueMethod.length) { |
97 | vm.getValueMethod = vm.ctx.settings.getValueMethod; | 134 | vm.getValueMethod = vm.ctx.settings.getValueMethod; |
@@ -104,7 +141,11 @@ function RoundSwitchController($element, $scope, utils) { | @@ -104,7 +141,11 @@ function RoundSwitchController($element, $scope, utils) { | ||
104 | onError('Target device is not set!'); | 141 | onError('Target device is not set!'); |
105 | } else { | 142 | } else { |
106 | if (!vm.isSimulated) { | 143 | if (!vm.isSimulated) { |
107 | - rpcRequestValue(); | 144 | + if (vm.retrieveValueMethod == 'rpc') { |
145 | + rpcRequestValue(); | ||
146 | + } else if (vm.retrieveValueMethod == 'attribute' || vm.retrieveValueMethod == 'timeseries') { | ||
147 | + subscribeForValue(); | ||
148 | + } | ||
108 | } | 149 | } |
109 | } | 150 | } |
110 | } | 151 | } |
@@ -127,6 +168,66 @@ function RoundSwitchController($element, $scope, utils) { | @@ -127,6 +168,66 @@ function RoundSwitchController($element, $scope, utils) { | ||
127 | setFontSize(switchError, vm.error, switchErrorContainer.height(), switchErrorContainer.width()); | 168 | setFontSize(switchError, vm.error, switchErrorContainer.height(), switchErrorContainer.width()); |
128 | } | 169 | } |
129 | 170 | ||
171 | + function subscribeForValue() { | ||
172 | + var valueSubscriptionInfo = [{ | ||
173 | + type: types.datasourceType.entity, | ||
174 | + entityType: types.entityType.device, | ||
175 | + entityId: vm.ctx.defaultSubscription.targetDeviceId | ||
176 | + }]; | ||
177 | + if (vm.retrieveValueMethod == 'attribute') { | ||
178 | + valueSubscriptionInfo[0].attributes = [ | ||
179 | + {name: vm.valueKey} | ||
180 | + ]; | ||
181 | + } else { | ||
182 | + valueSubscriptionInfo[0].timeseries = [ | ||
183 | + {name: vm.valueKey} | ||
184 | + ]; | ||
185 | + } | ||
186 | + var subscriptionOptions = { | ||
187 | + callbacks: { | ||
188 | + onDataUpdated: onDataUpdated, | ||
189 | + onDataUpdateError: onDataUpdateError | ||
190 | + } | ||
191 | + }; | ||
192 | + vm.ctx.subscriptionApi.createSubscriptionFromInfo ( | ||
193 | + types.widgetType.latest.value, valueSubscriptionInfo, subscriptionOptions, false, true).then( | ||
194 | + (subscription) => { | ||
195 | + vm.valueSubscription = subscription; | ||
196 | + } | ||
197 | + ); | ||
198 | + } | ||
199 | + | ||
200 | + function onDataUpdated(subscription, apply) { | ||
201 | + var value = false; | ||
202 | + var data = subscription.data; | ||
203 | + if (data.length) { | ||
204 | + var keyData = data[0]; | ||
205 | + if (keyData && keyData.data && keyData.data[0]) { | ||
206 | + var attrValue = keyData.data[0][1]; | ||
207 | + if (attrValue) { | ||
208 | + var parsed = null; | ||
209 | + try { | ||
210 | + parsed = vm.parseValueFunction(angular.fromJson(attrValue)); | ||
211 | + } catch (e){/**/} | ||
212 | + value = parsed ? true : false; | ||
213 | + } | ||
214 | + } | ||
215 | + } | ||
216 | + setValue(value); | ||
217 | + if (apply) { | ||
218 | + $scope.$digest(); | ||
219 | + } | ||
220 | + } | ||
221 | + | ||
222 | + function onDataUpdateError(subscription, e) { | ||
223 | + var exceptionData = utils.parseException(e); | ||
224 | + var errorText = exceptionData.name; | ||
225 | + if (exceptionData.message) { | ||
226 | + errorText += ': ' + exceptionData.message; | ||
227 | + } | ||
228 | + onError(errorText); | ||
229 | + } | ||
230 | + | ||
130 | function setValue(value) { | 231 | function setValue(value) { |
131 | vm.value = value ? true : false; | 232 | vm.value = value ? true : false; |
132 | onoff.prop('checked', !vm.value); | 233 | onoff.prop('checked', !vm.value); |
@@ -162,7 +263,7 @@ function RoundSwitchController($element, $scope, utils) { | @@ -162,7 +263,7 @@ function RoundSwitchController($element, $scope, utils) { | ||
162 | vm.error = ''; | 263 | vm.error = ''; |
163 | vm.ctx.controlApi.sendTwoWayCommand(vm.getValueMethod, null, vm.requestTimeout).then( | 264 | vm.ctx.controlApi.sendTwoWayCommand(vm.getValueMethod, null, vm.requestTimeout).then( |
164 | (responseBody) => { | 265 | (responseBody) => { |
165 | - setValue(responseBody); | 266 | + setValue(vm.parseValueFunction(responseBody)); |
166 | }, | 267 | }, |
167 | () => { | 268 | () => { |
168 | var errorText = vm.ctx.defaultSubscription.rpcErrorText; | 269 | var errorText = vm.ctx.defaultSubscription.rpcErrorText; |
@@ -181,7 +282,7 @@ function RoundSwitchController($element, $scope, utils) { | @@ -181,7 +282,7 @@ function RoundSwitchController($element, $scope, utils) { | ||
181 | vm.executingUpdateValue = true; | 282 | vm.executingUpdateValue = true; |
182 | } | 283 | } |
183 | vm.error = ''; | 284 | vm.error = ''; |
184 | - vm.ctx.controlApi.sendOneWayCommand(vm.setValueMethod, value, vm.requestTimeout).then( | 285 | + vm.ctx.controlApi.sendOneWayCommand(vm.setValueMethod, vm.convertValueFunction(value), vm.requestTimeout).then( |
185 | () => { | 286 | () => { |
186 | vm.executingUpdateValue = false; | 287 | vm.executingUpdateValue = false; |
187 | if (vm.scheduledValue != null && vm.scheduledValue != vm.rpcValue) { | 288 | if (vm.scheduledValue != null && vm.scheduledValue != vm.rpcValue) { |
@@ -41,7 +41,7 @@ function Switch() { | @@ -41,7 +41,7 @@ function Switch() { | ||
41 | } | 41 | } |
42 | 42 | ||
43 | /*@ngInject*/ | 43 | /*@ngInject*/ |
44 | -function SwitchController($element, $scope) { | 44 | +function SwitchController($element, $scope, types, utils) { |
45 | let vm = this; | 45 | let vm = this; |
46 | 46 | ||
47 | vm.showTitle = false; | 47 | vm.showTitle = false; |
@@ -63,12 +63,20 @@ function SwitchController($element, $scope) { | @@ -63,12 +63,20 @@ function SwitchController($element, $scope) { | ||
63 | 63 | ||
64 | vm.onValue = onValue; | 64 | vm.onValue = onValue; |
65 | 65 | ||
66 | + vm.valueSubscription = null; | ||
67 | + | ||
66 | $scope.$watch('vm.ctx', () => { | 68 | $scope.$watch('vm.ctx', () => { |
67 | if (vm.ctx) { | 69 | if (vm.ctx) { |
68 | init(); | 70 | init(); |
69 | } | 71 | } |
70 | }); | 72 | }); |
71 | 73 | ||
74 | + $scope.$on('$destroy', () => { | ||
75 | + if (vm.valueSubscription) { | ||
76 | + vm.ctx.subscriptionApi.removeSubscription(vm.valueSubscription.id); | ||
77 | + } | ||
78 | + }); | ||
79 | + | ||
72 | function init() { | 80 | function init() { |
73 | 81 | ||
74 | vm.title = angular.isDefined(vm.ctx.settings.title) ? vm.ctx.settings.title : ''; | 82 | vm.title = angular.isDefined(vm.ctx.settings.title) ? vm.ctx.settings.title : ''; |
@@ -90,6 +98,35 @@ function SwitchController($element, $scope) { | @@ -90,6 +98,35 @@ function SwitchController($element, $scope) { | ||
90 | if (vm.ctx.settings.requestTimeout) { | 98 | if (vm.ctx.settings.requestTimeout) { |
91 | vm.requestTimeout = vm.ctx.settings.requestTimeout; | 99 | vm.requestTimeout = vm.ctx.settings.requestTimeout; |
92 | } | 100 | } |
101 | + | ||
102 | + vm.retrieveValueMethod = 'rpc'; | ||
103 | + if (vm.ctx.settings.retrieveValueMethod && vm.ctx.settings.retrieveValueMethod.length) { | ||
104 | + vm.retrieveValueMethod = vm.ctx.settings.retrieveValueMethod; | ||
105 | + } | ||
106 | + | ||
107 | + vm.valueKey = 'value'; | ||
108 | + if (vm.ctx.settings.valueKey && vm.ctx.settings.valueKey.length) { | ||
109 | + vm.valueKey = vm.ctx.settings.valueKey; | ||
110 | + } | ||
111 | + | ||
112 | + vm.parseValueFunction = (data) => data ? true : false; | ||
113 | + if (vm.ctx.settings.parseValueFunction && vm.ctx.settings.parseValueFunction.length) { | ||
114 | + try { | ||
115 | + vm.parseValueFunction = new Function('data', vm.ctx.settings.parseValueFunction); | ||
116 | + } catch (e) { | ||
117 | + vm.parseValueFunction = (data) => data ? true : false; | ||
118 | + } | ||
119 | + } | ||
120 | + | ||
121 | + vm.convertValueFunction = (value) => value; | ||
122 | + if (vm.ctx.settings.convertValueFunction && vm.ctx.settings.convertValueFunction.length) { | ||
123 | + try { | ||
124 | + vm.convertValueFunction = new Function('value', vm.ctx.settings.convertValueFunction); | ||
125 | + } catch (e) { | ||
126 | + vm.convertValueFunction = (value) => value; | ||
127 | + } | ||
128 | + } | ||
129 | + | ||
93 | vm.getValueMethod = 'getValue'; | 130 | vm.getValueMethod = 'getValue'; |
94 | if (vm.ctx.settings.getValueMethod && vm.ctx.settings.getValueMethod.length) { | 131 | if (vm.ctx.settings.getValueMethod && vm.ctx.settings.getValueMethod.length) { |
95 | vm.getValueMethod = vm.ctx.settings.getValueMethod; | 132 | vm.getValueMethod = vm.ctx.settings.getValueMethod; |
@@ -102,7 +139,11 @@ function SwitchController($element, $scope) { | @@ -102,7 +139,11 @@ function SwitchController($element, $scope) { | ||
102 | onError('Target device is not set!'); | 139 | onError('Target device is not set!'); |
103 | } else { | 140 | } else { |
104 | if (!vm.isSimulated) { | 141 | if (!vm.isSimulated) { |
105 | - rpcRequestValue(); | 142 | + if (vm.retrieveValueMethod == 'rpc') { |
143 | + rpcRequestValue(); | ||
144 | + } else if (vm.retrieveValueMethod == 'attribute' || vm.retrieveValueMethod == 'timeseries') { | ||
145 | + subscribeForValue(); | ||
146 | + } | ||
106 | } | 147 | } |
107 | } | 148 | } |
108 | } | 149 | } |
@@ -144,6 +185,66 @@ function SwitchController($element, $scope) { | @@ -144,6 +185,66 @@ function SwitchController($element, $scope) { | ||
144 | setFontSize(switchError, vm.error, switchErrorContainer.height(), switchErrorContainer.width()); | 185 | setFontSize(switchError, vm.error, switchErrorContainer.height(), switchErrorContainer.width()); |
145 | } | 186 | } |
146 | 187 | ||
188 | + function subscribeForValue() { | ||
189 | + var valueSubscriptionInfo = [{ | ||
190 | + type: types.datasourceType.entity, | ||
191 | + entityType: types.entityType.device, | ||
192 | + entityId: vm.ctx.defaultSubscription.targetDeviceId | ||
193 | + }]; | ||
194 | + if (vm.retrieveValueMethod == 'attribute') { | ||
195 | + valueSubscriptionInfo[0].attributes = [ | ||
196 | + {name: vm.valueKey} | ||
197 | + ]; | ||
198 | + } else { | ||
199 | + valueSubscriptionInfo[0].timeseries = [ | ||
200 | + {name: vm.valueKey} | ||
201 | + ]; | ||
202 | + } | ||
203 | + var subscriptionOptions = { | ||
204 | + callbacks: { | ||
205 | + onDataUpdated: onDataUpdated, | ||
206 | + onDataUpdateError: onDataUpdateError | ||
207 | + } | ||
208 | + }; | ||
209 | + vm.ctx.subscriptionApi.createSubscriptionFromInfo ( | ||
210 | + types.widgetType.latest.value, valueSubscriptionInfo, subscriptionOptions, false, true).then( | ||
211 | + (subscription) => { | ||
212 | + vm.valueSubscription = subscription; | ||
213 | + } | ||
214 | + ); | ||
215 | + } | ||
216 | + | ||
217 | + function onDataUpdated(subscription, apply) { | ||
218 | + var value = false; | ||
219 | + var data = subscription.data; | ||
220 | + if (data.length) { | ||
221 | + var keyData = data[0]; | ||
222 | + if (keyData && keyData.data && keyData.data[0]) { | ||
223 | + var attrValue = keyData.data[0][1]; | ||
224 | + if (attrValue) { | ||
225 | + var parsed = null; | ||
226 | + try { | ||
227 | + parsed = vm.parseValueFunction(angular.fromJson(attrValue)); | ||
228 | + } catch (e){/**/} | ||
229 | + value = parsed ? true : false; | ||
230 | + } | ||
231 | + } | ||
232 | + } | ||
233 | + setValue(value); | ||
234 | + if (apply) { | ||
235 | + $scope.$digest(); | ||
236 | + } | ||
237 | + } | ||
238 | + | ||
239 | + function onDataUpdateError(subscription, e) { | ||
240 | + var exceptionData = utils.parseException(e); | ||
241 | + var errorText = exceptionData.name; | ||
242 | + if (exceptionData.message) { | ||
243 | + errorText += ': ' + exceptionData.message; | ||
244 | + } | ||
245 | + onError(errorText); | ||
246 | + } | ||
247 | + | ||
147 | function setValue(value) { | 248 | function setValue(value) { |
148 | vm.value = value ? true : false; | 249 | vm.value = value ? true : false; |
149 | } | 250 | } |
@@ -178,7 +279,7 @@ function SwitchController($element, $scope) { | @@ -178,7 +279,7 @@ function SwitchController($element, $scope) { | ||
178 | vm.error = ''; | 279 | vm.error = ''; |
179 | vm.ctx.controlApi.sendTwoWayCommand(vm.getValueMethod, null, vm.requestTimeout).then( | 280 | vm.ctx.controlApi.sendTwoWayCommand(vm.getValueMethod, null, vm.requestTimeout).then( |
180 | (responseBody) => { | 281 | (responseBody) => { |
181 | - setValue(responseBody); | 282 | + setValue(vm.parseValueFunction(responseBody)); |
182 | }, | 283 | }, |
183 | () => { | 284 | () => { |
184 | var errorText = vm.ctx.defaultSubscription.rpcErrorText; | 285 | var errorText = vm.ctx.defaultSubscription.rpcErrorText; |
@@ -197,7 +298,7 @@ function SwitchController($element, $scope) { | @@ -197,7 +298,7 @@ function SwitchController($element, $scope) { | ||
197 | vm.executingUpdateValue = true; | 298 | vm.executingUpdateValue = true; |
198 | } | 299 | } |
199 | vm.error = ''; | 300 | vm.error = ''; |
200 | - vm.ctx.controlApi.sendOneWayCommand(vm.setValueMethod, value, vm.requestTimeout).then( | 301 | + vm.ctx.controlApi.sendOneWayCommand(vm.setValueMethod, vm.convertValueFunction(value), vm.requestTimeout).then( |
201 | () => { | 302 | () => { |
202 | vm.executingUpdateValue = false; | 303 | vm.executingUpdateValue = false; |
203 | if (vm.scheduledValue != null && vm.scheduledValue != vm.rpcValue) { | 304 | if (vm.scheduledValue != null && vm.scheduledValue != vm.rpcValue) { |