Commit ef21d2ae415e588bca993ed008a11e34683acc20
Merge remote-tracking branch 'upstream/master' into feature/stateful-services
Showing
18 changed files
with
4265 additions
and
133 deletions
Too many changes to show.
To preserve performance only 18 of 834 files are displayed.
@@ -133,6 +133,18 @@ | @@ -133,6 +133,18 @@ | ||
133 | <artifactId>spring-boot-starter-websocket</artifactId> | 133 | <artifactId>spring-boot-starter-websocket</artifactId> |
134 | </dependency> | 134 | </dependency> |
135 | <dependency> | 135 | <dependency> |
136 | + <groupId>org.springframework.cloud</groupId> | ||
137 | + <artifactId>spring-cloud-starter-oauth2</artifactId> | ||
138 | + </dependency> | ||
139 | + <dependency> | ||
140 | + <groupId>org.springframework.security</groupId> | ||
141 | + <artifactId>spring-security-oauth2-client</artifactId> | ||
142 | + </dependency> | ||
143 | + <dependency> | ||
144 | + <groupId>org.springframework.security</groupId> | ||
145 | + <artifactId>spring-security-oauth2-jose</artifactId> | ||
146 | + </dependency> | ||
147 | + <dependency> | ||
136 | <groupId>io.jsonwebtoken</groupId> | 148 | <groupId>io.jsonwebtoken</groupId> |
137 | <artifactId>jjwt</artifactId> | 149 | <artifactId>jjwt</artifactId> |
138 | </dependency> | 150 | </dependency> |
@@ -181,8 +193,8 @@ | @@ -181,8 +193,8 @@ | ||
181 | <artifactId>logback-classic</artifactId> | 193 | <artifactId>logback-classic</artifactId> |
182 | </dependency> | 194 | </dependency> |
183 | <dependency> | 195 | <dependency> |
184 | - <groupId>javax.mail</groupId> | ||
185 | - <artifactId>mail</artifactId> | 196 | + <groupId>com.sun.mail</groupId> |
197 | + <artifactId>javax.mail</artifactId> | ||
186 | </dependency> | 198 | </dependency> |
187 | <dependency> | 199 | <dependency> |
188 | <groupId>org.apache.curator</groupId> | 200 | <groupId>org.apache.curator</groupId> |
@@ -221,6 +233,11 @@ | @@ -221,6 +233,11 @@ | ||
221 | <scope>test</scope> | 233 | <scope>test</scope> |
222 | </dependency> | 234 | </dependency> |
223 | <dependency> | 235 | <dependency> |
236 | + <groupId>org.thingsboard</groupId> | ||
237 | + <artifactId>rest-client</artifactId> | ||
238 | + <scope>test</scope> | ||
239 | + </dependency> | ||
240 | + <dependency> | ||
224 | <groupId>org.springframework.boot</groupId> | 241 | <groupId>org.springframework.boot</groupId> |
225 | <artifactId>spring-boot-starter-test</artifactId> | 242 | <artifactId>spring-boot-starter-test</artifactId> |
226 | <scope>test</scope> | 243 | <scope>test</scope> |
@@ -547,7 +564,7 @@ | @@ -547,7 +564,7 @@ | ||
547 | </executions> | 564 | </executions> |
548 | </plugin> | 565 | </plugin> |
549 | <plugin> | 566 | <plugin> |
550 | - <groupId>org.fortasoft</groupId> | 567 | + <groupId>org.thingsboard</groupId> |
551 | <artifactId>gradle-maven-plugin</artifactId> | 568 | <artifactId>gradle-maven-plugin</artifactId> |
552 | <configuration> | 569 | <configuration> |
553 | <tasks> | 570 | <tasks> |
@@ -36,6 +36,7 @@ | @@ -36,6 +36,7 @@ | ||
36 | 36 | ||
37 | <logger name="org.thingsboard.server" level="INFO" /> | 37 | <logger name="org.thingsboard.server" level="INFO" /> |
38 | <logger name="akka" level="INFO" /> | 38 | <logger name="akka" level="INFO" /> |
39 | + <logger name="com.microsoft.azure.servicebus.primitives.CoreMessageReceiver" level="OFF" /> | ||
39 | 40 | ||
40 | <root level="INFO"> | 41 | <root level="INFO"> |
41 | <appender-ref ref="fileLogAppender"/> | 42 | <appender-ref ref="fileLogAppender"/> |
1 | +{ | ||
2 | + "title": "Gateways", | ||
3 | + "configuration": { | ||
4 | + "widgets": { | ||
5 | + "94715984-ae74-76e4-20b7-2f956b01ed80": { | ||
6 | + "isSystemType": true, | ||
7 | + "bundleAlias": "entity_admin_widgets", | ||
8 | + "typeAlias": "device_admin_table", | ||
9 | + "type": "latest", | ||
10 | + "title": "New widget", | ||
11 | + "sizeX": 24, | ||
12 | + "sizeY": 12, | ||
13 | + "config": { | ||
14 | + "timewindow": { | ||
15 | + "realtime": { | ||
16 | + "interval": 1000, | ||
17 | + "timewindowMs": 86400000 | ||
18 | + }, | ||
19 | + "aggregation": { | ||
20 | + "type": "NONE", | ||
21 | + "limit": 200 | ||
22 | + } | ||
23 | + }, | ||
24 | + "showTitle": true, | ||
25 | + "backgroundColor": "rgb(255, 255, 255)", | ||
26 | + "color": "rgba(0, 0, 0, 0.87)", | ||
27 | + "padding": "4px", | ||
28 | + "settings": { | ||
29 | + "enableSearch": true, | ||
30 | + "displayPagination": true, | ||
31 | + "defaultPageSize": 10, | ||
32 | + "defaultSortOrder": "entityName", | ||
33 | + "displayEntityName": true, | ||
34 | + "displayEntityType": false, | ||
35 | + "entitiesTitle": "List of gateways", | ||
36 | + "enableSelectColumnDisplay": true, | ||
37 | + "displayEntityLabel": false, | ||
38 | + "entityNameColumnTitle": "Gateway Name" | ||
39 | + }, | ||
40 | + "title": "Devices gateway table", | ||
41 | + "dropShadow": true, | ||
42 | + "enableFullscreen": true, | ||
43 | + "titleStyle": { | ||
44 | + "fontSize": "16px", | ||
45 | + "fontWeight": 400, | ||
46 | + "padding": "5px 10px 5px 10px" | ||
47 | + }, | ||
48 | + "useDashboardTimewindow": false, | ||
49 | + "showLegend": false, | ||
50 | + "datasources": [ | ||
51 | + { | ||
52 | + "type": "entity", | ||
53 | + "dataKeys": [ | ||
54 | + { | ||
55 | + "name": "active", | ||
56 | + "type": "attribute", | ||
57 | + "label": "Active", | ||
58 | + "color": "#2196f3", | ||
59 | + "settings": { | ||
60 | + "columnWidth": "0px", | ||
61 | + "useCellStyleFunction": true, | ||
62 | + "useCellContentFunction": true, | ||
63 | + "cellContentFunction": "value = '⬤';\nreturn value;", | ||
64 | + "cellStyleFunction": "var color;\nif (value == 'false') {\n color = '#EB5757';\n} else {\n color = '#27AE60';\n}\nreturn {\n color: color,\n fontSize: '18px'\n};" | ||
65 | + }, | ||
66 | + "_hash": 0.3646047595211721 | ||
67 | + }, | ||
68 | + { | ||
69 | + "name": "eventsSent", | ||
70 | + "type": "timeseries", | ||
71 | + "label": "Sent", | ||
72 | + "color": "#4caf50", | ||
73 | + "settings": { | ||
74 | + "columnWidth": "0px", | ||
75 | + "useCellStyleFunction": false, | ||
76 | + "useCellContentFunction": false | ||
77 | + }, | ||
78 | + "_hash": 0.7235710720767985 | ||
79 | + }, | ||
80 | + { | ||
81 | + "name": "eventsProduced", | ||
82 | + "type": "timeseries", | ||
83 | + "label": "Events", | ||
84 | + "color": "#f44336", | ||
85 | + "settings": { | ||
86 | + "columnWidth": "0px", | ||
87 | + "useCellStyleFunction": false, | ||
88 | + "useCellContentFunction": false | ||
89 | + }, | ||
90 | + "_hash": 0.5085933386303254 | ||
91 | + }, | ||
92 | + { | ||
93 | + "name": "LOGS", | ||
94 | + "type": "timeseries", | ||
95 | + "label": "Latest log", | ||
96 | + "color": "#ffc107", | ||
97 | + "settings": { | ||
98 | + "columnWidth": "0px", | ||
99 | + "useCellStyleFunction": false, | ||
100 | + "useCellContentFunction": false | ||
101 | + }, | ||
102 | + "_hash": 0.3504240371585048, | ||
103 | + "postFuncBody": "if(value) {\n return value.substring(0, 31) + \"...\";\n} else {\n return '';\n}" | ||
104 | + }, | ||
105 | + { | ||
106 | + "name": "RemoteLoggingLevel", | ||
107 | + "type": "attribute", | ||
108 | + "label": "Log level", | ||
109 | + "color": "#607d8b", | ||
110 | + "settings": { | ||
111 | + "columnWidth": "0px", | ||
112 | + "useCellStyleFunction": false, | ||
113 | + "useCellContentFunction": false | ||
114 | + }, | ||
115 | + "_hash": 0.9785994222542516 | ||
116 | + } | ||
117 | + ], | ||
118 | + "entityAliasId": "3e0f533a-0db1-3292-184f-06e73535061a" | ||
119 | + } | ||
120 | + ], | ||
121 | + "showTitleIcon": true, | ||
122 | + "titleIcon": "list", | ||
123 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
124 | + "iconSize": "24px", | ||
125 | + "titleTooltip": "List device", | ||
126 | + "widgetStyle": {}, | ||
127 | + "displayTimewindow": true, | ||
128 | + "actions": { | ||
129 | + "headerButton": [ | ||
130 | + { | ||
131 | + "id": "70837a9d-c3de-a9a7-03c5-dccd14998758", | ||
132 | + "name": "Add device", | ||
133 | + "icon": "add", | ||
134 | + "type": "customPretty", | ||
135 | + "customHtml": "<md-dialog aria-label=\"Add entity\" style=\"width: 480px\">\n <form name=\"addDeviceForm\" ng-submit=\"vm.save()\">\n <md-toolbar>\n <div class=\"md-toolbar-tools\">\n <h2>Add device</h2>\n <span flex></span>\n <md-button class=\"md-icon-button\" ng-click=\"vm.cancel()\">\n <ng-md-icon icon=\"close\" aria-label=\"Close\"></ng-md-icon>\n </md-button>\n </div>\n </md-toolbar>\n <md-progress-linear class=\"md-warn\" md-mode=\"indeterminate\" ng-disabled=\"!$root.loading && !vm.loading\" ng-show=\"$root.loading || vm.loading\"></md-progress-linear>\n <span style=\"min-height: 5px;\" flex=\"\" ng-show=\"!$root.loading && !vm.loading\"></span>\n <md-dialog-content>\n <div class=\"md-dialog-content\">\n <fieldset ng-disabled=\"$root.loading || vm.loading\">\n <md-input-container flex class=\"md-block\">\n <label>Device name</label>\n <input ng-model=\"vm.deviceName\" name=deviceName required>\n <div ng-messages=\"addDeviceForm.deviceName.$error\">\n <div ng-message=\"required\">Device name is required.</div>\n </div>\n </md-input-container>\n <div flex layout=\"row\">\n <md-input-container flex=\"50\" class=\"md-block\">\n <label>Latitude</label>\n <input type=\"number\" step=\"any\" name=\"latitude\" ng-model=\"vm.attributes.latitude\">\n </md-input-container>\n <md-input-container flex=\"50\" class=\"md-block\">\n <label>Longitude</label>\n <input type=\"number\" step=\"any\" name=\"longitude\" ng-model=\"vm.attributes.longitude\">\n </md-input-container>\n </div>\n <md-input-container class=\"md-block\">\n <label>Label</label>\n <input name=\"deviceLabel\" ng-model=\"vm.deviceLabel\">\n </md-input-container>\n </fieldset>\n </div>\n </md-dialog-content>\n <md-dialog-actions>\n <md-button type=\"submit\" ng-disabled=\"vm.loading || addDeviceForm.$invalid || !addDeviceForm.$dirty\" class=\"md-raised md-primary\">Create</md-button>\n <md-button ng-click=\"vm.cancel()\" class=\"md-primary\">Cancel</md-button>\n </md-dialog-actions>\n </form>\n</md-dialog>\n", | ||
136 | + "customCss": "", | ||
137 | + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet $mdDialog = $injector.get('$mdDialog'),\n $document = $injector.get('$document'),\n $q = $injector.get('$q'),\n $rootScope = $injector.get('$rootScope'),\n types = $injector.get('types'),\n deviceService = $injector.get('deviceService'),\n attributeService = $injector.get('attributeService');\n\nopenAddDeviceDialog();\n\nfunction openAddDeviceDialog() {\n $mdDialog.show({\n controller: ['$scope', '$mdDialog',\n AddDeviceDialogController\n ],\n controllerAs: 'vm',\n template: htmlTemplate,\n parent: angular.element($document[0].body),\n targetEvent: $event,\n multiple: true,\n clickOutsideToClose: false\n });\n}\n\nfunction AddDeviceDialogController($scope, $mdDialog) {\n let vm = this;\n vm.types = types;\n vm.attributes = {};\n vm.deviceType = \"gateway\";\n\n vm.cancel = () => {\n $mdDialog.hide();\n };\n\n vm.save = () => {\n vm.loading = true;\n $scope.addDeviceForm.$setPristine();\n let device = {\n additionalInfo: {gateway: true},\n name: vm.deviceName,\n type: vm.deviceType,\n label: vm.deviceLabel\n };\n deviceService.saveDevice(device).then(\n (device) => {\n saveAttributes(device.id).then(\n () => {\n vm.loading = false;\n updateAliasData();\n $mdDialog.hide();\n }\n );\n },\n () => {\n vm.loading = false;\n }\n );\n };\n\n function saveAttributes(entityId) {\n let attributesArray = [];\n for (let key in vm.attributes) {\n attributesArray.push({\n key: key,\n value: vm.attributes[key]\n });\n }\n if (attributesArray.length > 0) {\n return attributeService.saveEntityAttributes(\n entityId.entityType, entityId.id,\n \"SERVER_SCOPE\", attributesArray);\n } else {\n return $q.when([]);\n }\n }\n\n function updateAliasData() {\n let aliasIds = [];\n for (let id in widgetContext.aliasController\n .resolvedAliases) {\n aliasIds.push(id);\n }\n let tasks = [];\n aliasIds.forEach((aliasId) => {\n widgetContext.aliasController\n .setAliasUnresolved(aliasId);\n tasks.push(widgetContext.aliasController\n .getAliasInfo(aliasId));\n });\n $q.all(tasks).then(() => {\n $rootScope.$broadcast(\n 'widgetForceReInit');\n });\n }\n}" | ||
138 | + } | ||
139 | + ], | ||
140 | + "actionCellButton": [ | ||
141 | + { | ||
142 | + "id": "78845501-234e-a452-6819-82b5b776e99f", | ||
143 | + "name": "Configuration", | ||
144 | + "icon": "settings", | ||
145 | + "type": "openDashboardState", | ||
146 | + "targetDashboardStateId": "__entityname__config", | ||
147 | + "openRightLayout": false, | ||
148 | + "setEntityId": true | ||
149 | + }, | ||
150 | + { | ||
151 | + "id": "f6ffdba8-e40f-2b8d-851b-f5ecaf18606b", | ||
152 | + "name": "Graphs", | ||
153 | + "icon": "show_chart", | ||
154 | + "type": "openDashboardState", | ||
155 | + "targetDashboardStateId": "__entityname_grafic", | ||
156 | + "setEntityId": true | ||
157 | + }, | ||
158 | + { | ||
159 | + "id": "242671f3-76c6-6982-7acc-6f12addf0ccc", | ||
160 | + "name": "Edit device", | ||
161 | + "icon": "edit", | ||
162 | + "type": "customPretty", | ||
163 | + "customHtml": "<md-dialog aria-label=\"Edit entity\" style=\"width: 480px\">\n <form name=\"editDeviceForm\" ng-submit=\"vm.save()\">\n <md-toolbar>\n <div class=\"md-toolbar-tools\">\n <h2>Edit device</h2>\n <span flex></span>\n <md-button class=\"md-icon-button\" ng-click=\"vm.cancel()\">\n <ng-md-icon icon=\"close\" aria-label=\"Close\"></ng-md-icon>\n </md-button>\n </div>\n </md-toolbar>\n <md-progress-linear class=\"md-warn\" md-mode=\"indeterminate\" ng-disabled=\"!$root.loading && !vm.loading\" ng-show=\"$root.loading || vm.loading\"></md-progress-linear>\n <span style=\"min-height: 5px;\" flex=\"\" ng-show=\"!$root.loading && !vm.loading\"></span>\n <md-dialog-content>\n <div class=\"md-dialog-content\">\n <fieldset ng-disabled=\"$root.loading || vm.loading\">\n <md-input-container flex class=\"md-block\">\n <label>Device name</label>\n <input ng-model=\"vm.device.name\" name=deviceName required>\n <div ng-messages=\"editDeviceForm.deviceName.$error\">\n <div ng-message=\"required\">Device name is required.</div>\n </div>\n </md-input-container>\n <!--<div flex layout=\"row\">-->\n <!--<tb-entity-subtype-autocomplete flex=\"50\"-->\n <!-- ng-disabled=\"true\"-->\n <!-- tb-required=\"true\"-->\n <!-- the-form=\"editDeviceForm\"-->\n <!-- ng-model=\"vm.device.type\"-->\n <!-- entity-type=\"vm.types.entityType.device\">-->\n <!--</tb-entity-subtype-autocomplete>-->\n <!-- <md-input-container flex=\"50\" class=\"md-block\">-->\n <!-- <label>Label</label>-->\n <!-- <input name=\"deviceLabel\" ng-model=\"vm.device.label\">-->\n <!-- </md-input-container>-->\n <!--</div>-->\n <div flex layout=\"row\">\n <md-input-container flex=\"50\" class=\"md-block\">\n <label>Latitude</label>\n <input type=\"number\" step=\"any\" name=\"latitude\" ng-model=\"vm.attributes.latitude\">\n </md-input-container>\n <md-input-container flex=\"50\" class=\"md-block\">\n <label>Longitude</label>\n <input type=\"number\" step=\"any\" name=\"longitude\" ng-model=\"vm.attributes.longitude\">\n </md-input-container>\n </div>\n <md-input-container class=\"md-block\">\n <label>Label</label>\n <input name=\"deviceLabel\" ng-model=\"vm.device.label\">\n </md-input-container>\n </fieldset>\n </div>\n </md-dialog-content>\n <md-dialog-actions>\n <md-button type=\"submit\" ng-disabled=\"vm.loading || editDeviceForm.$invalid || !editDeviceForm.$dirty\" class=\"md-raised md-primary\">Create</md-button>\n <md-button ng-click=\"vm.cancel()\" class=\"md-primary\">Cancel</md-button>\n </md-dialog-actions>\n </form>\n</md-dialog>", | ||
164 | + "customCss": "/*=======================================================================*/\n/*========== There are two examples: for edit and add entity ==========*/\n/*=======================================================================*/\n/*======================== Edit entity example ========================*/\n/*=======================================================================*/\n/*\n.edit-entity-form md-input-container {\n padding-right: 10px;\n}\n\n.edit-entity-form .boolean-value-input {\n padding-left: 5px;\n}\n\n.edit-entity-form .boolean-value-input .checkbox-label {\n margin-bottom: 8px;\n color: rgba(0,0,0,0.54);\n font-size: 12px;\n}\n\n.relations-list .header {\n padding-right: 5px;\n padding-bottom: 5px;\n padding-left: 5px;\n}\n\n.relations-list .header .cell {\n padding-right: 5px;\n padding-left: 5px;\n font-size: 12px;\n font-weight: 700;\n color: rgba(0, 0, 0, .54);\n white-space: nowrap;\n}\n\n.relations-list .body {\n padding-right: 5px;\n padding-bottom: 15px;\n padding-left: 5px;\n}\n\n.relations-list .body .row {\n padding-top: 5px;\n}\n\n.relations-list .body .cell {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.relations-list .body md-autocomplete-wrap md-input-container {\n height: 30px;\n}\n\n.relations-list .body .md-button {\n margin: 0;\n}\n\n.relations-list.old-relations tb-entity-select tb-entity-autocomplete button {\n display: none;\n} \n*/\n/*========================================================================*/\n/*========================= Add entity example =========================*/\n/*========================================================================*/\n/*\n.add-entity-form md-input-container {\n padding-right: 10px;\n}\n\n.add-entity-form .boolean-value-input {\n padding-left: 5px;\n}\n\n.add-entity-form .boolean-value-input .checkbox-label {\n margin-bottom: 8px;\n color: rgba(0,0,0,0.54);\n font-size: 12px;\n}\n\n.relations-list .header {\n padding-right: 5px;\n padding-bottom: 5px;\n padding-left: 5px;\n}\n\n.relations-list .header .cell {\n padding-right: 5px;\n padding-left: 5px;\n font-size: 12px;\n font-weight: 700;\n color: rgba(0, 0, 0, .54);\n white-space: nowrap;\n}\n\n.relations-list .body {\n padding-right: 5px;\n padding-bottom: 15px;\n padding-left: 5px;\n}\n\n.relations-list .body .row {\n padding-top: 5px;\n}\n\n.relations-list .body .cell {\n padding-right: 5px;\n padding-left: 5px;\n}\n\n.relations-list .body md-autocomplete-wrap md-input-container {\n height: 30px;\n}\n\n.relations-list .body .md-button {\n margin: 0;\n}\n*/\n", | ||
165 | + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet $mdDialog = $injector.get('$mdDialog'),\n $document = $injector.get('$document'),\n $q = $injector.get('$q'),\n $rootScope = $injector.get('$rootScope'),\n types = $injector.get('types'),\n deviceService = $injector.get('deviceService'),\n attributeService = $injector.get('attributeService');\n \nopenEditDeviceDialog();\n\nfunction openEditDeviceDialog() {\n $mdDialog.show({\n controller: ['$scope','$mdDialog', EditDeviceDialogController],\n controllerAs: 'vm',\n template: htmlTemplate,\n parent: angular.element($document[0].body),\n targetEvent: $event,\n multiple: true,\n clickOutsideToClose: false\n });\n}\n\nfunction EditDeviceDialogController($scope,$mdDialog) {\n let vm = this;\n vm.types = types;\n vm.loading = false;\n vm.attributes = {};\n \n getEntityInfo();\n \n function getEntityInfo() {\n vm.loading = true;\n deviceService.getDevice(entityId.id).then(\n (device) => {\n attributeService.getEntityAttributesValues(entityId.entityType, entityId.id, 'SERVER_SCOPE').then(\n (data) => {\n if (data.length) {\n getEntityAttributes(data);\n }\n vm.device = device;\n vm.loading = false;\n } \n );\n }\n )\n }\n \n vm.cancel = function() {\n $mdDialog.hide();\n };\n \n vm.save = () => {\n vm.loading = true;\n $scope.editDeviceForm.$setPristine();\n deviceService.saveDevice(vm.device).then(\n () => {\n saveAttributes().then(\n () => {\n updateAliasData();\n vm.loading = false;\n $mdDialog.hide();\n }\n );\n },\n () => {\n vm.loading = false;\n }\n );\n }\n \n function getEntityAttributes(attributes) {\n for (let i = 0; i < attributes.length; i++) {\n vm.attributes[attributes[i].key] = attributes[i].value; \n }\n }\n \n function saveAttributes() {\n let attributesArray = [];\n for (let key in vm.attributes) {\n attributesArray.push({key: key, value: vm.attributes[key]});\n }\n if (attributesArray.length > 0) {\n return attributeService.saveEntityAttributes(entityId.entityType, entityId.id, \"SERVER_SCOPE\", attributesArray);\n } else {\n return $q.when([]);\n }\n }\n \n function updateAliasData() {\n let aliasIds = [];\n for (let id in widgetContext.aliasController.resolvedAliases) {\n aliasIds.push(id);\n }\n let tasks = [];\n aliasIds.forEach((aliasId) => {\n widgetContext.aliasController.setAliasUnresolved(aliasId);\n tasks.push(widgetContext.aliasController.getAliasInfo(aliasId));\n });\n console.log(widgetContext);\n $q.all(tasks).then(() => {\n $rootScope.$broadcast('widgetForceReInit');\n });\n }\n}\n" | ||
166 | + }, | ||
167 | + { | ||
168 | + "id": "862ec2b7-fbcf-376e-f85f-b77c07f36efa", | ||
169 | + "name": "Delete device", | ||
170 | + "icon": "delete", | ||
171 | + "type": "custom", | ||
172 | + "customFunction": "let $injector = widgetContext.$scope.$injector;\nlet $mdDialog = $injector.get('$mdDialog'),\n $document = $injector.get('$document'),\n types = $injector.get('types'),\n deviceService = $injector.get('deviceService'),\n $rootScope = $injector.get('$rootScope'),\n $q = $injector.get('$q');\n\nopenDeleteDeviceDialog();\n\nfunction openDeleteDeviceDialog() {\n let title = \"Are you sure you want to delete the device \" + entityName + \"?\";\n let content = \"Be careful, after the confirmation, the device and all related data will become unrecoverable!\";\n let confirm = $mdDialog.confirm()\n .targetEvent($event)\n .title(title)\n .htmlContent(content)\n .ariaLabel(title)\n .cancel('Cancel')\n .ok('Delete');\n $mdDialog.show(confirm).then(() => {\n deleteDevice();\n })\n}\n\nfunction deleteDevice() {\n deviceService.deleteDevice(entityId.id).then(\n () => {\n updateAliasData();\n }\n );\n}\n\nfunction updateAliasData() {\n let aliasIds = [];\n for (let id in widgetContext.aliasController.resolvedAliases) {\n aliasIds.push(id);\n }\n let tasks = [];\n aliasIds.forEach((aliasId) => {\n widgetContext.aliasController.setAliasUnresolved(aliasId);\n tasks.push(widgetContext.aliasController.getAliasInfo(aliasId));\n });\n $q.all(tasks).then(() => {\n $rootScope.$broadcast('entityAliasesChanged', aliasIds);\n });\n}" | ||
173 | + } | ||
174 | + ], | ||
175 | + "rowClick": [ | ||
176 | + { | ||
177 | + "id": "ad5fc7e1-5e60-e056-6940-a75a383466a1", | ||
178 | + "name": "to_entityname__config", | ||
179 | + "icon": "more_horiz", | ||
180 | + "type": "openDashboardState", | ||
181 | + "targetDashboardStateId": "__entityname__config", | ||
182 | + "setEntityId": true, | ||
183 | + "stateEntityParamName": "" | ||
184 | + } | ||
185 | + ] | ||
186 | + } | ||
187 | + }, | ||
188 | + "id": "94715984-ae74-76e4-20b7-2f956b01ed80" | ||
189 | + }, | ||
190 | + "eadabbc7-519e-76fc-ba10-b3fe8c18da10": { | ||
191 | + "isSystemType": true, | ||
192 | + "bundleAlias": "cards", | ||
193 | + "typeAlias": "timeseries_table", | ||
194 | + "type": "timeseries", | ||
195 | + "title": "New widget", | ||
196 | + "sizeX": 14, | ||
197 | + "sizeY": 13, | ||
198 | + "config": { | ||
199 | + "datasources": [ | ||
200 | + { | ||
201 | + "type": "entity", | ||
202 | + "dataKeys": [ | ||
203 | + { | ||
204 | + "name": "LOGS", | ||
205 | + "type": "timeseries", | ||
206 | + "label": "LOGS", | ||
207 | + "color": "#2196f3", | ||
208 | + "settings": { | ||
209 | + "useCellStyleFunction": false, | ||
210 | + "useCellContentFunction": false | ||
211 | + }, | ||
212 | + "_hash": 0.3496649158709739, | ||
213 | + "postFuncBody": "return value.replace(/ - (.*) - \\[/gi, ' - <b style=\"color:#0f0;\">$1</b> - [');" | ||
214 | + } | ||
215 | + ], | ||
216 | + "entityAliasId": "b2487e75-2fa4-f211-142c-434dfd50c70c" | ||
217 | + } | ||
218 | + ], | ||
219 | + "timewindow": { | ||
220 | + "realtime": { | ||
221 | + "interval": 1000, | ||
222 | + "timewindowMs": 2592000000 | ||
223 | + }, | ||
224 | + "aggregation": { | ||
225 | + "type": "NONE", | ||
226 | + "limit": 200 | ||
227 | + } | ||
228 | + }, | ||
229 | + "showTitle": true, | ||
230 | + "backgroundColor": "rgb(255, 255, 255)", | ||
231 | + "color": "rgba(0, 0, 0, 0.87)", | ||
232 | + "padding": "8px", | ||
233 | + "settings": { | ||
234 | + "showTimestamp": true, | ||
235 | + "displayPagination": true, | ||
236 | + "defaultPageSize": 10 | ||
237 | + }, | ||
238 | + "title": "Debug events (logs)", | ||
239 | + "dropShadow": true, | ||
240 | + "enableFullscreen": true, | ||
241 | + "titleStyle": { | ||
242 | + "fontSize": "16px", | ||
243 | + "fontWeight": 400 | ||
244 | + }, | ||
245 | + "useDashboardTimewindow": false, | ||
246 | + "showLegend": false, | ||
247 | + "widgetStyle": {}, | ||
248 | + "actions": {}, | ||
249 | + "showTitleIcon": false, | ||
250 | + "titleIcon": null, | ||
251 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
252 | + "iconSize": "24px", | ||
253 | + "titleTooltip": "", | ||
254 | + "displayTimewindow": true | ||
255 | + }, | ||
256 | + "id": "eadabbc7-519e-76fc-ba10-b3fe8c18da10" | ||
257 | + }, | ||
258 | + "f928afc4-30d1-8d0c-e3cf-777f9f9d1155": { | ||
259 | + "isSystemType": true, | ||
260 | + "bundleAlias": "charts", | ||
261 | + "typeAlias": "basic_timeseries", | ||
262 | + "type": "timeseries", | ||
263 | + "title": "New widget", | ||
264 | + "sizeX": 17, | ||
265 | + "sizeY": 4, | ||
266 | + "config": { | ||
267 | + "datasources": [ | ||
268 | + { | ||
269 | + "type": "entity", | ||
270 | + "dataKeys": [ | ||
271 | + { | ||
272 | + "name": "opcuaEventsProduced", | ||
273 | + "type": "timeseries", | ||
274 | + "label": "opcuaEventsProduced", | ||
275 | + "color": "#2196f3", | ||
276 | + "settings": { | ||
277 | + "excludeFromStacking": false, | ||
278 | + "hideDataByDefault": false, | ||
279 | + "disableDataHiding": false, | ||
280 | + "removeFromLegend": false, | ||
281 | + "showLines": true, | ||
282 | + "fillLines": false, | ||
283 | + "showPoints": false, | ||
284 | + "showPointShape": "circle", | ||
285 | + "pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", | ||
286 | + "showPointsLineWidth": 5, | ||
287 | + "showPointsRadius": 3, | ||
288 | + "tooltipValueFormatter": "", | ||
289 | + "showSeparateAxis": false, | ||
290 | + "axisTitle": "", | ||
291 | + "axisPosition": "left", | ||
292 | + "axisTicksFormatter": "", | ||
293 | + "comparisonSettings": { | ||
294 | + "showValuesForComparison": true, | ||
295 | + "comparisonValuesLabel": "", | ||
296 | + "color": "" | ||
297 | + } | ||
298 | + }, | ||
299 | + "_hash": 0.1477920581839779 | ||
300 | + }, | ||
301 | + { | ||
302 | + "name": "opcuaEventsSent", | ||
303 | + "type": "timeseries", | ||
304 | + "label": "opcuaEventsSent", | ||
305 | + "color": "#4caf50", | ||
306 | + "settings": { | ||
307 | + "excludeFromStacking": false, | ||
308 | + "hideDataByDefault": false, | ||
309 | + "disableDataHiding": false, | ||
310 | + "removeFromLegend": false, | ||
311 | + "showLines": true, | ||
312 | + "fillLines": false, | ||
313 | + "showPoints": false, | ||
314 | + "showPointShape": "circle", | ||
315 | + "pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", | ||
316 | + "showPointsLineWidth": 5, | ||
317 | + "showPointsRadius": 3, | ||
318 | + "tooltipValueFormatter": "", | ||
319 | + "showSeparateAxis": false, | ||
320 | + "axisTitle": "", | ||
321 | + "axisPosition": "left", | ||
322 | + "axisTicksFormatter": "", | ||
323 | + "comparisonSettings": { | ||
324 | + "showValuesForComparison": true, | ||
325 | + "comparisonValuesLabel": "", | ||
326 | + "color": "" | ||
327 | + } | ||
328 | + }, | ||
329 | + "_hash": 0.6500957113784758 | ||
330 | + } | ||
331 | + ], | ||
332 | + "entityAliasId": "b2487e75-2fa4-f211-142c-434dfd50c70c" | ||
333 | + } | ||
334 | + ], | ||
335 | + "timewindow": { | ||
336 | + "realtime": { | ||
337 | + "interval": 1000, | ||
338 | + "timewindowMs": 120000 | ||
339 | + }, | ||
340 | + "aggregation": { | ||
341 | + "type": "NONE", | ||
342 | + "limit": 25000 | ||
343 | + }, | ||
344 | + "hideInterval": false, | ||
345 | + "hideAggregation": false | ||
346 | + }, | ||
347 | + "showTitle": true, | ||
348 | + "backgroundColor": "#fff", | ||
349 | + "color": "rgba(0, 0, 0, 0.87)", | ||
350 | + "padding": "8px", | ||
351 | + "settings": { | ||
352 | + "shadowSize": 4, | ||
353 | + "fontColor": "#545454", | ||
354 | + "fontSize": 10, | ||
355 | + "xaxis": { | ||
356 | + "showLabels": true, | ||
357 | + "color": "#545454" | ||
358 | + }, | ||
359 | + "yaxis": { | ||
360 | + "showLabels": true, | ||
361 | + "color": "#545454" | ||
362 | + }, | ||
363 | + "grid": { | ||
364 | + "color": "#545454", | ||
365 | + "tickColor": "#DDDDDD", | ||
366 | + "verticalLines": true, | ||
367 | + "horizontalLines": true, | ||
368 | + "outlineWidth": 1 | ||
369 | + }, | ||
370 | + "stack": false, | ||
371 | + "tooltipIndividual": false, | ||
372 | + "timeForComparison": "months", | ||
373 | + "xaxisSecond": { | ||
374 | + "axisPosition": "top", | ||
375 | + "showLabels": true | ||
376 | + } | ||
377 | + }, | ||
378 | + "title": "Real time information", | ||
379 | + "dropShadow": true, | ||
380 | + "enableFullscreen": true, | ||
381 | + "titleStyle": { | ||
382 | + "fontSize": "16px", | ||
383 | + "fontWeight": 400 | ||
384 | + }, | ||
385 | + "mobileHeight": null, | ||
386 | + "showTitleIcon": false, | ||
387 | + "titleIcon": null, | ||
388 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
389 | + "iconSize": "24px", | ||
390 | + "titleTooltip": "", | ||
391 | + "widgetStyle": {}, | ||
392 | + "useDashboardTimewindow": false, | ||
393 | + "displayTimewindow": true, | ||
394 | + "showLegend": true, | ||
395 | + "legendConfig": { | ||
396 | + "direction": "column", | ||
397 | + "position": "right", | ||
398 | + "showMin": true, | ||
399 | + "showMax": true, | ||
400 | + "showAvg": true, | ||
401 | + "showTotal": true | ||
402 | + }, | ||
403 | + "actions": {} | ||
404 | + }, | ||
405 | + "id": "f928afc4-30d1-8d0c-e3cf-777f9f9d1155" | ||
406 | + }, | ||
407 | + "2a95b473-042d-59d0-2da2-40d0cccb6c8a": { | ||
408 | + "isSystemType": true, | ||
409 | + "bundleAlias": "cards", | ||
410 | + "typeAlias": "timeseries_table", | ||
411 | + "type": "timeseries", | ||
412 | + "title": "New widget", | ||
413 | + "sizeX": 7, | ||
414 | + "sizeY": 7, | ||
415 | + "config": { | ||
416 | + "datasources": [ | ||
417 | + { | ||
418 | + "type": "entity", | ||
419 | + "dataKeys": [ | ||
420 | + { | ||
421 | + "name": "eventsSent", | ||
422 | + "type": "timeseries", | ||
423 | + "label": "Events", | ||
424 | + "color": "#2196f3", | ||
425 | + "settings": { | ||
426 | + "useCellStyleFunction": false, | ||
427 | + "useCellContentFunction": false | ||
428 | + }, | ||
429 | + "_hash": 0.8156044798125357 | ||
430 | + }, | ||
431 | + { | ||
432 | + "name": "eventsProduced", | ||
433 | + "type": "timeseries", | ||
434 | + "label": "Produced", | ||
435 | + "color": "#4caf50", | ||
436 | + "settings": { | ||
437 | + "useCellStyleFunction": false, | ||
438 | + "useCellContentFunction": false | ||
439 | + }, | ||
440 | + "_hash": 0.6538259344015449 | ||
441 | + } | ||
442 | + ], | ||
443 | + "entityAliasId": "b2487e75-2fa4-f211-142c-434dfd50c70c" | ||
444 | + } | ||
445 | + ], | ||
446 | + "timewindow": { | ||
447 | + "realtime": { | ||
448 | + "interval": 1000, | ||
449 | + "timewindowMs": 604800000 | ||
450 | + }, | ||
451 | + "aggregation": { | ||
452 | + "type": "NONE", | ||
453 | + "limit": 200 | ||
454 | + } | ||
455 | + }, | ||
456 | + "showTitle": true, | ||
457 | + "backgroundColor": "rgb(255, 255, 255)", | ||
458 | + "color": "rgba(0, 0, 0, 0.87)", | ||
459 | + "padding": "8px", | ||
460 | + "settings": { | ||
461 | + "showTimestamp": true, | ||
462 | + "displayPagination": true, | ||
463 | + "defaultPageSize": 6, | ||
464 | + "hideEmptyLines": true | ||
465 | + }, | ||
466 | + "title": "Total Messages", | ||
467 | + "dropShadow": true, | ||
468 | + "enableFullscreen": true, | ||
469 | + "titleStyle": { | ||
470 | + "fontSize": "16px", | ||
471 | + "fontWeight": 400 | ||
472 | + }, | ||
473 | + "useDashboardTimewindow": false, | ||
474 | + "showLegend": false, | ||
475 | + "widgetStyle": {}, | ||
476 | + "actions": {}, | ||
477 | + "showTitleIcon": false, | ||
478 | + "titleIcon": null, | ||
479 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
480 | + "iconSize": "24px", | ||
481 | + "titleTooltip": "", | ||
482 | + "displayTimewindow": true, | ||
483 | + "legendConfig": { | ||
484 | + "direction": "column", | ||
485 | + "position": "bottom", | ||
486 | + "showMin": false, | ||
487 | + "showMax": false, | ||
488 | + "showAvg": true, | ||
489 | + "showTotal": false | ||
490 | + } | ||
491 | + }, | ||
492 | + "id": "2a95b473-042d-59d0-2da2-40d0cccb6c8a" | ||
493 | + }, | ||
494 | + "aaa69366-aacc-9028-65aa-645c0f8533ec": { | ||
495 | + "isSystemType": true, | ||
496 | + "bundleAlias": "charts", | ||
497 | + "typeAlias": "basic_timeseries", | ||
498 | + "type": "timeseries", | ||
499 | + "title": "New widget", | ||
500 | + "sizeX": 17, | ||
501 | + "sizeY": 4, | ||
502 | + "config": { | ||
503 | + "datasources": [ | ||
504 | + { | ||
505 | + "type": "entity", | ||
506 | + "dataKeys": [ | ||
507 | + { | ||
508 | + "name": "eventsSent", | ||
509 | + "type": "timeseries", | ||
510 | + "label": "eventsSent", | ||
511 | + "color": "#2196f3", | ||
512 | + "settings": { | ||
513 | + "excludeFromStacking": false, | ||
514 | + "hideDataByDefault": false, | ||
515 | + "disableDataHiding": false, | ||
516 | + "removeFromLegend": false, | ||
517 | + "showLines": true, | ||
518 | + "fillLines": false, | ||
519 | + "showPoints": false, | ||
520 | + "showPointShape": "circle", | ||
521 | + "pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", | ||
522 | + "showPointsLineWidth": 5, | ||
523 | + "showPointsRadius": 3, | ||
524 | + "tooltipValueFormatter": "", | ||
525 | + "showSeparateAxis": false, | ||
526 | + "axisTitle": "", | ||
527 | + "axisPosition": "left", | ||
528 | + "axisTicksFormatter": "", | ||
529 | + "comparisonSettings": { | ||
530 | + "showValuesForComparison": true, | ||
531 | + "comparisonValuesLabel": "", | ||
532 | + "color": "" | ||
533 | + } | ||
534 | + }, | ||
535 | + "_hash": 0.41414001784591314 | ||
536 | + }, | ||
537 | + { | ||
538 | + "name": "eventsProduced", | ||
539 | + "type": "timeseries", | ||
540 | + "label": "eventsProduced", | ||
541 | + "color": "#4caf50", | ||
542 | + "settings": { | ||
543 | + "excludeFromStacking": false, | ||
544 | + "hideDataByDefault": false, | ||
545 | + "disableDataHiding": false, | ||
546 | + "removeFromLegend": false, | ||
547 | + "showLines": true, | ||
548 | + "fillLines": false, | ||
549 | + "showPoints": false, | ||
550 | + "showPointShape": "circle", | ||
551 | + "pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", | ||
552 | + "showPointsLineWidth": 5, | ||
553 | + "showPointsRadius": 3, | ||
554 | + "tooltipValueFormatter": "", | ||
555 | + "showSeparateAxis": false, | ||
556 | + "axisTitle": "", | ||
557 | + "axisPosition": "left", | ||
558 | + "axisTicksFormatter": "", | ||
559 | + "comparisonSettings": { | ||
560 | + "showValuesForComparison": true, | ||
561 | + "comparisonValuesLabel": "", | ||
562 | + "color": "" | ||
563 | + } | ||
564 | + }, | ||
565 | + "_hash": 0.7819101846284422 | ||
566 | + } | ||
567 | + ], | ||
568 | + "entityAliasId": "b2487e75-2fa4-f211-142c-434dfd50c70c" | ||
569 | + } | ||
570 | + ], | ||
571 | + "timewindow": { | ||
572 | + "realtime": { | ||
573 | + "timewindowMs": 60000 | ||
574 | + } | ||
575 | + }, | ||
576 | + "showTitle": true, | ||
577 | + "backgroundColor": "#fff", | ||
578 | + "color": "rgba(0, 0, 0, 0.87)", | ||
579 | + "padding": "8px", | ||
580 | + "settings": { | ||
581 | + "shadowSize": 4, | ||
582 | + "fontColor": "#545454", | ||
583 | + "fontSize": 10, | ||
584 | + "xaxis": { | ||
585 | + "showLabels": true, | ||
586 | + "color": "#545454" | ||
587 | + }, | ||
588 | + "yaxis": { | ||
589 | + "showLabels": true, | ||
590 | + "color": "#545454" | ||
591 | + }, | ||
592 | + "grid": { | ||
593 | + "color": "#545454", | ||
594 | + "tickColor": "#DDDDDD", | ||
595 | + "verticalLines": true, | ||
596 | + "horizontalLines": true, | ||
597 | + "outlineWidth": 1 | ||
598 | + }, | ||
599 | + "stack": false, | ||
600 | + "tooltipIndividual": false, | ||
601 | + "timeForComparison": "months", | ||
602 | + "xaxisSecond": { | ||
603 | + "axisPosition": "top", | ||
604 | + "showLabels": true | ||
605 | + } | ||
606 | + }, | ||
607 | + "title": "History information", | ||
608 | + "dropShadow": true, | ||
609 | + "enableFullscreen": true, | ||
610 | + "titleStyle": { | ||
611 | + "fontSize": "16px", | ||
612 | + "fontWeight": 400 | ||
613 | + }, | ||
614 | + "mobileHeight": null, | ||
615 | + "showTitleIcon": false, | ||
616 | + "titleIcon": null, | ||
617 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
618 | + "iconSize": "24px", | ||
619 | + "titleTooltip": "", | ||
620 | + "widgetStyle": {}, | ||
621 | + "useDashboardTimewindow": true, | ||
622 | + "displayTimewindow": true, | ||
623 | + "showLegend": true, | ||
624 | + "legendConfig": { | ||
625 | + "direction": "column", | ||
626 | + "position": "right", | ||
627 | + "showMin": true, | ||
628 | + "showMax": true, | ||
629 | + "showAvg": true, | ||
630 | + "showTotal": true | ||
631 | + }, | ||
632 | + "actions": {} | ||
633 | + }, | ||
634 | + "id": "aaa69366-aacc-9028-65aa-645c0f8533ec" | ||
635 | + }, | ||
636 | + "ce5c7d01-a3ef-5cf0-4578-8505135c23a0": { | ||
637 | + "isSystemType": true, | ||
638 | + "bundleAlias": "charts", | ||
639 | + "typeAlias": "basic_timeseries", | ||
640 | + "type": "timeseries", | ||
641 | + "title": "New widget", | ||
642 | + "sizeX": 17, | ||
643 | + "sizeY": 4, | ||
644 | + "config": { | ||
645 | + "datasources": [ | ||
646 | + { | ||
647 | + "type": "entity", | ||
648 | + "dataKeys": [ | ||
649 | + { | ||
650 | + "name": "bleEventsProduced", | ||
651 | + "type": "timeseries", | ||
652 | + "label": "bleEventsProduced", | ||
653 | + "color": "#2196f3", | ||
654 | + "settings": { | ||
655 | + "excludeFromStacking": false, | ||
656 | + "hideDataByDefault": false, | ||
657 | + "disableDataHiding": false, | ||
658 | + "removeFromLegend": false, | ||
659 | + "showLines": true, | ||
660 | + "fillLines": false, | ||
661 | + "showPoints": false, | ||
662 | + "showPointShape": "circle", | ||
663 | + "pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", | ||
664 | + "showPointsLineWidth": 5, | ||
665 | + "showPointsRadius": 3, | ||
666 | + "tooltipValueFormatter": "", | ||
667 | + "showSeparateAxis": false, | ||
668 | + "axisTitle": "", | ||
669 | + "axisPosition": "left", | ||
670 | + "axisTicksFormatter": "", | ||
671 | + "comparisonSettings": { | ||
672 | + "showValuesForComparison": true, | ||
673 | + "comparisonValuesLabel": "", | ||
674 | + "color": "" | ||
675 | + } | ||
676 | + }, | ||
677 | + "_hash": 0.5625165504526104 | ||
678 | + }, | ||
679 | + { | ||
680 | + "name": "bleEventsSent", | ||
681 | + "type": "timeseries", | ||
682 | + "label": "bleEventsSent", | ||
683 | + "color": "#4caf50", | ||
684 | + "settings": { | ||
685 | + "excludeFromStacking": false, | ||
686 | + "hideDataByDefault": false, | ||
687 | + "disableDataHiding": false, | ||
688 | + "removeFromLegend": false, | ||
689 | + "showLines": true, | ||
690 | + "fillLines": false, | ||
691 | + "showPoints": false, | ||
692 | + "showPointShape": "circle", | ||
693 | + "pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", | ||
694 | + "showPointsLineWidth": 5, | ||
695 | + "showPointsRadius": 3, | ||
696 | + "tooltipValueFormatter": "", | ||
697 | + "showSeparateAxis": false, | ||
698 | + "axisTitle": "", | ||
699 | + "axisPosition": "left", | ||
700 | + "axisTicksFormatter": "", | ||
701 | + "comparisonSettings": { | ||
702 | + "showValuesForComparison": true, | ||
703 | + "comparisonValuesLabel": "", | ||
704 | + "color": "" | ||
705 | + } | ||
706 | + }, | ||
707 | + "_hash": 0.6817950080745288 | ||
708 | + } | ||
709 | + ], | ||
710 | + "entityAliasId": "b2487e75-2fa4-f211-142c-434dfd50c70c" | ||
711 | + } | ||
712 | + ], | ||
713 | + "timewindow": { | ||
714 | + "realtime": { | ||
715 | + "interval": 5000, | ||
716 | + "timewindowMs": 120000 | ||
717 | + }, | ||
718 | + "aggregation": { | ||
719 | + "type": "AVG", | ||
720 | + "limit": 25000 | ||
721 | + } | ||
722 | + }, | ||
723 | + "showTitle": true, | ||
724 | + "backgroundColor": "#fff", | ||
725 | + "color": "rgba(0, 0, 0, 0.87)", | ||
726 | + "padding": "8px", | ||
727 | + "settings": { | ||
728 | + "shadowSize": 4, | ||
729 | + "fontColor": "#545454", | ||
730 | + "fontSize": 10, | ||
731 | + "xaxis": { | ||
732 | + "showLabels": true, | ||
733 | + "color": "#545454" | ||
734 | + }, | ||
735 | + "yaxis": { | ||
736 | + "showLabels": true, | ||
737 | + "color": "#545454" | ||
738 | + }, | ||
739 | + "grid": { | ||
740 | + "color": "#545454", | ||
741 | + "tickColor": "#DDDDDD", | ||
742 | + "verticalLines": true, | ||
743 | + "horizontalLines": true, | ||
744 | + "outlineWidth": 1 | ||
745 | + }, | ||
746 | + "stack": false, | ||
747 | + "tooltipIndividual": false, | ||
748 | + "timeForComparison": "months", | ||
749 | + "xaxisSecond": { | ||
750 | + "axisPosition": "top", | ||
751 | + "showLabels": true | ||
752 | + } | ||
753 | + }, | ||
754 | + "title": "Real time information", | ||
755 | + "dropShadow": true, | ||
756 | + "enableFullscreen": true, | ||
757 | + "titleStyle": { | ||
758 | + "fontSize": "16px", | ||
759 | + "fontWeight": 400 | ||
760 | + }, | ||
761 | + "mobileHeight": null, | ||
762 | + "showTitleIcon": false, | ||
763 | + "titleIcon": null, | ||
764 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
765 | + "iconSize": "24px", | ||
766 | + "titleTooltip": "", | ||
767 | + "widgetStyle": {}, | ||
768 | + "useDashboardTimewindow": false, | ||
769 | + "displayTimewindow": true, | ||
770 | + "showLegend": true, | ||
771 | + "legendConfig": { | ||
772 | + "direction": "column", | ||
773 | + "position": "right", | ||
774 | + "showMin": true, | ||
775 | + "showMax": true, | ||
776 | + "showAvg": true, | ||
777 | + "showTotal": true | ||
778 | + }, | ||
779 | + "actions": {} | ||
780 | + }, | ||
781 | + "id": "ce5c7d01-a3ef-5cf0-4578-8505135c23a0" | ||
782 | + }, | ||
783 | + "466f046d-6005-a168-b107-60fcb2469cd5": { | ||
784 | + "isSystemType": true, | ||
785 | + "bundleAlias": "gateway_widgets", | ||
786 | + "typeAlias": "attributes_card", | ||
787 | + "type": "latest", | ||
788 | + "title": "New widget", | ||
789 | + "sizeX": 7, | ||
790 | + "sizeY": 5, | ||
791 | + "config": { | ||
792 | + "datasources": [ | ||
793 | + { | ||
794 | + "type": "entity", | ||
795 | + "dataKeys": [], | ||
796 | + "entityAliasId": "b2487e75-2fa4-f211-142c-434dfd50c70c" | ||
797 | + } | ||
798 | + ], | ||
799 | + "timewindow": { | ||
800 | + "realtime": { | ||
801 | + "timewindowMs": 60000 | ||
802 | + } | ||
803 | + }, | ||
804 | + "showTitle": true, | ||
805 | + "backgroundColor": "#fff", | ||
806 | + "color": "rgba(0, 0, 0, 0.87)", | ||
807 | + "padding": "8px", | ||
808 | + "settings": { | ||
809 | + "eventsTitle": "Gateway Events Form", | ||
810 | + "eventsReg": [ | ||
811 | + "EventsProduced", | ||
812 | + "EventsSent" | ||
813 | + ] | ||
814 | + }, | ||
815 | + "title": "Gateway events", | ||
816 | + "showTitleIcon": false, | ||
817 | + "titleIcon": null, | ||
818 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
819 | + "iconSize": "24px", | ||
820 | + "titleTooltip": "", | ||
821 | + "dropShadow": true, | ||
822 | + "enableFullscreen": true, | ||
823 | + "widgetStyle": {}, | ||
824 | + "titleStyle": { | ||
825 | + "fontSize": "16px", | ||
826 | + "fontWeight": 400 | ||
827 | + }, | ||
828 | + "useDashboardTimewindow": true, | ||
829 | + "displayTimewindow": true, | ||
830 | + "showLegend": false, | ||
831 | + "actions": {} | ||
832 | + }, | ||
833 | + "id": "466f046d-6005-a168-b107-60fcb2469cd5" | ||
834 | + }, | ||
835 | + "8fc32225-164f-3258-73f7-e6b6d959cf0b": { | ||
836 | + "isSystemType": true, | ||
837 | + "bundleAlias": "gateway_widgets", | ||
838 | + "typeAlias": "config_form_latest", | ||
839 | + "type": "latest", | ||
840 | + "title": "New widget", | ||
841 | + "sizeX": 10, | ||
842 | + "sizeY": 9, | ||
843 | + "config": { | ||
844 | + "datasources": [ | ||
845 | + { | ||
846 | + "type": "entity", | ||
847 | + "dataKeys": [], | ||
848 | + "entityAliasId": "b2487e75-2fa4-f211-142c-434dfd50c70c" | ||
849 | + } | ||
850 | + ], | ||
851 | + "timewindow": { | ||
852 | + "realtime": { | ||
853 | + "timewindowMs": 60000 | ||
854 | + } | ||
855 | + }, | ||
856 | + "showTitle": true, | ||
857 | + "backgroundColor": "#fff", | ||
858 | + "color": "rgba(0, 0, 0, 0.87)", | ||
859 | + "padding": "8px", | ||
860 | + "settings": { | ||
861 | + "gatewayTitle": "Gateway configuration (Single device)", | ||
862 | + "readOnly": false | ||
863 | + }, | ||
864 | + "title": "New Gateway configuration (Single device)", | ||
865 | + "showTitleIcon": false, | ||
866 | + "titleIcon": null, | ||
867 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
868 | + "iconSize": "24px", | ||
869 | + "titleTooltip": "", | ||
870 | + "dropShadow": true, | ||
871 | + "enableFullscreen": true, | ||
872 | + "widgetStyle": {}, | ||
873 | + "titleStyle": { | ||
874 | + "fontSize": "16px", | ||
875 | + "fontWeight": 400 | ||
876 | + }, | ||
877 | + "useDashboardTimewindow": true, | ||
878 | + "displayTimewindow": true, | ||
879 | + "showLegend": false, | ||
880 | + "actions": {} | ||
881 | + }, | ||
882 | + "id": "8fc32225-164f-3258-73f7-e6b6d959cf0b" | ||
883 | + }, | ||
884 | + "063fc179-c9fd-f952-e714-f24e9c43c05c": { | ||
885 | + "isSystemType": true, | ||
886 | + "bundleAlias": "control_widgets", | ||
887 | + "typeAlias": "rpcbutton", | ||
888 | + "type": "rpc", | ||
889 | + "title": "New widget", | ||
890 | + "sizeX": 4, | ||
891 | + "sizeY": 2, | ||
892 | + "config": { | ||
893 | + "targetDeviceAliases": [], | ||
894 | + "showTitle": false, | ||
895 | + "backgroundColor": "#e6e7e8", | ||
896 | + "color": "rgba(0, 0, 0, 0.87)", | ||
897 | + "padding": "0px", | ||
898 | + "settings": { | ||
899 | + "requestTimeout": 5000, | ||
900 | + "oneWayElseTwoWay": true, | ||
901 | + "styleButton": { | ||
902 | + "isRaised": true, | ||
903 | + "isPrimary": false | ||
904 | + }, | ||
905 | + "methodParams": "{}", | ||
906 | + "methodName": "gateway_reboot", | ||
907 | + "buttonText": "GATEWAY REBOOT" | ||
908 | + }, | ||
909 | + "title": "New RPC Button", | ||
910 | + "dropShadow": true, | ||
911 | + "enableFullscreen": false, | ||
912 | + "widgetStyle": {}, | ||
913 | + "titleStyle": { | ||
914 | + "fontSize": "16px", | ||
915 | + "fontWeight": 400 | ||
916 | + }, | ||
917 | + "useDashboardTimewindow": true, | ||
918 | + "showLegend": false, | ||
919 | + "actions": {}, | ||
920 | + "datasources": [], | ||
921 | + "showTitleIcon": false, | ||
922 | + "titleIcon": null, | ||
923 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
924 | + "iconSize": "24px", | ||
925 | + "titleTooltip": "", | ||
926 | + "displayTimewindow": true, | ||
927 | + "targetDeviceAliasIds": [ | ||
928 | + "b2487e75-2fa4-f211-142c-434dfd50c70c" | ||
929 | + ] | ||
930 | + }, | ||
931 | + "id": "063fc179-c9fd-f952-e714-f24e9c43c05c" | ||
932 | + }, | ||
933 | + "3c2134cc-27a0-93e1-dbe1-2fa7c1ce16b7": { | ||
934 | + "isSystemType": true, | ||
935 | + "bundleAlias": "control_widgets", | ||
936 | + "typeAlias": "rpcbutton", | ||
937 | + "type": "rpc", | ||
938 | + "title": "New widget", | ||
939 | + "sizeX": 4, | ||
940 | + "sizeY": 2, | ||
941 | + "config": { | ||
942 | + "targetDeviceAliases": [], | ||
943 | + "showTitle": false, | ||
944 | + "backgroundColor": "#e6e7e8", | ||
945 | + "color": "rgba(0, 0, 0, 0.87)", | ||
946 | + "padding": "0px", | ||
947 | + "settings": { | ||
948 | + "requestTimeout": 5000, | ||
949 | + "oneWayElseTwoWay": true, | ||
950 | + "styleButton": { | ||
951 | + "isRaised": true, | ||
952 | + "isPrimary": false | ||
953 | + }, | ||
954 | + "methodName": "gateway_restart", | ||
955 | + "methodParams": "{}", | ||
956 | + "buttonText": "gateway restart" | ||
957 | + }, | ||
958 | + "title": "New RPC Button", | ||
959 | + "dropShadow": true, | ||
960 | + "enableFullscreen": false, | ||
961 | + "widgetStyle": {}, | ||
962 | + "titleStyle": { | ||
963 | + "fontSize": "16px", | ||
964 | + "fontWeight": 400 | ||
965 | + }, | ||
966 | + "useDashboardTimewindow": true, | ||
967 | + "showLegend": false, | ||
968 | + "actions": {}, | ||
969 | + "datasources": [], | ||
970 | + "showTitleIcon": false, | ||
971 | + "titleIcon": null, | ||
972 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
973 | + "iconSize": "24px", | ||
974 | + "titleTooltip": "", | ||
975 | + "displayTimewindow": true, | ||
976 | + "targetDeviceAliasIds": [ | ||
977 | + "b2487e75-2fa4-f211-142c-434dfd50c70c" | ||
978 | + ] | ||
979 | + }, | ||
980 | + "id": "3c2134cc-27a0-93e1-dbe1-2fa7c1ce16b7" | ||
981 | + }, | ||
982 | + "6770b6ba-eff8-df05-75f8-c1f9326d4842": { | ||
983 | + "isSystemType": true, | ||
984 | + "bundleAlias": "input_widgets", | ||
985 | + "typeAlias": "markers_placement_openstreetmap", | ||
986 | + "type": "latest", | ||
987 | + "title": "New widget", | ||
988 | + "sizeX": 6, | ||
989 | + "sizeY": 4, | ||
990 | + "config": { | ||
991 | + "datasources": [ | ||
992 | + { | ||
993 | + "type": "entity", | ||
994 | + "dataKeys": [ | ||
995 | + { | ||
996 | + "name": "latitude", | ||
997 | + "type": "attribute", | ||
998 | + "label": "latitude", | ||
999 | + "color": "#2196f3", | ||
1000 | + "settings": {}, | ||
1001 | + "_hash": 0.9743324774725604 | ||
1002 | + }, | ||
1003 | + { | ||
1004 | + "name": "longitude", | ||
1005 | + "type": "attribute", | ||
1006 | + "label": "longitude", | ||
1007 | + "color": "#4caf50", | ||
1008 | + "settings": {}, | ||
1009 | + "_hash": 0.5530093635101525 | ||
1010 | + } | ||
1011 | + ], | ||
1012 | + "entityAliasId": "b2487e75-2fa4-f211-142c-434dfd50c70c" | ||
1013 | + } | ||
1014 | + ], | ||
1015 | + "timewindow": { | ||
1016 | + "realtime": { | ||
1017 | + "timewindowMs": 60000 | ||
1018 | + } | ||
1019 | + }, | ||
1020 | + "showTitle": false, | ||
1021 | + "backgroundColor": "#fff", | ||
1022 | + "color": "rgba(0, 0, 0, 0.87)", | ||
1023 | + "padding": "8px", | ||
1024 | + "settings": { | ||
1025 | + "fitMapBounds": true, | ||
1026 | + "latKeyName": "latitude", | ||
1027 | + "lngKeyName": "longitude", | ||
1028 | + "showLabel": true, | ||
1029 | + "label": "${entityName}", | ||
1030 | + "tooltipPattern": "<b>${entityName}</b><br/><br/><b>Latitude:</b> ${latitude:7}<br/><b>Longitude:</b> ${longitude:7}<br/><br/><link-act name='delete'>Delete</link-act>", | ||
1031 | + "markerImageSize": 34, | ||
1032 | + "useColorFunction": false, | ||
1033 | + "markerImages": [], | ||
1034 | + "useMarkerImageFunction": false, | ||
1035 | + "color": "#fe7569", | ||
1036 | + "mapProvider": "OpenStreetMap.Mapnik", | ||
1037 | + "showTooltip": true, | ||
1038 | + "autocloseTooltip": true, | ||
1039 | + "defaultCenterPosition": [ | ||
1040 | + 0, | ||
1041 | + 0 | ||
1042 | + ], | ||
1043 | + "customProviderTileUrl": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", | ||
1044 | + "showTooltipAction": "click", | ||
1045 | + "polygonKeyName": "coordinates", | ||
1046 | + "polygonOpacity": 0.5, | ||
1047 | + "polygonStrokeOpacity": 1, | ||
1048 | + "polygonStrokeWeight": 1, | ||
1049 | + "zoomOnClick": true, | ||
1050 | + "showCoverageOnHover": true, | ||
1051 | + "animate": true, | ||
1052 | + "maxClusterRadius": 80, | ||
1053 | + "removeOutsideVisibleBounds": true, | ||
1054 | + "defaultZoomLevel": 5 | ||
1055 | + }, | ||
1056 | + "title": "Gateway Location", | ||
1057 | + "dropShadow": true, | ||
1058 | + "enableFullscreen": false, | ||
1059 | + "titleStyle": { | ||
1060 | + "fontSize": "16px", | ||
1061 | + "fontWeight": 400 | ||
1062 | + }, | ||
1063 | + "useDashboardTimewindow": true, | ||
1064 | + "showLegend": false, | ||
1065 | + "widgetStyle": {}, | ||
1066 | + "actions": { | ||
1067 | + "tooltipAction": [ | ||
1068 | + { | ||
1069 | + "id": "54c293c4-9ca6-e34f-dc6a-0271944c1c66", | ||
1070 | + "name": "delete", | ||
1071 | + "icon": "more_horiz", | ||
1072 | + "type": "custom", | ||
1073 | + "customFunction": "var $rootScope = widgetContext.$scope.$injector.get('$rootScope');\nvar entityDatasource = widgetContext.map.subscription.datasources.filter(\n function(entity) {\n return entity.entityId === entityId.id\n });\n\nwidgetContext.map.saveMarkerLocation(entityDatasource[0],\n widgetContext.map.locations[0], {\n \"lat\": null,\n \"lng\": null\n }).then(function succes() {\n $rootScope.$broadcast('widgetForceReInit');\n });" | ||
1074 | + } | ||
1075 | + ] | ||
1076 | + }, | ||
1077 | + "showTitleIcon": false, | ||
1078 | + "titleIcon": null, | ||
1079 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
1080 | + "iconSize": "24px", | ||
1081 | + "titleTooltip": "", | ||
1082 | + "displayTimewindow": true | ||
1083 | + }, | ||
1084 | + "id": "6770b6ba-eff8-df05-75f8-c1f9326d4842" | ||
1085 | + } | ||
1086 | + }, | ||
1087 | + "states": { | ||
1088 | + "main_gateway": { | ||
1089 | + "name": "Gateways", | ||
1090 | + "root": true, | ||
1091 | + "layouts": { | ||
1092 | + "main": { | ||
1093 | + "widgets": { | ||
1094 | + "94715984-ae74-76e4-20b7-2f956b01ed80": { | ||
1095 | + "sizeX": 24, | ||
1096 | + "sizeY": 12, | ||
1097 | + "row": 0, | ||
1098 | + "col": 0 | ||
1099 | + } | ||
1100 | + }, | ||
1101 | + "gridSettings": { | ||
1102 | + "backgroundColor": "#eeeeee", | ||
1103 | + "color": "rgba(0,0,0,0.870588)", | ||
1104 | + "columns": 24, | ||
1105 | + "margins": [ | ||
1106 | + 10, | ||
1107 | + 10 | ||
1108 | + ], | ||
1109 | + "backgroundSizeMode": "100%", | ||
1110 | + "autoFillHeight": true, | ||
1111 | + "mobileAutoFillHeight": false, | ||
1112 | + "mobileRowHeight": 70 | ||
1113 | + } | ||
1114 | + } | ||
1115 | + } | ||
1116 | + }, | ||
1117 | + "__entityname__config": { | ||
1118 | + "name": "${entityName} Configuration", | ||
1119 | + "root": false, | ||
1120 | + "layouts": { | ||
1121 | + "main": { | ||
1122 | + "widgets": { | ||
1123 | + "eadabbc7-519e-76fc-ba10-b3fe8c18da10": { | ||
1124 | + "sizeX": 14, | ||
1125 | + "sizeY": 13, | ||
1126 | + "row": 0, | ||
1127 | + "col": 10 | ||
1128 | + }, | ||
1129 | + "8fc32225-164f-3258-73f7-e6b6d959cf0b": { | ||
1130 | + "sizeX": 10, | ||
1131 | + "sizeY": 9, | ||
1132 | + "row": 0, | ||
1133 | + "col": 0 | ||
1134 | + }, | ||
1135 | + "063fc179-c9fd-f952-e714-f24e9c43c05c": { | ||
1136 | + "sizeX": 4, | ||
1137 | + "sizeY": 2, | ||
1138 | + "row": 9, | ||
1139 | + "col": 0 | ||
1140 | + }, | ||
1141 | + "3c2134cc-27a0-93e1-dbe1-2fa7c1ce16b7": { | ||
1142 | + "sizeX": 4, | ||
1143 | + "sizeY": 2, | ||
1144 | + "row": 11, | ||
1145 | + "col": 0 | ||
1146 | + }, | ||
1147 | + "6770b6ba-eff8-df05-75f8-c1f9326d4842": { | ||
1148 | + "sizeX": 6, | ||
1149 | + "sizeY": 4, | ||
1150 | + "row": 9, | ||
1151 | + "col": 4 | ||
1152 | + } | ||
1153 | + }, | ||
1154 | + "gridSettings": { | ||
1155 | + "backgroundColor": "#eeeeee", | ||
1156 | + "color": "rgba(0,0,0,0.870588)", | ||
1157 | + "columns": 24, | ||
1158 | + "margins": [ | ||
1159 | + 10, | ||
1160 | + 10 | ||
1161 | + ], | ||
1162 | + "backgroundSizeMode": "100%", | ||
1163 | + "autoFillHeight": true, | ||
1164 | + "mobileAutoFillHeight": false, | ||
1165 | + "mobileRowHeight": 70 | ||
1166 | + } | ||
1167 | + } | ||
1168 | + } | ||
1169 | + }, | ||
1170 | + "__entityname_grafic": { | ||
1171 | + "name": "${entityName} Details", | ||
1172 | + "root": false, | ||
1173 | + "layouts": { | ||
1174 | + "main": { | ||
1175 | + "widgets": { | ||
1176 | + "f928afc4-30d1-8d0c-e3cf-777f9f9d1155": { | ||
1177 | + "sizeX": 17, | ||
1178 | + "sizeY": 4, | ||
1179 | + "mobileHeight": null, | ||
1180 | + "row": 4, | ||
1181 | + "col": 7 | ||
1182 | + }, | ||
1183 | + "2a95b473-042d-59d0-2da2-40d0cccb6c8a": { | ||
1184 | + "sizeX": 7, | ||
1185 | + "sizeY": 7, | ||
1186 | + "row": 5, | ||
1187 | + "col": 0 | ||
1188 | + }, | ||
1189 | + "aaa69366-aacc-9028-65aa-645c0f8533ec": { | ||
1190 | + "sizeX": 17, | ||
1191 | + "sizeY": 4, | ||
1192 | + "mobileHeight": null, | ||
1193 | + "row": 0, | ||
1194 | + "col": 7 | ||
1195 | + }, | ||
1196 | + "ce5c7d01-a3ef-5cf0-4578-8505135c23a0": { | ||
1197 | + "sizeX": 17, | ||
1198 | + "sizeY": 4, | ||
1199 | + "mobileHeight": null, | ||
1200 | + "row": 8, | ||
1201 | + "col": 7 | ||
1202 | + }, | ||
1203 | + "466f046d-6005-a168-b107-60fcb2469cd5": { | ||
1204 | + "sizeX": 7, | ||
1205 | + "sizeY": 5, | ||
1206 | + "row": 0, | ||
1207 | + "col": 0 | ||
1208 | + } | ||
1209 | + }, | ||
1210 | + "gridSettings": { | ||
1211 | + "backgroundColor": "#eeeeee", | ||
1212 | + "color": "rgba(0,0,0,0.870588)", | ||
1213 | + "columns": 24, | ||
1214 | + "margins": [ | ||
1215 | + 10, | ||
1216 | + 10 | ||
1217 | + ], | ||
1218 | + "backgroundSizeMode": "auto 100%", | ||
1219 | + "autoFillHeight": true, | ||
1220 | + "mobileAutoFillHeight": true, | ||
1221 | + "mobileRowHeight": 70 | ||
1222 | + } | ||
1223 | + } | ||
1224 | + } | ||
1225 | + } | ||
1226 | + }, | ||
1227 | + "entityAliases": { | ||
1228 | + "3e0f533a-0db1-3292-184f-06e73535061a": { | ||
1229 | + "id": "3e0f533a-0db1-3292-184f-06e73535061a", | ||
1230 | + "alias": "Gateways", | ||
1231 | + "filter": { | ||
1232 | + "type": "deviceType", | ||
1233 | + "resolveMultiple": true, | ||
1234 | + "deviceType": "gateway", | ||
1235 | + "deviceNameFilter": "" | ||
1236 | + } | ||
1237 | + }, | ||
1238 | + "b2487e75-2fa4-f211-142c-434dfd50c70c": { | ||
1239 | + "id": "b2487e75-2fa4-f211-142c-434dfd50c70c", | ||
1240 | + "alias": "Current Gateway", | ||
1241 | + "filter": { | ||
1242 | + "type": "stateEntity", | ||
1243 | + "resolveMultiple": false, | ||
1244 | + "stateEntityParamName": "", | ||
1245 | + "defaultStateEntity": null | ||
1246 | + } | ||
1247 | + } | ||
1248 | + }, | ||
1249 | + "timewindow": { | ||
1250 | + "realtime": { | ||
1251 | + "interval": 1000, | ||
1252 | + "timewindowMs": 86400000 | ||
1253 | + }, | ||
1254 | + "aggregation": { | ||
1255 | + "type": "NONE", | ||
1256 | + "limit": 25000 | ||
1257 | + }, | ||
1258 | + "hideInterval": false, | ||
1259 | + "hideAggregation": false, | ||
1260 | + "hideAggInterval": false | ||
1261 | + }, | ||
1262 | + "settings": { | ||
1263 | + "stateControllerId": "entity", | ||
1264 | + "showTitle": true, | ||
1265 | + "showDashboardsSelect": true, | ||
1266 | + "showEntitiesSelect": true, | ||
1267 | + "showDashboardTimewindow": true, | ||
1268 | + "showDashboardExport": true, | ||
1269 | + "toolbarAlwaysOpen": true, | ||
1270 | + "titleColor": "rgba(0,0,0,0.870588)" | ||
1271 | + } | ||
1272 | + }, | ||
1273 | + "name": "Gateways" | ||
1274 | +} |
1 | +{ | ||
2 | + "title": "Rule Engine Statistics", | ||
3 | + "configuration": { | ||
4 | + "widgets": { | ||
5 | + "81987f19-3eac-e4ce-b790-d96e9b54d9a0": { | ||
6 | + "isSystemType": true, | ||
7 | + "bundleAlias": "charts", | ||
8 | + "typeAlias": "basic_timeseries", | ||
9 | + "type": "timeseries", | ||
10 | + "title": "New widget", | ||
11 | + "sizeX": 12, | ||
12 | + "sizeY": 7, | ||
13 | + "config": { | ||
14 | + "datasources": [ | ||
15 | + { | ||
16 | + "type": "entity", | ||
17 | + "dataKeys": [ | ||
18 | + { | ||
19 | + "name": "successfulMsgs", | ||
20 | + "type": "timeseries", | ||
21 | + "label": "${entityName} Successful", | ||
22 | + "color": "#4caf50", | ||
23 | + "settings": { | ||
24 | + "excludeFromStacking": false, | ||
25 | + "hideDataByDefault": false, | ||
26 | + "disableDataHiding": false, | ||
27 | + "removeFromLegend": false, | ||
28 | + "showLines": true, | ||
29 | + "fillLines": false, | ||
30 | + "showPoints": false, | ||
31 | + "showPointShape": "circle", | ||
32 | + "pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", | ||
33 | + "showPointsLineWidth": 5, | ||
34 | + "showPointsRadius": 3, | ||
35 | + "showSeparateAxis": false, | ||
36 | + "axisPosition": "left", | ||
37 | + "thresholds": [ | ||
38 | + { | ||
39 | + "thresholdValueSource": "predefinedValue" | ||
40 | + } | ||
41 | + ], | ||
42 | + "comparisonSettings": { | ||
43 | + "showValuesForComparison": true | ||
44 | + } | ||
45 | + }, | ||
46 | + "_hash": 0.15490750967648736 | ||
47 | + }, | ||
48 | + { | ||
49 | + "name": "failedMsgs", | ||
50 | + "type": "timeseries", | ||
51 | + "label": "${entityName} Permanent Failures", | ||
52 | + "color": "#ef5350", | ||
53 | + "settings": { | ||
54 | + "excludeFromStacking": false, | ||
55 | + "hideDataByDefault": false, | ||
56 | + "disableDataHiding": false, | ||
57 | + "removeFromLegend": false, | ||
58 | + "showLines": true, | ||
59 | + "fillLines": false, | ||
60 | + "showPoints": false, | ||
61 | + "showPointShape": "circle", | ||
62 | + "pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", | ||
63 | + "showPointsLineWidth": 5, | ||
64 | + "showPointsRadius": 3, | ||
65 | + "showSeparateAxis": false, | ||
66 | + "axisPosition": "left", | ||
67 | + "thresholds": [ | ||
68 | + { | ||
69 | + "thresholdValueSource": "predefinedValue" | ||
70 | + } | ||
71 | + ], | ||
72 | + "comparisonSettings": { | ||
73 | + "showValuesForComparison": true | ||
74 | + } | ||
75 | + }, | ||
76 | + "_hash": 0.4186621166514697 | ||
77 | + }, | ||
78 | + { | ||
79 | + "name": "tmpFailed", | ||
80 | + "type": "timeseries", | ||
81 | + "label": "${entityName} Processing Failures", | ||
82 | + "color": "#ffc107", | ||
83 | + "settings": { | ||
84 | + "excludeFromStacking": false, | ||
85 | + "hideDataByDefault": false, | ||
86 | + "disableDataHiding": false, | ||
87 | + "removeFromLegend": false, | ||
88 | + "showLines": true, | ||
89 | + "fillLines": false, | ||
90 | + "showPoints": false, | ||
91 | + "showPointShape": "circle", | ||
92 | + "pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", | ||
93 | + "showPointsLineWidth": 5, | ||
94 | + "showPointsRadius": 3, | ||
95 | + "showSeparateAxis": false, | ||
96 | + "axisPosition": "left", | ||
97 | + "thresholds": [ | ||
98 | + { | ||
99 | + "thresholdValueSource": "predefinedValue" | ||
100 | + } | ||
101 | + ], | ||
102 | + "comparisonSettings": { | ||
103 | + "showValuesForComparison": true | ||
104 | + } | ||
105 | + }, | ||
106 | + "_hash": 0.49891007198715376 | ||
107 | + } | ||
108 | + ], | ||
109 | + "entityAliasId": "140f23dd-e3a0-ed98-6189-03c49d2d8018" | ||
110 | + } | ||
111 | + ], | ||
112 | + "timewindow": { | ||
113 | + "realtime": { | ||
114 | + "interval": 1000, | ||
115 | + "timewindowMs": 300000 | ||
116 | + }, | ||
117 | + "aggregation": { | ||
118 | + "type": "NONE", | ||
119 | + "limit": 8640 | ||
120 | + }, | ||
121 | + "hideInterval": false, | ||
122 | + "hideAggregation": false, | ||
123 | + "hideAggInterval": false | ||
124 | + }, | ||
125 | + "showTitle": true, | ||
126 | + "backgroundColor": "#fff", | ||
127 | + "color": "rgba(0, 0, 0, 0.87)", | ||
128 | + "padding": "8px", | ||
129 | + "settings": { | ||
130 | + "shadowSize": 4, | ||
131 | + "fontColor": "#545454", | ||
132 | + "fontSize": 10, | ||
133 | + "xaxis": { | ||
134 | + "showLabels": true, | ||
135 | + "color": "#545454" | ||
136 | + }, | ||
137 | + "yaxis": { | ||
138 | + "showLabels": true, | ||
139 | + "color": "#545454" | ||
140 | + }, | ||
141 | + "grid": { | ||
142 | + "color": "#545454", | ||
143 | + "tickColor": "#DDDDDD", | ||
144 | + "verticalLines": true, | ||
145 | + "horizontalLines": true, | ||
146 | + "outlineWidth": 1 | ||
147 | + }, | ||
148 | + "stack": false, | ||
149 | + "tooltipIndividual": false, | ||
150 | + "timeForComparison": "months", | ||
151 | + "xaxisSecond": { | ||
152 | + "axisPosition": "top", | ||
153 | + "showLabels": true | ||
154 | + } | ||
155 | + }, | ||
156 | + "title": "Queue Stats", | ||
157 | + "dropShadow": true, | ||
158 | + "enableFullscreen": true, | ||
159 | + "titleStyle": { | ||
160 | + "fontSize": "16px", | ||
161 | + "fontWeight": 400 | ||
162 | + }, | ||
163 | + "mobileHeight": null, | ||
164 | + "showTitleIcon": false, | ||
165 | + "titleIcon": null, | ||
166 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
167 | + "iconSize": "24px", | ||
168 | + "titleTooltip": "", | ||
169 | + "widgetStyle": {}, | ||
170 | + "useDashboardTimewindow": false, | ||
171 | + "displayTimewindow": true, | ||
172 | + "showLegend": true, | ||
173 | + "actions": {}, | ||
174 | + "legendConfig": { | ||
175 | + "direction": "column", | ||
176 | + "position": "bottom", | ||
177 | + "showMin": true, | ||
178 | + "showMax": true, | ||
179 | + "showAvg": false, | ||
180 | + "showTotal": true | ||
181 | + } | ||
182 | + }, | ||
183 | + "id": "81987f19-3eac-e4ce-b790-d96e9b54d9a0" | ||
184 | + }, | ||
185 | + "5eb79712-5c24-3060-7e4f-6af36b8f842d": { | ||
186 | + "isSystemType": true, | ||
187 | + "bundleAlias": "cards", | ||
188 | + "typeAlias": "timeseries_table", | ||
189 | + "type": "timeseries", | ||
190 | + "title": "New widget", | ||
191 | + "sizeX": 24, | ||
192 | + "sizeY": 5, | ||
193 | + "config": { | ||
194 | + "datasources": [ | ||
195 | + { | ||
196 | + "type": "entity", | ||
197 | + "dataKeys": [ | ||
198 | + { | ||
199 | + "name": "ruleEngineException", | ||
200 | + "type": "timeseries", | ||
201 | + "label": "Rule Chain", | ||
202 | + "color": "#2196f3", | ||
203 | + "settings": { | ||
204 | + "useCellStyleFunction": false, | ||
205 | + "useCellContentFunction": true, | ||
206 | + "cellContentFunction": "return JSON.parse(value).ruleChainName;" | ||
207 | + }, | ||
208 | + "_hash": 0.9954481282345906 | ||
209 | + }, | ||
210 | + { | ||
211 | + "name": "ruleEngineException", | ||
212 | + "type": "timeseries", | ||
213 | + "label": "Rule Node", | ||
214 | + "color": "#4caf50", | ||
215 | + "settings": { | ||
216 | + "useCellStyleFunction": false, | ||
217 | + "useCellContentFunction": true, | ||
218 | + "cellContentFunction": "return JSON.parse(value).ruleNodeName;" | ||
219 | + }, | ||
220 | + "_hash": 0.18580357036589978 | ||
221 | + }, | ||
222 | + { | ||
223 | + "name": "ruleEngineException", | ||
224 | + "type": "timeseries", | ||
225 | + "label": "Latest Error", | ||
226 | + "color": "#f44336", | ||
227 | + "settings": { | ||
228 | + "useCellStyleFunction": false, | ||
229 | + "useCellContentFunction": true, | ||
230 | + "cellContentFunction": "return JSON.parse(value).message;" | ||
231 | + }, | ||
232 | + "_hash": 0.7255162989552142 | ||
233 | + } | ||
234 | + ], | ||
235 | + "entityAliasId": "140f23dd-e3a0-ed98-6189-03c49d2d8018" | ||
236 | + } | ||
237 | + ], | ||
238 | + "timewindow": { | ||
239 | + "realtime": { | ||
240 | + "interval": 1000, | ||
241 | + "timewindowMs": 86400000 | ||
242 | + }, | ||
243 | + "aggregation": { | ||
244 | + "type": "NONE", | ||
245 | + "limit": 200 | ||
246 | + } | ||
247 | + }, | ||
248 | + "showTitle": true, | ||
249 | + "backgroundColor": "rgb(255, 255, 255)", | ||
250 | + "color": "rgba(0, 0, 0, 0.87)", | ||
251 | + "padding": "8px", | ||
252 | + "settings": { | ||
253 | + "showTimestamp": true, | ||
254 | + "displayPagination": true, | ||
255 | + "defaultPageSize": 10 | ||
256 | + }, | ||
257 | + "title": "Exceptions", | ||
258 | + "dropShadow": true, | ||
259 | + "enableFullscreen": true, | ||
260 | + "titleStyle": { | ||
261 | + "fontSize": "16px", | ||
262 | + "fontWeight": 400 | ||
263 | + }, | ||
264 | + "useDashboardTimewindow": false, | ||
265 | + "showLegend": false, | ||
266 | + "widgetStyle": {}, | ||
267 | + "actions": {}, | ||
268 | + "showTitleIcon": false, | ||
269 | + "titleIcon": null, | ||
270 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
271 | + "iconSize": "24px", | ||
272 | + "titleTooltip": "", | ||
273 | + "displayTimewindow": true | ||
274 | + }, | ||
275 | + "id": "5eb79712-5c24-3060-7e4f-6af36b8f842d" | ||
276 | + }, | ||
277 | + "ad3f1417-87a8-750e-fc67-49a2de1466d4": { | ||
278 | + "isSystemType": true, | ||
279 | + "bundleAlias": "charts", | ||
280 | + "typeAlias": "basic_timeseries", | ||
281 | + "type": "timeseries", | ||
282 | + "title": "New widget", | ||
283 | + "sizeX": 12, | ||
284 | + "sizeY": 7, | ||
285 | + "config": { | ||
286 | + "datasources": [ | ||
287 | + { | ||
288 | + "type": "entity", | ||
289 | + "dataKeys": [ | ||
290 | + { | ||
291 | + "name": "timeoutMsgs", | ||
292 | + "type": "timeseries", | ||
293 | + "label": "${entityName} Permanent Timeouts", | ||
294 | + "color": "#4caf50", | ||
295 | + "settings": { | ||
296 | + "excludeFromStacking": false, | ||
297 | + "hideDataByDefault": false, | ||
298 | + "disableDataHiding": false, | ||
299 | + "removeFromLegend": false, | ||
300 | + "showLines": true, | ||
301 | + "fillLines": false, | ||
302 | + "showPoints": false, | ||
303 | + "showPointShape": "circle", | ||
304 | + "pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", | ||
305 | + "showPointsLineWidth": 5, | ||
306 | + "showPointsRadius": 3, | ||
307 | + "showSeparateAxis": false, | ||
308 | + "axisPosition": "left", | ||
309 | + "thresholds": [ | ||
310 | + { | ||
311 | + "thresholdValueSource": "predefinedValue" | ||
312 | + } | ||
313 | + ], | ||
314 | + "comparisonSettings": { | ||
315 | + "showValuesForComparison": true | ||
316 | + } | ||
317 | + }, | ||
318 | + "_hash": 0.565222981550328 | ||
319 | + }, | ||
320 | + { | ||
321 | + "name": "tmpTimeout", | ||
322 | + "type": "timeseries", | ||
323 | + "label": "${entityName} Processing Timeouts", | ||
324 | + "color": "#9c27b0", | ||
325 | + "settings": { | ||
326 | + "excludeFromStacking": false, | ||
327 | + "hideDataByDefault": false, | ||
328 | + "disableDataHiding": false, | ||
329 | + "removeFromLegend": false, | ||
330 | + "showLines": true, | ||
331 | + "fillLines": false, | ||
332 | + "showPoints": false, | ||
333 | + "showPointShape": "circle", | ||
334 | + "pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", | ||
335 | + "showPointsLineWidth": 5, | ||
336 | + "showPointsRadius": 3, | ||
337 | + "showSeparateAxis": false, | ||
338 | + "axisPosition": "left", | ||
339 | + "thresholds": [ | ||
340 | + { | ||
341 | + "thresholdValueSource": "predefinedValue" | ||
342 | + } | ||
343 | + ], | ||
344 | + "comparisonSettings": { | ||
345 | + "showValuesForComparison": true | ||
346 | + } | ||
347 | + }, | ||
348 | + "_hash": 0.2679547062508352 | ||
349 | + } | ||
350 | + ], | ||
351 | + "entityAliasId": "140f23dd-e3a0-ed98-6189-03c49d2d8018" | ||
352 | + } | ||
353 | + ], | ||
354 | + "timewindow": { | ||
355 | + "realtime": { | ||
356 | + "interval": 1000, | ||
357 | + "timewindowMs": 300000 | ||
358 | + }, | ||
359 | + "aggregation": { | ||
360 | + "type": "NONE", | ||
361 | + "limit": 8640 | ||
362 | + }, | ||
363 | + "hideInterval": false, | ||
364 | + "hideAggregation": false, | ||
365 | + "hideAggInterval": false | ||
366 | + }, | ||
367 | + "showTitle": true, | ||
368 | + "backgroundColor": "#fff", | ||
369 | + "color": "rgba(0, 0, 0, 0.87)", | ||
370 | + "padding": "8px", | ||
371 | + "settings": { | ||
372 | + "shadowSize": 4, | ||
373 | + "fontColor": "#545454", | ||
374 | + "fontSize": 10, | ||
375 | + "xaxis": { | ||
376 | + "showLabels": true, | ||
377 | + "color": "#545454" | ||
378 | + }, | ||
379 | + "yaxis": { | ||
380 | + "showLabels": true, | ||
381 | + "color": "#545454" | ||
382 | + }, | ||
383 | + "grid": { | ||
384 | + "color": "#545454", | ||
385 | + "tickColor": "#DDDDDD", | ||
386 | + "verticalLines": true, | ||
387 | + "horizontalLines": true, | ||
388 | + "outlineWidth": 1 | ||
389 | + }, | ||
390 | + "stack": false, | ||
391 | + "tooltipIndividual": false, | ||
392 | + "timeForComparison": "months", | ||
393 | + "xaxisSecond": { | ||
394 | + "axisPosition": "top", | ||
395 | + "showLabels": true | ||
396 | + } | ||
397 | + }, | ||
398 | + "title": "Processing Failures and Timeouts", | ||
399 | + "dropShadow": true, | ||
400 | + "enableFullscreen": true, | ||
401 | + "titleStyle": { | ||
402 | + "fontSize": "16px", | ||
403 | + "fontWeight": 400 | ||
404 | + }, | ||
405 | + "mobileHeight": null, | ||
406 | + "showTitleIcon": false, | ||
407 | + "titleIcon": null, | ||
408 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
409 | + "iconSize": "24px", | ||
410 | + "titleTooltip": "", | ||
411 | + "widgetStyle": {}, | ||
412 | + "useDashboardTimewindow": false, | ||
413 | + "displayTimewindow": true, | ||
414 | + "showLegend": true, | ||
415 | + "actions": {}, | ||
416 | + "legendConfig": { | ||
417 | + "direction": "column", | ||
418 | + "position": "bottom", | ||
419 | + "showMin": true, | ||
420 | + "showMax": true, | ||
421 | + "showAvg": false, | ||
422 | + "showTotal": true | ||
423 | + } | ||
424 | + }, | ||
425 | + "id": "ad3f1417-87a8-750e-fc67-49a2de1466d4" | ||
426 | + } | ||
427 | + }, | ||
428 | + "states": { | ||
429 | + "default": { | ||
430 | + "name": "Rule Engine Statistics", | ||
431 | + "root": true, | ||
432 | + "layouts": { | ||
433 | + "main": { | ||
434 | + "widgets": { | ||
435 | + "81987f19-3eac-e4ce-b790-d96e9b54d9a0": { | ||
436 | + "sizeX": 12, | ||
437 | + "sizeY": 7, | ||
438 | + "mobileHeight": null, | ||
439 | + "row": 0, | ||
440 | + "col": 0 | ||
441 | + }, | ||
442 | + "5eb79712-5c24-3060-7e4f-6af36b8f842d": { | ||
443 | + "sizeX": 24, | ||
444 | + "sizeY": 5, | ||
445 | + "row": 7, | ||
446 | + "col": 0 | ||
447 | + }, | ||
448 | + "ad3f1417-87a8-750e-fc67-49a2de1466d4": { | ||
449 | + "sizeX": 12, | ||
450 | + "sizeY": 7, | ||
451 | + "mobileHeight": null, | ||
452 | + "row": 0, | ||
453 | + "col": 12 | ||
454 | + } | ||
455 | + }, | ||
456 | + "gridSettings": { | ||
457 | + "backgroundColor": "#eeeeee", | ||
458 | + "color": "rgba(0,0,0,0.870588)", | ||
459 | + "columns": 24, | ||
460 | + "margins": [ | ||
461 | + 10, | ||
462 | + 10 | ||
463 | + ], | ||
464 | + "backgroundSizeMode": "100%", | ||
465 | + "autoFillHeight": true, | ||
466 | + "mobileAutoFillHeight": false, | ||
467 | + "mobileRowHeight": 70 | ||
468 | + } | ||
469 | + } | ||
470 | + } | ||
471 | + } | ||
472 | + }, | ||
473 | + "entityAliases": { | ||
474 | + "140f23dd-e3a0-ed98-6189-03c49d2d8018": { | ||
475 | + "id": "140f23dd-e3a0-ed98-6189-03c49d2d8018", | ||
476 | + "alias": "TbServiceQueues", | ||
477 | + "filter": { | ||
478 | + "type": "assetType", | ||
479 | + "resolveMultiple": true, | ||
480 | + "assetType": "TbServiceQueue", | ||
481 | + "assetNameFilter": "" | ||
482 | + } | ||
483 | + } | ||
484 | + }, | ||
485 | + "timewindow": { | ||
486 | + "displayValue": "", | ||
487 | + "selectedTab": 0, | ||
488 | + "hideInterval": false, | ||
489 | + "hideAggregation": false, | ||
490 | + "hideAggInterval": false, | ||
491 | + "realtime": { | ||
492 | + "interval": 1000, | ||
493 | + "timewindowMs": 60000 | ||
494 | + }, | ||
495 | + "history": { | ||
496 | + "historyType": 0, | ||
497 | + "interval": 1000, | ||
498 | + "timewindowMs": 60000, | ||
499 | + "fixedTimewindow": { | ||
500 | + "startTimeMs": 1586176634823, | ||
501 | + "endTimeMs": 1586263034823 | ||
502 | + } | ||
503 | + }, | ||
504 | + "aggregation": { | ||
505 | + "type": "AVG", | ||
506 | + "limit": 25000 | ||
507 | + } | ||
508 | + }, | ||
509 | + "settings": { | ||
510 | + "stateControllerId": "entity", | ||
511 | + "showTitle": false, | ||
512 | + "showDashboardsSelect": true, | ||
513 | + "showEntitiesSelect": true, | ||
514 | + "showDashboardTimewindow": true, | ||
515 | + "showDashboardExport": true, | ||
516 | + "toolbarAlwaysOpen": true | ||
517 | + } | ||
518 | + }, | ||
519 | + "name": "Rule Engine Statistics" | ||
520 | +} |
1 | +{ | ||
2 | + "title": "Thermostats", | ||
3 | + "configuration": { | ||
4 | + "widgets": { | ||
5 | + "f33c746c-0dfc-c212-395b-b448c8a17209": { | ||
6 | + "isSystemType": true, | ||
7 | + "bundleAlias": "cards", | ||
8 | + "typeAlias": "entities_table", | ||
9 | + "type": "latest", | ||
10 | + "title": "New widget", | ||
11 | + "sizeX": 11, | ||
12 | + "sizeY": 11, | ||
13 | + "config": { | ||
14 | + "timewindow": { | ||
15 | + "realtime": { | ||
16 | + "interval": 1000, | ||
17 | + "timewindowMs": 86400000 | ||
18 | + }, | ||
19 | + "aggregation": { | ||
20 | + "type": "NONE", | ||
21 | + "limit": 200 | ||
22 | + } | ||
23 | + }, | ||
24 | + "showTitle": true, | ||
25 | + "backgroundColor": "rgb(255, 255, 255)", | ||
26 | + "color": "rgba(0, 0, 0, 0.87)", | ||
27 | + "padding": "4px", | ||
28 | + "settings": { | ||
29 | + "enableSearch": true, | ||
30 | + "displayPagination": true, | ||
31 | + "defaultPageSize": 10, | ||
32 | + "defaultSortOrder": "entityName", | ||
33 | + "displayEntityName": true, | ||
34 | + "displayEntityType": false, | ||
35 | + "enableSelectColumnDisplay": false, | ||
36 | + "entitiesTitle": "Thermostats", | ||
37 | + "displayEntityLabel": false, | ||
38 | + "entityNameColumnTitle": "Thermostat name" | ||
39 | + }, | ||
40 | + "title": "Thermostats", | ||
41 | + "dropShadow": true, | ||
42 | + "enableFullscreen": false, | ||
43 | + "titleStyle": { | ||
44 | + "fontSize": "16px", | ||
45 | + "fontWeight": 400, | ||
46 | + "padding": "5px 10px 5px 10px" | ||
47 | + }, | ||
48 | + "useDashboardTimewindow": false, | ||
49 | + "showLegend": false, | ||
50 | + "datasources": [ | ||
51 | + { | ||
52 | + "type": "entity", | ||
53 | + "dataKeys": [ | ||
54 | + { | ||
55 | + "name": "active", | ||
56 | + "type": "attribute", | ||
57 | + "label": "Active", | ||
58 | + "color": "#2196f3", | ||
59 | + "settings": { | ||
60 | + "columnWidth": "0px", | ||
61 | + "useCellStyleFunction": true, | ||
62 | + "useCellContentFunction": true, | ||
63 | + "cellContentFunction": "value = '⬤';\nreturn value;", | ||
64 | + "cellStyleFunction": "var color;\nif (value === \"true\") {\n color = 'rgb(39, 134, 34)';\n} else {\n color = 'rgb(255, 0, 0)';\n}\nreturn {\n color: color,\n fontSize: '18px'\n};" | ||
65 | + }, | ||
66 | + "_hash": 0.9264526512320641 | ||
67 | + }, | ||
68 | + { | ||
69 | + "name": "temperature", | ||
70 | + "type": "timeseries", | ||
71 | + "label": "Temperature", | ||
72 | + "color": "#4caf50", | ||
73 | + "settings": { | ||
74 | + "columnWidth": "0px", | ||
75 | + "useCellStyleFunction": false, | ||
76 | + "useCellContentFunction": false | ||
77 | + }, | ||
78 | + "_hash": 0.9801965063904188, | ||
79 | + "units": "°C", | ||
80 | + "decimals": 1 | ||
81 | + }, | ||
82 | + { | ||
83 | + "name": "humidity", | ||
84 | + "type": "timeseries", | ||
85 | + "label": "Humidity", | ||
86 | + "color": "#f44336", | ||
87 | + "settings": { | ||
88 | + "columnWidth": "0px", | ||
89 | + "useCellStyleFunction": false, | ||
90 | + "useCellContentFunction": false | ||
91 | + }, | ||
92 | + "_hash": 0.5726727868178358, | ||
93 | + "units": "%", | ||
94 | + "decimals": 0 | ||
95 | + } | ||
96 | + ], | ||
97 | + "entityAliasId": "68a058e1-fdda-8482-715b-3ae4a488568e" | ||
98 | + } | ||
99 | + ], | ||
100 | + "showTitleIcon": false, | ||
101 | + "titleIcon": null, | ||
102 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
103 | + "iconSize": "24px", | ||
104 | + "titleTooltip": "", | ||
105 | + "widgetStyle": {}, | ||
106 | + "displayTimewindow": true, | ||
107 | + "actions": { | ||
108 | + "headerButton": [ | ||
109 | + { | ||
110 | + "id": "85b803db-90f2-5c63-1388-a378e0eb10d6", | ||
111 | + "name": "Edit location", | ||
112 | + "icon": "map", | ||
113 | + "type": "openDashboardState", | ||
114 | + "targetDashboardStateId": "map", | ||
115 | + "setEntityId": false | ||
116 | + }, | ||
117 | + { | ||
118 | + "id": "8ab5a518-67d2-b6a2-956d-81fd512294b2", | ||
119 | + "name": "Add", | ||
120 | + "icon": "add", | ||
121 | + "type": "customPretty", | ||
122 | + "customHtml": "<md-dialog aria-label=\"Add entity\">\n <form name=\"addEntityForm\" class=\"add-entity-form\" ng-submit=\"vm.save()\">\n <md-toolbar>\n <div class=\"md-toolbar-tools\">\n <h2>Add thermostat</h2>\n <span flex></span>\n <md-button class=\"md-icon-button\" ng-click=\"vm.cancel()\">\n <ng-md-icon icon=\"close\" aria-label=\"Close\"></ng-md-icon>\n </md-button>\n </div>\n </md-toolbar>\n <md-dialog-content>\n <div class=\"md-dialog-content\">\n <md-input-container flex class=\"md-block\">\n <label>Thermostat name</label>\n <input ng-model=\"vm.entityName\" name=entityName required>\n <div ng-messages=\"addEntityForm.entityName.$error\">\n <div ng-message=\"required\">Thermostat name is required.</div>\n </div>\n </md-input-container>\n <md-switch ng-model=\"vm.attributes.alarmTemperature\">\n High temperature alarm\n </md-switch>\n <md-input-container flex class=\"md-block\">\n <label>High temperature threshold, °C</label>\n <input name=\"thresholdTemperature\" type=\"number\" step=\"any\" \n ng-model=\"vm.attributes.thresholdTemperature\"\n ng-disabled=\"!vm.attributes.alarmTemperature\"\n ng-required=\"vm.attributes.alarmTemperature\">\n <div ng-messages=\"addEntityForm.thresholdTemperature.$error\">\n <div ng-message=\"required\">High temperature threshold is required.</div>\n </div>\n </md-input-container>\n <md-switch ng-model=\"vm.attributes.alarmHumidity\">\n Low humidity alarm\n </md-switch>\n <md-input-container flex class=\"md-block\">\n <label>Low humidity threshold, %</label>\n <input name=\"thresholdHumidity\" type=\"number\" step=\"any\" \n ng-model=\"vm.attributes.thresholdHumidity\"\n ng-disabled=\"!vm.attributes.alarmHumidity\"\n ng-required=\"vm.attributes.alarmHumidity\">\n <div ng-messages=\"addEntityForm.thresholdHumidity.$error\">\n <div ng-message=\"required\">Low humidity threshold is required.</div>\n </div>\n </md-input-container>\n </div>\n </md-dialog-content>\n <md-dialog-actions>\n <md-button type=\"submit\" ng-disabled=\"addEntityForm.$invalid || !addEntityForm.$dirty\" class=\"md-raised md-primary\">Create</md-button>\n <md-button ng-click=\"vm.cancel()\" class=\"md-primary\">Cancel</md-button>\n </md-dialog-actions>\n </form>\n</md-dialog>", | ||
123 | + "customCss": ".add-entity-form md-input-container {\n padding-right: 10px;\n}\n\n.add-entity-form .boolean-value-input {\n padding-left: 5px;\n}\n\n.add-entity-form .boolean-value-input .checkbox-label {\n margin-bottom: 8px;\n color: rgba(0,0,0,0.54);\n font-size: 12px;\n}\n\n", | ||
124 | + "customFunction": "var $injector = widgetContext.$scope.$injector;\nvar $mdDialog = $injector.get('$mdDialog'),\n $document = $injector.get('$document'),\n $q = $injector.get('$q'),\n $rootScope = $injector.get('$rootScope'),\n deviceService = $injector.get('deviceService'),\n attributeService = $injector.get('attributeService');\n\nopenAddEntityDialog();\n\nfunction openAddEntityDialog() {\n $mdDialog.show({\n controller: ['$scope','$mdDialog', AddEntityDialogController],\n controllerAs: 'vm',\n template: htmlTemplate,\n locals: {\n entityId: entityId\n },\n parent: angular.element($document[0].body),\n targetEvent: $event,\n multiple: true,\n clickOutsideToClose: false\n });\n}\n\nfunction AddEntityDialogController($scope, $mdDialog) {\n var vm = this;\n vm.attributes = {};\n\n vm.save = function() {\n $scope.addEntityForm.$setPristine();\n saveEntityPromise().then(\n function (entity) {\n saveAttributes(entity.id).then(() => {\n updateAliasData();\n $mdDialog.hide();\n });\n }\n );\n };\n vm.cancel = function() {\n $mdDialog.hide();\n };\n \n \n function saveEntityPromise() {\n var entity = {\n name: vm.entityName,\n type: \"thermostat\"\n };\n return deviceService.saveDevice(entity);\n }\n \n function saveAttributes(entityId) {\n var attributesArray = [];\n for (var key in vm.attributes) {\n attributesArray.push({key: key, value: vm.attributes[key]});\n }\n if (attributesArray.length > 0) {\n return attributeService.saveEntityAttributes(entityId.entityType, entityId.id, \"SERVER_SCOPE\", attributesArray);\n } else {\n return $q.when(null);\n } \n }\n \n function updateAliasData() {\n var aliasIds = [];\n for (var id in widgetContext.aliasController.resolvedAliases) {\n aliasIds.push(id);\n }\n var tasks = [];\n aliasIds.forEach(function(aliasId) {\n widgetContext.aliasController.setAliasUnresolved(aliasId);\n tasks.push(widgetContext.aliasController.getAliasInfo(aliasId));\n });\n $q.all(tasks).then(function() {\n $rootScope.$broadcast('widgetForceReInit');\n });\n }\n}" | ||
125 | + } | ||
126 | + ], | ||
127 | + "actionCellButton": [ | ||
128 | + { | ||
129 | + "id": "ca241cd8-788d-5508-a9ce-74b03ef42a7f", | ||
130 | + "name": "Chart", | ||
131 | + "icon": "show_chart", | ||
132 | + "type": "openDashboardState", | ||
133 | + "targetDashboardStateId": "chart", | ||
134 | + "setEntityId": true | ||
135 | + }, | ||
136 | + { | ||
137 | + "id": "7506576f-87ba-d3a0-88fb-e304d451776d", | ||
138 | + "name": "Edit", | ||
139 | + "icon": "edit", | ||
140 | + "type": "customPretty", | ||
141 | + "customHtml": "<md-dialog aria-label=\"Edit entity\">\n <form name=\"editEntityForm\" class=\"edit-entity-form\" ng-submit=\"vm.save()\">\n <md-toolbar>\n <div class=\"md-toolbar-tools\">\n <h2>Edit thermostat {{vm.entityName}}</h2>\n <span flex></span>\n <md-button class=\"md-icon-button\" ng-click=\"vm.cancel()\">\n <ng-md-icon icon=\"close\" aria-label=\"Close\"></ng-md-icon>\n </md-button>\n </div>\n </md-toolbar>\n <md-dialog-content>\n <div class=\"md-dialog-content\">\n <md-input-container flex class=\"md-block\">\n <label>Thermostat name</label>\n <input ng-model=\"vm.entityName\" readonly>\n </md-input-container>\n <md-switch ng-model=\"vm.attributes.alarmTemperature\">\n High temperature alarm\n </md-switch>\n <md-input-container flex class=\"md-block\">\n <label>High temperature threshold, °C</label>\n <input name=\"thresholdTemperature\" type=\"number\" step=\"any\" \n ng-model=\"vm.attributes.thresholdTemperature\"\n ng-disabled=\"!vm.attributes.alarmTemperature\"\n ng-required=\"vm.attributes.alarmTemperature\">\n <div ng-messages=\"editEntityForm.thresholdTemperature.$error\">\n <div ng-message=\"required\">High temperature threshold is required.</div>\n </div>\n </md-input-container>\n <md-switch ng-model=\"vm.attributes.alarmHumidity\">\n Low humidity alarm\n </md-switch>\n <md-input-container flex class=\"md-block\">\n <label>Low humidity threshold, %</label>\n <input name=\"thresholdHumidity\" type=\"number\" step=\"any\" \n ng-model=\"vm.attributes.thresholdHumidity\"\n ng-disabled=\"!vm.attributes.alarmHumidity\"\n ng-required=\"vm.attributes.alarmHumidity\">\n <div ng-messages=\"editEntityForm.thresholdHumidity.$error\">\n <div ng-message=\"required\">Low humidity threshold is required.</div>\n </div>\n </md-input-container>\n </div>\n </md-dialog-content>\n <md-dialog-actions>\n <md-button type=\"submit\" ng-disabled=\"editEntityForm.$invalid || !editEntityForm.$dirty\" class=\"md-raised md-primary\">Save</md-button>\n <md-button ng-click=\"vm.cancel()\" class=\"md-primary\">Cancel</md-button>\n </md-dialog-actions>\n </form>\n</md-dialog>", | ||
142 | + "customCss": ".edit-entity-form md-input-container {\n padding-right: 10px;\n}\n\n.edit-entity-form .boolean-value-input {\n padding-left: 5px;\n}\n\n.edit-entity-form .boolean-value-input .checkbox-label {\n margin-bottom: 8px;\n color: rgba(0,0,0,0.54);\n font-size: 12px;\n}\n", | ||
143 | + "customFunction": "var $injector = widgetContext.$scope.$injector;\nvar $mdDialog = $injector.get('$mdDialog'),\n $document = $injector.get('$document'),\n attributeService = $injector.get('attributeService');\n\nopenEditEntityDialog();\n\nfunction openEditEntityDialog() {\n $mdDialog.show({\n controller: ['$scope','$mdDialog', EditEntityDialogController],\n controllerAs: 'vm',\n template: htmlTemplate,\n locals: {\n entityId: entityId\n },\n parent: angular.element($document[0].body),\n targetEvent: $event,\n multiple: true,\n clickOutsideToClose: false\n });\n}\n\nfunction EditEntityDialogController($scope,$mdDialog) {\n var vm = this;\n vm.entityId = entityId;\n vm.entityName = entityName;\n vm.entityType = entityId.entityType;\n vm.attributes = {};\n vm.serverAttributes = {};\n getEntityInfo();\n \n vm.save = function() {\n saveAttributes();\n $mdDialog.hide();\n };\n vm.cancel = function() {\n $mdDialog.hide();\n };\n \n function getEntityAttributes(attributes) {\n for (var i = 0; i < attributes.length; i++) {\n vm.attributes[attributes[i].key] = attributes[i].value; \n }\n vm.serverAttributes = angular.copy(vm.attributes);\n }\n \n function getEntityInfo() {\n attributeService.getEntityAttributesValues(entityId.entityType, entityId.id, 'SERVER_SCOPE').then(\n function(data){\n if (data.length) {\n getEntityAttributes(data);\n }\n });\n }\n \n function saveAttributes() {\n var attributesArray = [];\n for (var key in vm.attributes) {\n if (vm.attributes[key] !== vm.serverAttributes[key]) {\n attributesArray.push({key: key, value: vm.attributes[key]});\n }\n }\n if (attributesArray.length > 0) {\n attributeService.saveEntityAttributes(entityId.entityType, entityId.id, \"SERVER_SCOPE\", attributesArray);\n } \n }\n}" | ||
144 | + }, | ||
145 | + { | ||
146 | + "id": "3488848b-e47d-6af6-659f-5d78369ece5e", | ||
147 | + "name": "Delete", | ||
148 | + "icon": "delete", | ||
149 | + "type": "custom", | ||
150 | + "customFunction": "var $injector = widgetContext.$scope.$injector;\nvar $mdDialog = $injector.get('$mdDialog'),\n $document = $injector.get('$document'),\n deviceService = $injector.get('deviceService')\n $rootScope = $injector.get('$rootScope'),\n $q = $injector.get('$q');\n\nopenDeleteEntityDialog();\n\nfunction openDeleteEntityDialog() {\n var title = 'Delete thermostat \"' + entityName + '\"';\n var content = 'Are you sure you want to delete the thermostat \"' +\n entityName + '\"?';\n var confirm = $mdDialog.confirm()\n .targetEvent($event)\n .title(title)\n .htmlContent(content)\n .ariaLabel(title)\n .cancel('Cancel')\n .ok('Delete');\n $mdDialog.show(confirm).then(function() {\n deleteEntity();\n })\n}\n\nfunction deleteEntity() {\n deviceService.deleteDevice(entityId.id).then(\n function success() {\n updateAliasData();\n },\n function fail() {\n showErrorDialog();\n }\n );\n}\n\nfunction updateAliasData() {\n var aliasIds = [];\n for (var id in widgetContext.aliasController.resolvedAliases) {\n aliasIds.push(id);\n }\n var tasks = [];\n aliasIds.forEach(function(aliasId) {\n widgetContext.aliasController.setAliasUnresolved(aliasId);\n tasks.push(widgetContext.aliasController.getAliasInfo(aliasId));\n });\n $q.all(tasks).then(function() {\n $rootScope.$broadcast('entityAliasesChanged', aliasIds);\n });\n}\n\nfunction showErrorDialog() {\n var title = 'Error';\n var content = 'An error occurred while deleting the thermostat. Please try again.';\n var alert = $mdDialog.alert()\n .title(title)\n .htmlContent(content)\n .ariaLabel(title)\n .parent(angular.element($document[0].body))\n .targetEvent($event)\n .multiple(true)\n .clickOutsideToClose(true)\n .ok('CLOSE');\n $mdDialog.show(alert);\n}" | ||
151 | + } | ||
152 | + ], | ||
153 | + "rowClick": [] | ||
154 | + } | ||
155 | + }, | ||
156 | + "id": "f33c746c-0dfc-c212-395b-b448c8a17209" | ||
157 | + }, | ||
158 | + "7943196b-eedb-d422-f9c3-b32d379ad172": { | ||
159 | + "isSystemType": true, | ||
160 | + "bundleAlias": "alarm_widgets", | ||
161 | + "typeAlias": "alarms_table", | ||
162 | + "type": "alarm", | ||
163 | + "title": "New widget", | ||
164 | + "sizeX": 13, | ||
165 | + "sizeY": 5, | ||
166 | + "config": { | ||
167 | + "timewindow": { | ||
168 | + "realtime": { | ||
169 | + "interval": 1000, | ||
170 | + "timewindowMs": 86400000 | ||
171 | + }, | ||
172 | + "aggregation": { | ||
173 | + "type": "NONE", | ||
174 | + "limit": 200 | ||
175 | + } | ||
176 | + }, | ||
177 | + "showTitle": true, | ||
178 | + "backgroundColor": "rgb(255, 255, 255)", | ||
179 | + "color": "rgba(0, 0, 0, 0.87)", | ||
180 | + "padding": "4px", | ||
181 | + "settings": { | ||
182 | + "enableSelection": true, | ||
183 | + "enableSearch": true, | ||
184 | + "displayDetails": true, | ||
185 | + "allowAcknowledgment": true, | ||
186 | + "allowClear": true, | ||
187 | + "displayPagination": true, | ||
188 | + "defaultPageSize": 10, | ||
189 | + "defaultSortOrder": "-createdTime", | ||
190 | + "enableSelectColumnDisplay": false, | ||
191 | + "enableStatusFilter": true, | ||
192 | + "alarmsTitle": "Alarms" | ||
193 | + }, | ||
194 | + "title": "New Alarms table", | ||
195 | + "dropShadow": true, | ||
196 | + "enableFullscreen": false, | ||
197 | + "titleStyle": { | ||
198 | + "fontSize": "16px", | ||
199 | + "fontWeight": 400, | ||
200 | + "padding": "5px 10px 5px 10px" | ||
201 | + }, | ||
202 | + "useDashboardTimewindow": false, | ||
203 | + "showLegend": false, | ||
204 | + "alarmSource": { | ||
205 | + "type": "entity", | ||
206 | + "dataKeys": [ | ||
207 | + { | ||
208 | + "name": "createdTime", | ||
209 | + "type": "alarm", | ||
210 | + "label": "Created time", | ||
211 | + "color": "#2196f3", | ||
212 | + "settings": {}, | ||
213 | + "_hash": 0.7308410188824108 | ||
214 | + }, | ||
215 | + { | ||
216 | + "name": "originator", | ||
217 | + "type": "alarm", | ||
218 | + "label": "Originator", | ||
219 | + "color": "#4caf50", | ||
220 | + "settings": {}, | ||
221 | + "_hash": 0.056085530105439485 | ||
222 | + }, | ||
223 | + { | ||
224 | + "name": "type", | ||
225 | + "type": "alarm", | ||
226 | + "label": "Type", | ||
227 | + "color": "#f44336", | ||
228 | + "settings": {}, | ||
229 | + "_hash": 0.10212012352561795 | ||
230 | + }, | ||
231 | + { | ||
232 | + "name": "severity", | ||
233 | + "type": "alarm", | ||
234 | + "label": "Severity", | ||
235 | + "color": "#ffc107", | ||
236 | + "settings": {}, | ||
237 | + "_hash": 0.1777349980531262 | ||
238 | + }, | ||
239 | + { | ||
240 | + "name": "status", | ||
241 | + "type": "alarm", | ||
242 | + "label": "Status", | ||
243 | + "color": "#607d8b", | ||
244 | + "settings": {}, | ||
245 | + "_hash": 0.7977920750136249 | ||
246 | + } | ||
247 | + ], | ||
248 | + "entityAliasId": "ce27a9d0-93bf-b7a4-054d-d0369a8cf813", | ||
249 | + "name": "alarms" | ||
250 | + }, | ||
251 | + "alarmSearchStatus": "ANY", | ||
252 | + "alarmsPollingInterval": 5, | ||
253 | + "showTitleIcon": false, | ||
254 | + "titleIcon": null, | ||
255 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
256 | + "iconSize": "24px", | ||
257 | + "titleTooltip": "", | ||
258 | + "widgetStyle": {}, | ||
259 | + "displayTimewindow": true, | ||
260 | + "actions": {}, | ||
261 | + "datasources": [], | ||
262 | + "alarmsMaxCountLoad": 0, | ||
263 | + "alarmsFetchSize": 100 | ||
264 | + }, | ||
265 | + "id": "7943196b-eedb-d422-f9c3-b32d379ad172" | ||
266 | + }, | ||
267 | + "14a19183-f0b2-d6be-0f62-9863f0a51111": { | ||
268 | + "isSystemType": true, | ||
269 | + "bundleAlias": "charts", | ||
270 | + "typeAlias": "basic_timeseries", | ||
271 | + "type": "timeseries", | ||
272 | + "title": "New widget", | ||
273 | + "sizeX": 18, | ||
274 | + "sizeY": 6, | ||
275 | + "config": { | ||
276 | + "datasources": [ | ||
277 | + { | ||
278 | + "type": "entity", | ||
279 | + "dataKeys": [ | ||
280 | + { | ||
281 | + "name": "temperature", | ||
282 | + "type": "timeseries", | ||
283 | + "label": "Temperature", | ||
284 | + "color": "#ef5350", | ||
285 | + "settings": { | ||
286 | + "excludeFromStacking": false, | ||
287 | + "hideDataByDefault": false, | ||
288 | + "disableDataHiding": false, | ||
289 | + "removeFromLegend": false, | ||
290 | + "showLines": true, | ||
291 | + "fillLines": true, | ||
292 | + "showPoints": false, | ||
293 | + "showPointShape": "circle", | ||
294 | + "pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", | ||
295 | + "showPointsLineWidth": 5, | ||
296 | + "showPointsRadius": 3, | ||
297 | + "showSeparateAxis": false, | ||
298 | + "axisPosition": "left", | ||
299 | + "thresholds": [ | ||
300 | + { | ||
301 | + "thresholdValueSource": "predefinedValue" | ||
302 | + } | ||
303 | + ], | ||
304 | + "comparisonSettings": { | ||
305 | + "showValuesForComparison": true | ||
306 | + } | ||
307 | + }, | ||
308 | + "_hash": 0.7852346160709658, | ||
309 | + "units": "°C", | ||
310 | + "decimals": 1 | ||
311 | + } | ||
312 | + ], | ||
313 | + "entityAliasId": "12ae98c7-1ea2-52cf-64d5-763e9d993547" | ||
314 | + } | ||
315 | + ], | ||
316 | + "timewindow": { | ||
317 | + "realtime": { | ||
318 | + "interval": 30000, | ||
319 | + "timewindowMs": 3600000 | ||
320 | + }, | ||
321 | + "aggregation": { | ||
322 | + "type": "AVG", | ||
323 | + "limit": 25000 | ||
324 | + } | ||
325 | + }, | ||
326 | + "showTitle": true, | ||
327 | + "backgroundColor": "#fff", | ||
328 | + "color": "rgba(0, 0, 0, 0.87)", | ||
329 | + "padding": "8px", | ||
330 | + "settings": { | ||
331 | + "shadowSize": 4, | ||
332 | + "fontColor": "#545454", | ||
333 | + "fontSize": 10, | ||
334 | + "xaxis": { | ||
335 | + "showLabels": true, | ||
336 | + "color": "#545454" | ||
337 | + }, | ||
338 | + "yaxis": { | ||
339 | + "showLabels": true, | ||
340 | + "color": "#545454" | ||
341 | + }, | ||
342 | + "grid": { | ||
343 | + "color": "#545454", | ||
344 | + "tickColor": "#DDDDDD", | ||
345 | + "verticalLines": true, | ||
346 | + "horizontalLines": true, | ||
347 | + "outlineWidth": 1 | ||
348 | + }, | ||
349 | + "stack": false, | ||
350 | + "tooltipIndividual": false, | ||
351 | + "timeForComparison": "months", | ||
352 | + "xaxisSecond": { | ||
353 | + "axisPosition": "top", | ||
354 | + "showLabels": true | ||
355 | + }, | ||
356 | + "smoothLines": true | ||
357 | + }, | ||
358 | + "title": "Temperature", | ||
359 | + "dropShadow": true, | ||
360 | + "enableFullscreen": true, | ||
361 | + "titleStyle": { | ||
362 | + "fontSize": "16px", | ||
363 | + "fontWeight": 400 | ||
364 | + }, | ||
365 | + "mobileHeight": null, | ||
366 | + "showTitleIcon": false, | ||
367 | + "titleIcon": null, | ||
368 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
369 | + "iconSize": "24px", | ||
370 | + "titleTooltip": "", | ||
371 | + "widgetStyle": {}, | ||
372 | + "useDashboardTimewindow": false, | ||
373 | + "displayTimewindow": true, | ||
374 | + "showLegend": true, | ||
375 | + "legendConfig": { | ||
376 | + "direction": "column", | ||
377 | + "position": "bottom", | ||
378 | + "showMin": true, | ||
379 | + "showMax": true, | ||
380 | + "showAvg": true, | ||
381 | + "showTotal": false | ||
382 | + }, | ||
383 | + "actions": {} | ||
384 | + }, | ||
385 | + "id": "14a19183-f0b2-d6be-0f62-9863f0a51111" | ||
386 | + }, | ||
387 | + "07f49fd5-a73b-d74c-c220-362c20af81f4": { | ||
388 | + "isSystemType": true, | ||
389 | + "bundleAlias": "charts", | ||
390 | + "typeAlias": "basic_timeseries", | ||
391 | + "type": "timeseries", | ||
392 | + "title": "New widget", | ||
393 | + "sizeX": 18, | ||
394 | + "sizeY": 6, | ||
395 | + "config": { | ||
396 | + "datasources": [ | ||
397 | + { | ||
398 | + "type": "entity", | ||
399 | + "dataKeys": [ | ||
400 | + { | ||
401 | + "name": "humidity", | ||
402 | + "type": "timeseries", | ||
403 | + "label": "Humidity", | ||
404 | + "color": "#2196f3", | ||
405 | + "settings": { | ||
406 | + "excludeFromStacking": false, | ||
407 | + "hideDataByDefault": false, | ||
408 | + "disableDataHiding": false, | ||
409 | + "removeFromLegend": false, | ||
410 | + "showLines": true, | ||
411 | + "fillLines": true, | ||
412 | + "showPoints": false, | ||
413 | + "showPointShape": "circle", | ||
414 | + "pointShapeFormatter": "var size = radius * Math.sqrt(Math.PI) / 2;\nctx.moveTo(x - size, y - size);\nctx.lineTo(x + size, y + size);\nctx.moveTo(x - size, y + size);\nctx.lineTo(x + size, y - size);", | ||
415 | + "showPointsLineWidth": 5, | ||
416 | + "showPointsRadius": 3, | ||
417 | + "showSeparateAxis": false, | ||
418 | + "axisPosition": "left", | ||
419 | + "thresholds": [ | ||
420 | + { | ||
421 | + "thresholdValueSource": "predefinedValue" | ||
422 | + } | ||
423 | + ], | ||
424 | + "comparisonSettings": { | ||
425 | + "showValuesForComparison": true | ||
426 | + } | ||
427 | + }, | ||
428 | + "_hash": 0.28640715926957183, | ||
429 | + "units": "%", | ||
430 | + "decimals": 0 | ||
431 | + } | ||
432 | + ], | ||
433 | + "entityAliasId": "12ae98c7-1ea2-52cf-64d5-763e9d993547" | ||
434 | + } | ||
435 | + ], | ||
436 | + "timewindow": { | ||
437 | + "realtime": { | ||
438 | + "interval": 30000, | ||
439 | + "timewindowMs": 3600000 | ||
440 | + }, | ||
441 | + "aggregation": { | ||
442 | + "type": "AVG", | ||
443 | + "limit": 25000 | ||
444 | + } | ||
445 | + }, | ||
446 | + "showTitle": true, | ||
447 | + "backgroundColor": "#fff", | ||
448 | + "color": "rgba(0, 0, 0, 0.87)", | ||
449 | + "padding": "8px", | ||
450 | + "settings": { | ||
451 | + "shadowSize": 4, | ||
452 | + "fontColor": "#545454", | ||
453 | + "fontSize": 10, | ||
454 | + "xaxis": { | ||
455 | + "showLabels": true, | ||
456 | + "color": "#545454" | ||
457 | + }, | ||
458 | + "yaxis": { | ||
459 | + "showLabels": true, | ||
460 | + "color": "#545454" | ||
461 | + }, | ||
462 | + "grid": { | ||
463 | + "color": "#545454", | ||
464 | + "tickColor": "#DDDDDD", | ||
465 | + "verticalLines": true, | ||
466 | + "horizontalLines": true, | ||
467 | + "outlineWidth": 1 | ||
468 | + }, | ||
469 | + "stack": false, | ||
470 | + "tooltipIndividual": false, | ||
471 | + "timeForComparison": "months", | ||
472 | + "xaxisSecond": { | ||
473 | + "axisPosition": "top", | ||
474 | + "showLabels": true | ||
475 | + }, | ||
476 | + "smoothLines": true | ||
477 | + }, | ||
478 | + "title": "Humidity", | ||
479 | + "dropShadow": true, | ||
480 | + "enableFullscreen": true, | ||
481 | + "titleStyle": { | ||
482 | + "fontSize": "16px", | ||
483 | + "fontWeight": 400 | ||
484 | + }, | ||
485 | + "mobileHeight": null, | ||
486 | + "showTitleIcon": false, | ||
487 | + "titleIcon": null, | ||
488 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
489 | + "iconSize": "24px", | ||
490 | + "titleTooltip": "", | ||
491 | + "widgetStyle": {}, | ||
492 | + "useDashboardTimewindow": false, | ||
493 | + "displayTimewindow": true, | ||
494 | + "showLegend": true, | ||
495 | + "legendConfig": { | ||
496 | + "direction": "column", | ||
497 | + "position": "bottom", | ||
498 | + "showMin": true, | ||
499 | + "showMax": true, | ||
500 | + "showAvg": true, | ||
501 | + "showTotal": false | ||
502 | + }, | ||
503 | + "actions": {} | ||
504 | + }, | ||
505 | + "id": "07f49fd5-a73b-d74c-c220-362c20af81f4" | ||
506 | + }, | ||
507 | + "c4631f94-2db3-523b-4d09-2a1a0a75d93f": { | ||
508 | + "isSystemType": true, | ||
509 | + "bundleAlias": "input_widgets", | ||
510 | + "typeAlias": "update_multiple_attributes", | ||
511 | + "type": "latest", | ||
512 | + "title": "New widget", | ||
513 | + "sizeX": 6, | ||
514 | + "sizeY": 6, | ||
515 | + "config": { | ||
516 | + "datasources": [ | ||
517 | + { | ||
518 | + "type": "entity", | ||
519 | + "dataKeys": [ | ||
520 | + { | ||
521 | + "name": "alarmTemperature", | ||
522 | + "type": "attribute", | ||
523 | + "label": "High temperature alarm", | ||
524 | + "color": "#4caf50", | ||
525 | + "settings": { | ||
526 | + "dataKeyType": "server", | ||
527 | + "dataKeyValueType": "booleanCheckbox", | ||
528 | + "required": false, | ||
529 | + "isEditable": "editable", | ||
530 | + "dataKeyHidden": false, | ||
531 | + "step": 1 | ||
532 | + }, | ||
533 | + "_hash": 0.8725278440159361 | ||
534 | + }, | ||
535 | + { | ||
536 | + "name": "thresholdTemperature", | ||
537 | + "type": "attribute", | ||
538 | + "label": "High temperature threshold, °C", | ||
539 | + "color": "#f44336", | ||
540 | + "settings": { | ||
541 | + "dataKeyType": "server", | ||
542 | + "dataKeyValueType": "double", | ||
543 | + "required": false, | ||
544 | + "isEditable": "editable", | ||
545 | + "dataKeyHidden": false, | ||
546 | + "step": 1, | ||
547 | + "disabledOnDataKey": "alarmTemperature" | ||
548 | + }, | ||
549 | + "_hash": 0.7316078472857874 | ||
550 | + }, | ||
551 | + { | ||
552 | + "name": "alarmHumidity", | ||
553 | + "type": "attribute", | ||
554 | + "label": "Low humidity alarm", | ||
555 | + "color": "#ffc107", | ||
556 | + "settings": { | ||
557 | + "dataKeyType": "server", | ||
558 | + "dataKeyValueType": "booleanCheckbox", | ||
559 | + "required": false, | ||
560 | + "isEditable": "editable", | ||
561 | + "dataKeyHidden": false, | ||
562 | + "step": 1 | ||
563 | + }, | ||
564 | + "_hash": 0.5339673667431057 | ||
565 | + }, | ||
566 | + { | ||
567 | + "name": "thresholdHumidity", | ||
568 | + "type": "attribute", | ||
569 | + "label": "Low humidity threshold, %", | ||
570 | + "color": "#607d8b", | ||
571 | + "settings": { | ||
572 | + "dataKeyType": "server", | ||
573 | + "dataKeyValueType": "double", | ||
574 | + "required": false, | ||
575 | + "isEditable": "editable", | ||
576 | + "dataKeyHidden": false, | ||
577 | + "step": 1, | ||
578 | + "disabledOnDataKey": "alarmHumidity" | ||
579 | + }, | ||
580 | + "_hash": 0.2687091190358901 | ||
581 | + } | ||
582 | + ], | ||
583 | + "entityAliasId": "12ae98c7-1ea2-52cf-64d5-763e9d993547" | ||
584 | + } | ||
585 | + ], | ||
586 | + "timewindow": { | ||
587 | + "realtime": { | ||
588 | + "timewindowMs": 60000 | ||
589 | + } | ||
590 | + }, | ||
591 | + "showTitle": true, | ||
592 | + "backgroundColor": "#fff", | ||
593 | + "color": "rgba(0, 0, 0, 0.87)", | ||
594 | + "padding": "8px", | ||
595 | + "settings": { | ||
596 | + "showActionButtons": false, | ||
597 | + "showResultMessage": true, | ||
598 | + "fieldsAlignment": "column", | ||
599 | + "fieldsInRow": 2, | ||
600 | + "groupTitle": "${entityName}", | ||
601 | + "widgetTitle": "Termostat settings" | ||
602 | + }, | ||
603 | + "title": "New Update Multiple Attributes", | ||
604 | + "dropShadow": true, | ||
605 | + "enableFullscreen": false, | ||
606 | + "enableDataExport": false, | ||
607 | + "widgetStyle": {}, | ||
608 | + "titleStyle": { | ||
609 | + "fontSize": "16px", | ||
610 | + "fontWeight": 400 | ||
611 | + }, | ||
612 | + "useDashboardTimewindow": true, | ||
613 | + "showLegend": false, | ||
614 | + "actions": {}, | ||
615 | + "showTitleIcon": false, | ||
616 | + "titleIcon": null, | ||
617 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
618 | + "iconSize": "24px", | ||
619 | + "titleTooltip": "", | ||
620 | + "displayTimewindow": true | ||
621 | + }, | ||
622 | + "id": "c4631f94-2db3-523b-4d09-2a1a0a75d93f" | ||
623 | + }, | ||
624 | + "3da9a9a1-0b9a-2e1f-0dcb-0ff34a695abb": { | ||
625 | + "isSystemType": true, | ||
626 | + "bundleAlias": "maps_v2", | ||
627 | + "typeAlias": "openstreetmap", | ||
628 | + "type": "latest", | ||
629 | + "title": "New widget", | ||
630 | + "sizeX": 13, | ||
631 | + "sizeY": 6, | ||
632 | + "config": { | ||
633 | + "datasources": [ | ||
634 | + { | ||
635 | + "type": "entity", | ||
636 | + "dataKeys": [ | ||
637 | + { | ||
638 | + "name": "temperature", | ||
639 | + "type": "timeseries", | ||
640 | + "label": "temperature", | ||
641 | + "color": "#2196f3", | ||
642 | + "settings": {}, | ||
643 | + "_hash": 0.1371919646686739, | ||
644 | + "decimals": 1, | ||
645 | + "postFuncBody": "return value || \"\";" | ||
646 | + }, | ||
647 | + { | ||
648 | + "name": "humidity", | ||
649 | + "type": "timeseries", | ||
650 | + "label": "humidity", | ||
651 | + "color": "#4caf50", | ||
652 | + "settings": {}, | ||
653 | + "_hash": 0.043177186765847475, | ||
654 | + "decimals": 0, | ||
655 | + "postFuncBody": "return value || \"\";" | ||
656 | + }, | ||
657 | + { | ||
658 | + "name": "longitude", | ||
659 | + "type": "attribute", | ||
660 | + "label": "longitude", | ||
661 | + "color": "#f44336", | ||
662 | + "settings": {}, | ||
663 | + "_hash": 0.5548964320315584 | ||
664 | + }, | ||
665 | + { | ||
666 | + "name": "latitude", | ||
667 | + "type": "attribute", | ||
668 | + "label": "latitude", | ||
669 | + "color": "#ffc107", | ||
670 | + "settings": {}, | ||
671 | + "_hash": 0.1803778014971602 | ||
672 | + }, | ||
673 | + { | ||
674 | + "name": "active", | ||
675 | + "type": "attribute", | ||
676 | + "label": "active", | ||
677 | + "color": "#607d8b", | ||
678 | + "settings": {}, | ||
679 | + "_hash": 0.30926987994082844 | ||
680 | + } | ||
681 | + ], | ||
682 | + "entityAliasId": "68a058e1-fdda-8482-715b-3ae4a488568e" | ||
683 | + } | ||
684 | + ], | ||
685 | + "timewindow": { | ||
686 | + "realtime": { | ||
687 | + "timewindowMs": 60000 | ||
688 | + } | ||
689 | + }, | ||
690 | + "showTitle": false, | ||
691 | + "backgroundColor": "#fff", | ||
692 | + "color": "rgba(0, 0, 0, 0.87)", | ||
693 | + "padding": "8px", | ||
694 | + "settings": { | ||
695 | + "fitMapBounds": true, | ||
696 | + "latKeyName": "latitude", | ||
697 | + "lngKeyName": "longitude", | ||
698 | + "showLabel": true, | ||
699 | + "label": "${entityName}", | ||
700 | + "tooltipPattern": "<b>${entityName}</b><br/><br/><b>Temperature:</b> ${temperature:1} °C<br/><b>Humidity:</b> ${humidity:0} %<br/><br/><link-act name=\"navigate_to_details\">Thermostat details</link-act><br/>", | ||
701 | + "markerImageSize": 48, | ||
702 | + "useColorFunction": false, | ||
703 | + "markerImages": [ | ||
704 | + "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJzdmc0NDA4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjAiIHk9IjAiIHZpZXdCb3g9IjAgMCAxNTAgMTUwIiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0MntmaWxsOiNmNDQzMzZ9PC9zdHlsZT48ZyBpZD0ibGF5ZXIxIj48ZyBpZD0icGF0aDY4ODEtMy01LTUtMS04LTQtNC03LTgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNDYuNDM4IC0yNzYuMDI4KSIgb3BhY2l0eT0iLjg5MiI+PHJhZGlhbEdyYWRpZW50IGlkPSJTVkdJRF8xXyIgY3g9IjMwODUuMjE1IiBjeT0iMzE3OC40NTgiIHI9IjQ5LjkwMSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCguNjc5MyAuMDA3NiAtLjUwOSAuNTYxMiAtMjMyLjYyOSAtMTQxMS43MjUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLW9wYWNpdHk9Ii4xODgiLz48L3JhZGlhbEdyYWRpZW50PjxwYXRoIGQ9Ik0yODUuNiAzODguNWMxMC4zLTEyLjQgNC40LTIyLjQtMTQuNC0yMi40LTE4LjkgMC00Mi40IDEwLTUzLjkgMjIuNC0xNi44IDE4IC40IDIzLjUtLjIgMzUtLjEgMS44IDMuOSAxLjggNyAwIDE5LjgtMTEuNSA0Ni41LTE3IDYxLjUtMzUiIGZpbGw9InVybCgjU1ZHSURfMV8pIi8+PC9nPjxwYXRoIGlkPSJwYXRoNjg4MS0zLTUtNS0xLTgtNC00IiBjbGFzcz0ic3QyIiBkPSJNMTI0LjcgNjkuMWMtLjktMjcuNS0yMi4zLTQ5LjgtNDkuOC00OS44cy00OSAyMi4zLTQ5LjggNDkuOGMtMS4zIDQwLjEgMzAuNyA1Mi4yIDQ0LjcgNzggMi4yIDQgOCA0IDEwLjEgMCAxNC4xLTI1LjggNDYuMS0zNy45IDQ0LjgtNzgiLz48L2c+PGcgaWQ9Imc0OTI4Ij48Y2lyY2xlIGlkPSJwYXRoNDk3OCIgY2xhc3M9InN0MiIgY3g9Ijc0LjkiIGN5PSI2OS4xIiByPSI0OS45Ii8+PGcgaWQ9Imc0OTE1Ij48cGF0aCBpZD0icGF0aDY4ODMtMi0zLTUtMi00LTktNC05IiBkPSJNNzQuOCAxMDYuNGMtMjAuNiAwLTM3LjQtMTYuNy0zNy40LTM3LjQgMC0yMC42IDE2LjctMzcuNCAzNy40LTM3LjQgMjAuNiAwIDM3LjQgMTYuNyAzNy40IDM3LjRzLTE2LjcgMzcuNC0zNy40IDM3LjQiIGZpbGw9IiNmZmYiLz48L2c+PC9nPjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik05NS45IDQ2LjZWNDloLTEwdi0yLjVsMTAgLjF6bS0yIDUuM2gtOHYyLjVoOHYtMi41em0tOCA3LjloNnYtMi41aC02djIuNXptNCAyLjloLTR2Mi41aDR2LTIuNXptLTQgNy44aDJWNjhoLTJ2Mi41em0xLjUgMTRjMCA2LjktNS41IDEyLjUtMTIuMyAxMi41cy0xMi4zLTUuNi0xMi4zLTEyLjVjMC00LjUgMi4zLTguNSA2LjEtMTAuN1Y0NS41YzAtMy41IDIuOC02LjMgNi4yLTYuM3M2LjIgMi44IDYuMiA2LjN2MjguM2MzLjggMi4yIDYuMSA2LjMgNi4xIDEwLjd6bS0yLjQgMGMwLTMuOC0yLjEtNy4yLTUuNC04LjlsLS43LS4zVjQ1LjVjMC0yLjEtMS43LTMuOC0zLjgtMy44LTIuMSAwLTMuOCAxLjctMy44IDMuOHYyOS44bC0uNy4zYy0zLjMgMS43LTUuNCA1LjEtNS40IDguOSAwIDUuNSA0LjQgMTAgOS45IDEwUzg1IDkwIDg1IDg0LjV6bS0yLjEgMGMwIDQuNC0zLjUgOC03LjggOHMtNy44LTMuNi03LjgtOGMwLTMuNiAyLjQtNi44IDUuOC03LjdsLjUtLjFWNjEuNWgzLjF2MTUuMmwuNS4xYzMuMyAxIDUuNyA0LjEgNS43IDcuN3ptLTcuNC01LjNjLS4yLS44LTEtMS40LTEuOS0xLjItMyAuNy01IDMuMy01IDYuNCAwIC45LjcgMS42IDEuNiAxLjZzMS42LS43IDEuNi0xLjZjMC0xLjYgMS4xLTMgMi42LTMuMy43LS4yIDEuMy0xIDEuMS0xLjl6Ii8+PC9zdmc+", | ||
705 | + "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJzdmc0NDA4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjAiIHk9IjAiIHZpZXdCb3g9IjAgMCAxNTAgMTUwIiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0MntmaWxsOiMyNzg2MjJ9PC9zdHlsZT48ZyBpZD0ibGF5ZXIxIj48ZyBpZD0icGF0aDY4ODEtMy01LTUtMS04LTQtNC03LTgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNDYuNDM4IC0yNzYuMDI4KSIgb3BhY2l0eT0iLjg5MiI+PHJhZGlhbEdyYWRpZW50IGlkPSJTVkdJRF8xXyIgY3g9IjMwODUuMjE1IiBjeT0iMzE3OC40NTgiIHI9IjQ5LjkwMSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCguNjc5MyAuMDA3NiAtLjUwOSAuNTYxMiAtMjMyLjYyOSAtMTQxMS43MjUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLW9wYWNpdHk9Ii4xODgiLz48L3JhZGlhbEdyYWRpZW50PjxwYXRoIGQ9Ik0yODUuNiAzODguNWMxMC4zLTEyLjQgNC40LTIyLjQtMTQuNC0yMi40LTE4LjkgMC00Mi40IDEwLTUzLjkgMjIuNC0xNi44IDE4IC40IDIzLjUtLjIgMzUtLjEgMS44IDMuOSAxLjggNyAwIDE5LjgtMTEuNSA0Ni41LTE3IDYxLjUtMzUiIGZpbGw9InVybCgjU1ZHSURfMV8pIi8+PC9nPjxwYXRoIGlkPSJwYXRoNjg4MS0zLTUtNS0xLTgtNC00IiBjbGFzcz0ic3QyIiBkPSJNMTI0LjcgNjkuMWMtLjktMjcuNS0yMi4zLTQ5LjgtNDkuOC00OS44cy00OSAyMi4zLTQ5LjggNDkuOGMtMS4zIDQwLjEgMzAuNyA1Mi4yIDQ0LjcgNzggMi4yIDQgOCA0IDEwLjEgMCAxNC4xLTI1LjggNDYuMS0zNy45IDQ0LjgtNzgiLz48L2c+PGcgaWQ9Imc0OTI4Ij48Y2lyY2xlIGlkPSJwYXRoNDk3OCIgY2xhc3M9InN0MiIgY3g9Ijc0LjkiIGN5PSI2OS4xIiByPSI0OS45Ii8+PGcgaWQ9Imc0OTE1Ij48cGF0aCBpZD0icGF0aDY4ODMtMi0zLTUtMi00LTktNC05IiBkPSJNNzQuOCAxMDYuNGMtMjAuNiAwLTM3LjQtMTYuNy0zNy40LTM3LjQgMC0yMC42IDE2LjctMzcuNCAzNy40LTM3LjQgMjAuNiAwIDM3LjQgMTYuNyAzNy40IDM3LjRzLTE2LjcgMzcuNC0zNy40IDM3LjQiIGZpbGw9IiNmZmYiLz48L2c+PC9nPjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik05NS45IDQ2LjZWNDloLTEwdi0yLjVsMTAgLjF6bS0yIDUuM2gtOHYyLjVoOHYtMi41em0tOCA3LjloNnYtMi41aC02djIuNXptNCAyLjloLTR2Mi41aDR2LTIuNXptLTQgNy44aDJWNjhoLTJ2Mi41em0xLjUgMTRjMCA2LjktNS41IDEyLjUtMTIuMyAxMi41cy0xMi4zLTUuNi0xMi4zLTEyLjVjMC00LjUgMi4zLTguNSA2LjEtMTAuN1Y0NS41YzAtMy41IDIuOC02LjMgNi4yLTYuM3M2LjIgMi44IDYuMiA2LjN2MjguM2MzLjggMi4yIDYuMSA2LjMgNi4xIDEwLjd6bS0yLjQgMGMwLTMuOC0yLjEtNy4yLTUuNC04LjlsLS43LS4zVjQ1LjVjMC0yLjEtMS43LTMuOC0zLjgtMy44LTIuMSAwLTMuOCAxLjctMy44IDMuOHYyOS44bC0uNy4zYy0zLjMgMS43LTUuNCA1LjEtNS40IDguOSAwIDUuNSA0LjQgMTAgOS45IDEwUzg1IDkwIDg1IDg0LjV6bS0yLjEgMGMwIDQuNC0zLjUgOC03LjggOHMtNy44LTMuNi03LjgtOGMwLTMuNiAyLjQtNi44IDUuOC03LjdsLjUtLjFWNjEuNWgzLjF2MTUuMmwuNS4xYzMuMyAxIDUuNyA0LjEgNS43IDcuN3ptLTcuNC01LjNjLS4yLS44LTEtMS40LTEuOS0xLjItMyAuNy01IDMuMy01IDYuNCAwIC45LjcgMS42IDEuNiAxLjZzMS42LS43IDEuNi0xLjZjMC0xLjYgMS4xLTMgMi42LTMuMy43LS4yIDEuMy0xIDEuMS0xLjl6Ii8+PC9zdmc+Cg==" | ||
706 | + ], | ||
707 | + "useMarkerImageFunction": true, | ||
708 | + "colorFunction": "\n", | ||
709 | + "color": "#fe7569", | ||
710 | + "mapProvider": "OpenStreetMap.HOT", | ||
711 | + "showTooltip": true, | ||
712 | + "autocloseTooltip": true, | ||
713 | + "customProviderTileUrl": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", | ||
714 | + "defaultCenterPosition": [ | ||
715 | + 0, | ||
716 | + 0 | ||
717 | + ], | ||
718 | + "showTooltipAction": "click", | ||
719 | + "polygonKeyName": "coordinates", | ||
720 | + "polygonOpacity": 0.5, | ||
721 | + "polygonStrokeOpacity": 1, | ||
722 | + "polygonStrokeWeight": 1, | ||
723 | + "zoomOnClick": true, | ||
724 | + "showCoverageOnHover": true, | ||
725 | + "animate": true, | ||
726 | + "maxClusterRadius": 80, | ||
727 | + "removeOutsideVisibleBounds": true, | ||
728 | + "useLabelFunction": true, | ||
729 | + "labelFunction": "var color;\nif(dsData[dsIndex].active !== \"true\"){\n color = 'rgb(255, 0, 0)';\n} else {\n color = 'rgb(39, 134, 34)';\n}\nreturn '<span style=\"border: solid ' + color + '; border-radius: 10px; color: ' + color + '; background-color: #fff; padding: 3px 5px; font-size: 14px\">' + \n '${entityLabel}' + \n '</span>'", | ||
730 | + "defaultZoomLevel": 14, | ||
731 | + "markerImageFunction": "var res;\nif(dsData[dsIndex].active !== \"true\"){\n\tvar res = {\n\t url: images[0],\n\t size: 48\n\t}\n} else {\n var res = {\n\t url: images[1],\n\t size: 48\n\t}\n}\nreturn res;" | ||
732 | + }, | ||
733 | + "title": "Thermostat maps", | ||
734 | + "dropShadow": true, | ||
735 | + "enableFullscreen": false, | ||
736 | + "titleStyle": { | ||
737 | + "fontSize": "16px", | ||
738 | + "fontWeight": 400 | ||
739 | + }, | ||
740 | + "useDashboardTimewindow": true, | ||
741 | + "showLegend": false, | ||
742 | + "widgetStyle": {}, | ||
743 | + "actions": { | ||
744 | + "headerButton": [], | ||
745 | + "tooltipAction": [ | ||
746 | + { | ||
747 | + "id": "bef25673-b37a-8821-bc0f-5d6dd3680f24", | ||
748 | + "name": "navigate_to_details", | ||
749 | + "icon": "more_horiz", | ||
750 | + "type": "openDashboardState", | ||
751 | + "targetDashboardStateId": "chart", | ||
752 | + "setEntityId": true | ||
753 | + } | ||
754 | + ] | ||
755 | + }, | ||
756 | + "showTitleIcon": false, | ||
757 | + "titleIcon": null, | ||
758 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
759 | + "iconSize": "24px", | ||
760 | + "titleTooltip": "", | ||
761 | + "displayTimewindow": true | ||
762 | + }, | ||
763 | + "id": "3da9a9a1-0b9a-2e1f-0dcb-0ff34a695abb" | ||
764 | + }, | ||
765 | + "00fb2742-ba1f-7e43-673f-d6c08b72ed06": { | ||
766 | + "isSystemType": true, | ||
767 | + "bundleAlias": "input_widgets", | ||
768 | + "typeAlias": "markers_placement_openstreetmap", | ||
769 | + "type": "latest", | ||
770 | + "title": "New widget", | ||
771 | + "sizeX": 24, | ||
772 | + "sizeY": 12, | ||
773 | + "config": { | ||
774 | + "datasources": [ | ||
775 | + { | ||
776 | + "type": "entity", | ||
777 | + "dataKeys": [ | ||
778 | + { | ||
779 | + "name": "longitude", | ||
780 | + "type": "attribute", | ||
781 | + "label": "longitude", | ||
782 | + "color": "#2196f3", | ||
783 | + "settings": {}, | ||
784 | + "_hash": 0.3640193654284214 | ||
785 | + }, | ||
786 | + { | ||
787 | + "name": "latitude", | ||
788 | + "type": "attribute", | ||
789 | + "label": "latitude", | ||
790 | + "color": "#4caf50", | ||
791 | + "settings": {}, | ||
792 | + "_hash": 0.49020393887695923 | ||
793 | + }, | ||
794 | + { | ||
795 | + "name": "temperature", | ||
796 | + "type": "timeseries", | ||
797 | + "label": "temperature", | ||
798 | + "color": "#f44336", | ||
799 | + "settings": {}, | ||
800 | + "_hash": 0.5885892766009955, | ||
801 | + "postFuncBody": "return value || \"\";" | ||
802 | + }, | ||
803 | + { | ||
804 | + "name": "humidity", | ||
805 | + "type": "timeseries", | ||
806 | + "label": "humidity", | ||
807 | + "color": "#ffc107", | ||
808 | + "settings": {}, | ||
809 | + "_hash": 0.21077893588180707, | ||
810 | + "postFuncBody": "return value || \"\";" | ||
811 | + }, | ||
812 | + { | ||
813 | + "name": "active", | ||
814 | + "type": "attribute", | ||
815 | + "label": "active", | ||
816 | + "color": "#607d8b", | ||
817 | + "settings": {}, | ||
818 | + "_hash": 0.34722983638504346 | ||
819 | + } | ||
820 | + ], | ||
821 | + "entityAliasId": "68a058e1-fdda-8482-715b-3ae4a488568e" | ||
822 | + } | ||
823 | + ], | ||
824 | + "timewindow": { | ||
825 | + "realtime": { | ||
826 | + "timewindowMs": 60000 | ||
827 | + } | ||
828 | + }, | ||
829 | + "showTitle": false, | ||
830 | + "backgroundColor": "#fff", | ||
831 | + "color": "rgba(0, 0, 0, 0.87)", | ||
832 | + "padding": "8px", | ||
833 | + "settings": { | ||
834 | + "fitMapBounds": true, | ||
835 | + "latKeyName": "latitude", | ||
836 | + "lngKeyName": "longitude", | ||
837 | + "showLabel": true, | ||
838 | + "label": "${entityName}", | ||
839 | + "tooltipPattern": "<b>${entityName}</b><br/><br/><b>Temperature:</b> ${temperature:1} °C<br/><b>Humidity:</b> ${humidity:0} %<br/><br/><link-act name='delete'>Delete</link-act>", | ||
840 | + "markerImageSize": 34, | ||
841 | + "useColorFunction": false, | ||
842 | + "markerImages": [ | ||
843 | + "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJzdmc0NDA4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjAiIHk9IjAiIHZpZXdCb3g9IjAgMCAxNTAgMTUwIiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0MntmaWxsOiNmNDQzMzZ9PC9zdHlsZT48ZyBpZD0ibGF5ZXIxIj48ZyBpZD0icGF0aDY4ODEtMy01LTUtMS04LTQtNC03LTgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNDYuNDM4IC0yNzYuMDI4KSIgb3BhY2l0eT0iLjg5MiI+PHJhZGlhbEdyYWRpZW50IGlkPSJTVkdJRF8xXyIgY3g9IjMwODUuMjE1IiBjeT0iMzE3OC40NTgiIHI9IjQ5LjkwMSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCguNjc5MyAuMDA3NiAtLjUwOSAuNTYxMiAtMjMyLjYyOSAtMTQxMS43MjUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLW9wYWNpdHk9Ii4xODgiLz48L3JhZGlhbEdyYWRpZW50PjxwYXRoIGQ9Ik0yODUuNiAzODguNWMxMC4zLTEyLjQgNC40LTIyLjQtMTQuNC0yMi40LTE4LjkgMC00Mi40IDEwLTUzLjkgMjIuNC0xNi44IDE4IC40IDIzLjUtLjIgMzUtLjEgMS44IDMuOSAxLjggNyAwIDE5LjgtMTEuNSA0Ni41LTE3IDYxLjUtMzUiIGZpbGw9InVybCgjU1ZHSURfMV8pIi8+PC9nPjxwYXRoIGlkPSJwYXRoNjg4MS0zLTUtNS0xLTgtNC00IiBjbGFzcz0ic3QyIiBkPSJNMTI0LjcgNjkuMWMtLjktMjcuNS0yMi4zLTQ5LjgtNDkuOC00OS44cy00OSAyMi4zLTQ5LjggNDkuOGMtMS4zIDQwLjEgMzAuNyA1Mi4yIDQ0LjcgNzggMi4yIDQgOCA0IDEwLjEgMCAxNC4xLTI1LjggNDYuMS0zNy45IDQ0LjgtNzgiLz48L2c+PGcgaWQ9Imc0OTI4Ij48Y2lyY2xlIGlkPSJwYXRoNDk3OCIgY2xhc3M9InN0MiIgY3g9Ijc0LjkiIGN5PSI2OS4xIiByPSI0OS45Ii8+PGcgaWQ9Imc0OTE1Ij48cGF0aCBpZD0icGF0aDY4ODMtMi0zLTUtMi00LTktNC05IiBkPSJNNzQuOCAxMDYuNGMtMjAuNiAwLTM3LjQtMTYuNy0zNy40LTM3LjQgMC0yMC42IDE2LjctMzcuNCAzNy40LTM3LjQgMjAuNiAwIDM3LjQgMTYuNyAzNy40IDM3LjRzLTE2LjcgMzcuNC0zNy40IDM3LjQiIGZpbGw9IiNmZmYiLz48L2c+PC9nPjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik05NS45IDQ2LjZWNDloLTEwdi0yLjVsMTAgLjF6bS0yIDUuM2gtOHYyLjVoOHYtMi41em0tOCA3LjloNnYtMi41aC02djIuNXptNCAyLjloLTR2Mi41aDR2LTIuNXptLTQgNy44aDJWNjhoLTJ2Mi41em0xLjUgMTRjMCA2LjktNS41IDEyLjUtMTIuMyAxMi41cy0xMi4zLTUuNi0xMi4zLTEyLjVjMC00LjUgMi4zLTguNSA2LjEtMTAuN1Y0NS41YzAtMy41IDIuOC02LjMgNi4yLTYuM3M2LjIgMi44IDYuMiA2LjN2MjguM2MzLjggMi4yIDYuMSA2LjMgNi4xIDEwLjd6bS0yLjQgMGMwLTMuOC0yLjEtNy4yLTUuNC04LjlsLS43LS4zVjQ1LjVjMC0yLjEtMS43LTMuOC0zLjgtMy44LTIuMSAwLTMuOCAxLjctMy44IDMuOHYyOS44bC0uNy4zYy0zLjMgMS43LTUuNCA1LjEtNS40IDguOSAwIDUuNSA0LjQgMTAgOS45IDEwUzg1IDkwIDg1IDg0LjV6bS0yLjEgMGMwIDQuNC0zLjUgOC03LjggOHMtNy44LTMuNi03LjgtOGMwLTMuNiAyLjQtNi44IDUuOC03LjdsLjUtLjFWNjEuNWgzLjF2MTUuMmwuNS4xYzMuMyAxIDUuNyA0LjEgNS43IDcuN3ptLTcuNC01LjNjLS4yLS44LTEtMS40LTEuOS0xLjItMyAuNy01IDMuMy01IDYuNCAwIC45LjcgMS42IDEuNiAxLjZzMS42LS43IDEuNi0xLjZjMC0xLjYgMS4xLTMgMi42LTMuMy43LS4yIDEuMy0xIDEuMS0xLjl6Ii8+PC9zdmc+", | ||
844 | + "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJzdmc0NDA4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjAiIHk9IjAiIHZpZXdCb3g9IjAgMCAxNTAgMTUwIiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0MntmaWxsOiMyNzg2MjJ9PC9zdHlsZT48ZyBpZD0ibGF5ZXIxIj48ZyBpZD0icGF0aDY4ODEtMy01LTUtMS04LTQtNC03LTgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNDYuNDM4IC0yNzYuMDI4KSIgb3BhY2l0eT0iLjg5MiI+PHJhZGlhbEdyYWRpZW50IGlkPSJTVkdJRF8xXyIgY3g9IjMwODUuMjE1IiBjeT0iMzE3OC40NTgiIHI9IjQ5LjkwMSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCguNjc5MyAuMDA3NiAtLjUwOSAuNTYxMiAtMjMyLjYyOSAtMTQxMS43MjUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLW9wYWNpdHk9Ii4xODgiLz48L3JhZGlhbEdyYWRpZW50PjxwYXRoIGQ9Ik0yODUuNiAzODguNWMxMC4zLTEyLjQgNC40LTIyLjQtMTQuNC0yMi40LTE4LjkgMC00Mi40IDEwLTUzLjkgMjIuNC0xNi44IDE4IC40IDIzLjUtLjIgMzUtLjEgMS44IDMuOSAxLjggNyAwIDE5LjgtMTEuNSA0Ni41LTE3IDYxLjUtMzUiIGZpbGw9InVybCgjU1ZHSURfMV8pIi8+PC9nPjxwYXRoIGlkPSJwYXRoNjg4MS0zLTUtNS0xLTgtNC00IiBjbGFzcz0ic3QyIiBkPSJNMTI0LjcgNjkuMWMtLjktMjcuNS0yMi4zLTQ5LjgtNDkuOC00OS44cy00OSAyMi4zLTQ5LjggNDkuOGMtMS4zIDQwLjEgMzAuNyA1Mi4yIDQ0LjcgNzggMi4yIDQgOCA0IDEwLjEgMCAxNC4xLTI1LjggNDYuMS0zNy45IDQ0LjgtNzgiLz48L2c+PGcgaWQ9Imc0OTI4Ij48Y2lyY2xlIGlkPSJwYXRoNDk3OCIgY2xhc3M9InN0MiIgY3g9Ijc0LjkiIGN5PSI2OS4xIiByPSI0OS45Ii8+PGcgaWQ9Imc0OTE1Ij48cGF0aCBpZD0icGF0aDY4ODMtMi0zLTUtMi00LTktNC05IiBkPSJNNzQuOCAxMDYuNGMtMjAuNiAwLTM3LjQtMTYuNy0zNy40LTM3LjQgMC0yMC42IDE2LjctMzcuNCAzNy40LTM3LjQgMjAuNiAwIDM3LjQgMTYuNyAzNy40IDM3LjRzLTE2LjcgMzcuNC0zNy40IDM3LjQiIGZpbGw9IiNmZmYiLz48L2c+PC9nPjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik05NS45IDQ2LjZWNDloLTEwdi0yLjVsMTAgLjF6bS0yIDUuM2gtOHYyLjVoOHYtMi41em0tOCA3LjloNnYtMi41aC02djIuNXptNCAyLjloLTR2Mi41aDR2LTIuNXptLTQgNy44aDJWNjhoLTJ2Mi41em0xLjUgMTRjMCA2LjktNS41IDEyLjUtMTIuMyAxMi41cy0xMi4zLTUuNi0xMi4zLTEyLjVjMC00LjUgMi4zLTguNSA2LjEtMTAuN1Y0NS41YzAtMy41IDIuOC02LjMgNi4yLTYuM3M2LjIgMi44IDYuMiA2LjN2MjguM2MzLjggMi4yIDYuMSA2LjMgNi4xIDEwLjd6bS0yLjQgMGMwLTMuOC0yLjEtNy4yLTUuNC04LjlsLS43LS4zVjQ1LjVjMC0yLjEtMS43LTMuOC0zLjgtMy44LTIuMSAwLTMuOCAxLjctMy44IDMuOHYyOS44bC0uNy4zYy0zLjMgMS43LTUuNCA1LjEtNS40IDguOSAwIDUuNSA0LjQgMTAgOS45IDEwUzg1IDkwIDg1IDg0LjV6bS0yLjEgMGMwIDQuNC0zLjUgOC03LjggOHMtNy44LTMuNi03LjgtOGMwLTMuNiAyLjQtNi44IDUuOC03LjdsLjUtLjFWNjEuNWgzLjF2MTUuMmwuNS4xYzMuMyAxIDUuNyA0LjEgNS43IDcuN3ptLTcuNC01LjNjLS4yLS44LTEtMS40LTEuOS0xLjItMyAuNy01IDMuMy01IDYuNCAwIC45LjcgMS42IDEuNiAxLjZzMS42LS43IDEuNi0xLjZjMC0xLjYgMS4xLTMgMi42LTMuMy43LS4yIDEuMy0xIDEuMS0xLjl6Ii8+PC9zdmc+Cg==" | ||
845 | + ], | ||
846 | + "useMarkerImageFunction": true, | ||
847 | + "color": "#fe7569", | ||
848 | + "mapProvider": "OpenStreetMap.HOT", | ||
849 | + "showTooltip": true, | ||
850 | + "autocloseTooltip": true, | ||
851 | + "defaultCenterPosition": [ | ||
852 | + 0, | ||
853 | + 0 | ||
854 | + ], | ||
855 | + "customProviderTileUrl": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", | ||
856 | + "showTooltipAction": "click", | ||
857 | + "polygonKeyName": "coordinates", | ||
858 | + "polygonOpacity": 0.5, | ||
859 | + "polygonStrokeOpacity": 1, | ||
860 | + "polygonStrokeWeight": 1, | ||
861 | + "zoomOnClick": true, | ||
862 | + "showCoverageOnHover": true, | ||
863 | + "animate": true, | ||
864 | + "maxClusterRadius": 80, | ||
865 | + "removeOutsideVisibleBounds": true, | ||
866 | + "defaultZoomLevel": 12, | ||
867 | + "labelFunction": "var color;\nif(dsData[dsIndex].active !== \"true\"){\n color = 'rgb(255, 0, 0)';\n} else {\n color = 'rgb(39, 134, 34)';\n}\nreturn '<span style=\"border: solid ' + color + '; border-radius: 10px; color: ' + color + '; background-color: #fff; padding: 3px 5px; font-size: 14px\">' + \n '${entityLabel}' + \n '</span>'", | ||
868 | + "markerImageFunction": "var res;\nif(dsData[dsIndex].active !== \"true\"){\n\tvar res = {\n\t url: images[0],\n\t size: 48\n\t}\n} else {\n var res = {\n\t url: images[1],\n\t size: 48\n\t}\n}\nreturn res;", | ||
869 | + "useLabelFunction": true | ||
870 | + }, | ||
871 | + "title": "New Markers Placement - OpenStreetMap", | ||
872 | + "dropShadow": true, | ||
873 | + "enableFullscreen": false, | ||
874 | + "titleStyle": { | ||
875 | + "fontSize": "16px", | ||
876 | + "fontWeight": 400 | ||
877 | + }, | ||
878 | + "useDashboardTimewindow": true, | ||
879 | + "showLegend": false, | ||
880 | + "widgetStyle": {}, | ||
881 | + "actions": { | ||
882 | + "tooltipAction": [ | ||
883 | + { | ||
884 | + "id": "54c293c4-9ca6-e34f-dc6a-0271944c1c66", | ||
885 | + "name": "delete", | ||
886 | + "icon": "more_horiz", | ||
887 | + "type": "custom", | ||
888 | + "customFunction": "var $rootScope = widgetContext.$scope.$injector.get('$rootScope');\nvar entityDatasource = widgetContext.map.subscription.datasources.filter(\n function(entity) {\n return entity.entityId === entityId.id\n });\n\nwidgetContext.map.saveMarkerLocation(entityDatasource[0],\n widgetContext.map.locations[0], {\n \"lat\": null,\n \"lng\": null\n }).then(function succes() {\n $rootScope.$broadcast('widgetForceReInit');\n });" | ||
889 | + } | ||
890 | + ] | ||
891 | + }, | ||
892 | + "showTitleIcon": false, | ||
893 | + "titleIcon": null, | ||
894 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
895 | + "iconSize": "24px", | ||
896 | + "titleTooltip": "", | ||
897 | + "displayTimewindow": true | ||
898 | + }, | ||
899 | + "id": "00fb2742-ba1f-7e43-673f-d6c08b72ed06" | ||
900 | + }, | ||
901 | + "0a430429-9078-9ae6-2b67-e4a15a2bf8bf": { | ||
902 | + "isSystemType": true, | ||
903 | + "bundleAlias": "input_widgets", | ||
904 | + "typeAlias": "markers_placement_openstreetmap", | ||
905 | + "type": "latest", | ||
906 | + "title": "New widget", | ||
907 | + "sizeX": 6, | ||
908 | + "sizeY": 6, | ||
909 | + "config": { | ||
910 | + "datasources": [ | ||
911 | + { | ||
912 | + "type": "entity", | ||
913 | + "dataKeys": [ | ||
914 | + { | ||
915 | + "name": "longitude", | ||
916 | + "type": "attribute", | ||
917 | + "label": "longitude", | ||
918 | + "color": "#2196f3", | ||
919 | + "settings": {}, | ||
920 | + "_hash": 0.3640193654284214 | ||
921 | + }, | ||
922 | + { | ||
923 | + "name": "latitude", | ||
924 | + "type": "attribute", | ||
925 | + "label": "latitude", | ||
926 | + "color": "#4caf50", | ||
927 | + "settings": {}, | ||
928 | + "_hash": 0.49020393887695923 | ||
929 | + }, | ||
930 | + { | ||
931 | + "name": "temperature", | ||
932 | + "type": "timeseries", | ||
933 | + "label": "temperature", | ||
934 | + "color": "#f44336", | ||
935 | + "settings": {}, | ||
936 | + "_hash": 0.5885892766009955, | ||
937 | + "postFuncBody": "return value || \"\";" | ||
938 | + }, | ||
939 | + { | ||
940 | + "name": "humidity", | ||
941 | + "type": "timeseries", | ||
942 | + "label": "humidity", | ||
943 | + "color": "#ffc107", | ||
944 | + "settings": {}, | ||
945 | + "_hash": 0.21077893588180707, | ||
946 | + "postFuncBody": "return value || \"\";" | ||
947 | + }, | ||
948 | + { | ||
949 | + "name": "active", | ||
950 | + "type": "attribute", | ||
951 | + "label": "active", | ||
952 | + "color": "#607d8b", | ||
953 | + "settings": {}, | ||
954 | + "_hash": 0.34722983638504346 | ||
955 | + } | ||
956 | + ], | ||
957 | + "entityAliasId": "12ae98c7-1ea2-52cf-64d5-763e9d993547" | ||
958 | + } | ||
959 | + ], | ||
960 | + "timewindow": { | ||
961 | + "realtime": { | ||
962 | + "timewindowMs": 60000 | ||
963 | + } | ||
964 | + }, | ||
965 | + "showTitle": false, | ||
966 | + "backgroundColor": "#fff", | ||
967 | + "color": "rgba(0, 0, 0, 0.87)", | ||
968 | + "padding": "8px", | ||
969 | + "settings": { | ||
970 | + "fitMapBounds": true, | ||
971 | + "latKeyName": "latitude", | ||
972 | + "lngKeyName": "longitude", | ||
973 | + "showLabel": true, | ||
974 | + "label": "${entityName}", | ||
975 | + "tooltipPattern": "<b>${entityName}</b><br/><br/><b>Temperature:</b> ${temperature:1} °C<br/><b>Humidity:</b> ${humidity:0} %<br/><br/><link-act name='delete'>Delete</link-act>", | ||
976 | + "markerImageSize": 34, | ||
977 | + "useColorFunction": false, | ||
978 | + "markerImages": [ | ||
979 | + "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJzdmc0NDA4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjAiIHk9IjAiIHZpZXdCb3g9IjAgMCAxNTAgMTUwIiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0MntmaWxsOiNmNDQzMzZ9PC9zdHlsZT48ZyBpZD0ibGF5ZXIxIj48ZyBpZD0icGF0aDY4ODEtMy01LTUtMS04LTQtNC03LTgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNDYuNDM4IC0yNzYuMDI4KSIgb3BhY2l0eT0iLjg5MiI+PHJhZGlhbEdyYWRpZW50IGlkPSJTVkdJRF8xXyIgY3g9IjMwODUuMjE1IiBjeT0iMzE3OC40NTgiIHI9IjQ5LjkwMSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCguNjc5MyAuMDA3NiAtLjUwOSAuNTYxMiAtMjMyLjYyOSAtMTQxMS43MjUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLW9wYWNpdHk9Ii4xODgiLz48L3JhZGlhbEdyYWRpZW50PjxwYXRoIGQ9Ik0yODUuNiAzODguNWMxMC4zLTEyLjQgNC40LTIyLjQtMTQuNC0yMi40LTE4LjkgMC00Mi40IDEwLTUzLjkgMjIuNC0xNi44IDE4IC40IDIzLjUtLjIgMzUtLjEgMS44IDMuOSAxLjggNyAwIDE5LjgtMTEuNSA0Ni41LTE3IDYxLjUtMzUiIGZpbGw9InVybCgjU1ZHSURfMV8pIi8+PC9nPjxwYXRoIGlkPSJwYXRoNjg4MS0zLTUtNS0xLTgtNC00IiBjbGFzcz0ic3QyIiBkPSJNMTI0LjcgNjkuMWMtLjktMjcuNS0yMi4zLTQ5LjgtNDkuOC00OS44cy00OSAyMi4zLTQ5LjggNDkuOGMtMS4zIDQwLjEgMzAuNyA1Mi4yIDQ0LjcgNzggMi4yIDQgOCA0IDEwLjEgMCAxNC4xLTI1LjggNDYuMS0zNy45IDQ0LjgtNzgiLz48L2c+PGcgaWQ9Imc0OTI4Ij48Y2lyY2xlIGlkPSJwYXRoNDk3OCIgY2xhc3M9InN0MiIgY3g9Ijc0LjkiIGN5PSI2OS4xIiByPSI0OS45Ii8+PGcgaWQ9Imc0OTE1Ij48cGF0aCBpZD0icGF0aDY4ODMtMi0zLTUtMi00LTktNC05IiBkPSJNNzQuOCAxMDYuNGMtMjAuNiAwLTM3LjQtMTYuNy0zNy40LTM3LjQgMC0yMC42IDE2LjctMzcuNCAzNy40LTM3LjQgMjAuNiAwIDM3LjQgMTYuNyAzNy40IDM3LjRzLTE2LjcgMzcuNC0zNy40IDM3LjQiIGZpbGw9IiNmZmYiLz48L2c+PC9nPjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik05NS45IDQ2LjZWNDloLTEwdi0yLjVsMTAgLjF6bS0yIDUuM2gtOHYyLjVoOHYtMi41em0tOCA3LjloNnYtMi41aC02djIuNXptNCAyLjloLTR2Mi41aDR2LTIuNXptLTQgNy44aDJWNjhoLTJ2Mi41em0xLjUgMTRjMCA2LjktNS41IDEyLjUtMTIuMyAxMi41cy0xMi4zLTUuNi0xMi4zLTEyLjVjMC00LjUgMi4zLTguNSA2LjEtMTAuN1Y0NS41YzAtMy41IDIuOC02LjMgNi4yLTYuM3M2LjIgMi44IDYuMiA2LjN2MjguM2MzLjggMi4yIDYuMSA2LjMgNi4xIDEwLjd6bS0yLjQgMGMwLTMuOC0yLjEtNy4yLTUuNC04LjlsLS43LS4zVjQ1LjVjMC0yLjEtMS43LTMuOC0zLjgtMy44LTIuMSAwLTMuOCAxLjctMy44IDMuOHYyOS44bC0uNy4zYy0zLjMgMS43LTUuNCA1LjEtNS40IDguOSAwIDUuNSA0LjQgMTAgOS45IDEwUzg1IDkwIDg1IDg0LjV6bS0yLjEgMGMwIDQuNC0zLjUgOC03LjggOHMtNy44LTMuNi03LjgtOGMwLTMuNiAyLjQtNi44IDUuOC03LjdsLjUtLjFWNjEuNWgzLjF2MTUuMmwuNS4xYzMuMyAxIDUuNyA0LjEgNS43IDcuN3ptLTcuNC01LjNjLS4yLS44LTEtMS40LTEuOS0xLjItMyAuNy01IDMuMy01IDYuNCAwIC45LjcgMS42IDEuNiAxLjZzMS42LS43IDEuNi0xLjZjMC0xLjYgMS4xLTMgMi42LTMuMy43LS4yIDEuMy0xIDEuMS0xLjl6Ii8+PC9zdmc+", | ||
980 | + "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJzdmc0NDA4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjAiIHk9IjAiIHZpZXdCb3g9IjAgMCAxNTAgMTUwIiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0MntmaWxsOiMyNzg2MjJ9PC9zdHlsZT48ZyBpZD0ibGF5ZXIxIj48ZyBpZD0icGF0aDY4ODEtMy01LTUtMS04LTQtNC03LTgiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNDYuNDM4IC0yNzYuMDI4KSIgb3BhY2l0eT0iLjg5MiI+PHJhZGlhbEdyYWRpZW50IGlkPSJTVkdJRF8xXyIgY3g9IjMwODUuMjE1IiBjeT0iMzE3OC40NTgiIHI9IjQ5LjkwMSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCguNjc5MyAuMDA3NiAtLjUwOSAuNTYxMiAtMjMyLjYyOSAtMTQxMS43MjUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLW9wYWNpdHk9Ii4xODgiLz48L3JhZGlhbEdyYWRpZW50PjxwYXRoIGQ9Ik0yODUuNiAzODguNWMxMC4zLTEyLjQgNC40LTIyLjQtMTQuNC0yMi40LTE4LjkgMC00Mi40IDEwLTUzLjkgMjIuNC0xNi44IDE4IC40IDIzLjUtLjIgMzUtLjEgMS44IDMuOSAxLjggNyAwIDE5LjgtMTEuNSA0Ni41LTE3IDYxLjUtMzUiIGZpbGw9InVybCgjU1ZHSURfMV8pIi8+PC9nPjxwYXRoIGlkPSJwYXRoNjg4MS0zLTUtNS0xLTgtNC00IiBjbGFzcz0ic3QyIiBkPSJNMTI0LjcgNjkuMWMtLjktMjcuNS0yMi4zLTQ5LjgtNDkuOC00OS44cy00OSAyMi4zLTQ5LjggNDkuOGMtMS4zIDQwLjEgMzAuNyA1Mi4yIDQ0LjcgNzggMi4yIDQgOCA0IDEwLjEgMCAxNC4xLTI1LjggNDYuMS0zNy45IDQ0LjgtNzgiLz48L2c+PGcgaWQ9Imc0OTI4Ij48Y2lyY2xlIGlkPSJwYXRoNDk3OCIgY2xhc3M9InN0MiIgY3g9Ijc0LjkiIGN5PSI2OS4xIiByPSI0OS45Ii8+PGcgaWQ9Imc0OTE1Ij48cGF0aCBpZD0icGF0aDY4ODMtMi0zLTUtMi00LTktNC05IiBkPSJNNzQuOCAxMDYuNGMtMjAuNiAwLTM3LjQtMTYuNy0zNy40LTM3LjQgMC0yMC42IDE2LjctMzcuNCAzNy40LTM3LjQgMjAuNiAwIDM3LjQgMTYuNyAzNy40IDM3LjRzLTE2LjcgMzcuNC0zNy40IDM3LjQiIGZpbGw9IiNmZmYiLz48L2c+PC9nPjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik05NS45IDQ2LjZWNDloLTEwdi0yLjVsMTAgLjF6bS0yIDUuM2gtOHYyLjVoOHYtMi41em0tOCA3LjloNnYtMi41aC02djIuNXptNCAyLjloLTR2Mi41aDR2LTIuNXptLTQgNy44aDJWNjhoLTJ2Mi41em0xLjUgMTRjMCA2LjktNS41IDEyLjUtMTIuMyAxMi41cy0xMi4zLTUuNi0xMi4zLTEyLjVjMC00LjUgMi4zLTguNSA2LjEtMTAuN1Y0NS41YzAtMy41IDIuOC02LjMgNi4yLTYuM3M2LjIgMi44IDYuMiA2LjN2MjguM2MzLjggMi4yIDYuMSA2LjMgNi4xIDEwLjd6bS0yLjQgMGMwLTMuOC0yLjEtNy4yLTUuNC04LjlsLS43LS4zVjQ1LjVjMC0yLjEtMS43LTMuOC0zLjgtMy44LTIuMSAwLTMuOCAxLjctMy44IDMuOHYyOS44bC0uNy4zYy0zLjMgMS43LTUuNCA1LjEtNS40IDguOSAwIDUuNSA0LjQgMTAgOS45IDEwUzg1IDkwIDg1IDg0LjV6bS0yLjEgMGMwIDQuNC0zLjUgOC03LjggOHMtNy44LTMuNi03LjgtOGMwLTMuNiAyLjQtNi44IDUuOC03LjdsLjUtLjFWNjEuNWgzLjF2MTUuMmwuNS4xYzMuMyAxIDUuNyA0LjEgNS43IDcuN3ptLTcuNC01LjNjLS4yLS44LTEtMS40LTEuOS0xLjItMyAuNy01IDMuMy01IDYuNCAwIC45LjcgMS42IDEuNiAxLjZzMS42LS43IDEuNi0xLjZjMC0xLjYgMS4xLTMgMi42LTMuMy43LS4yIDEuMy0xIDEuMS0xLjl6Ii8+PC9zdmc+Cg==" | ||
981 | + ], | ||
982 | + "useMarkerImageFunction": true, | ||
983 | + "color": "#fe7569", | ||
984 | + "mapProvider": "OpenStreetMap.HOT", | ||
985 | + "showTooltip": true, | ||
986 | + "autocloseTooltip": true, | ||
987 | + "defaultCenterPosition": [ | ||
988 | + 37.7749, | ||
989 | + -122.4194 | ||
990 | + ], | ||
991 | + "customProviderTileUrl": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", | ||
992 | + "showTooltipAction": "click", | ||
993 | + "polygonKeyName": "coordinates", | ||
994 | + "polygonOpacity": 0.5, | ||
995 | + "polygonStrokeOpacity": 1, | ||
996 | + "polygonStrokeWeight": 1, | ||
997 | + "zoomOnClick": true, | ||
998 | + "showCoverageOnHover": true, | ||
999 | + "animate": true, | ||
1000 | + "maxClusterRadius": 80, | ||
1001 | + "removeOutsideVisibleBounds": true, | ||
1002 | + "defaultZoomLevel": 5, | ||
1003 | + "labelFunction": "var color;\nif(dsData[dsIndex].active !== \"true\"){\n color = 'rgb(255, 0, 0)';\n} else {\n color = 'rgb(39, 134, 34)';\n}\nreturn '<span style=\"border: solid ' + color + '; border-radius: 10px; color: ' + color + '; background-color: #fff; padding: 3px 5px; font-size: 14px\">' + \n '${entityLabel}' + \n '</span>'", | ||
1004 | + "markerImageFunction": "var res;\nif(dsData[dsIndex].active !== \"true\"){\n\tvar res = {\n\t url: images[0],\n\t size: 48\n\t}\n} else {\n var res = {\n\t url: images[1],\n\t size: 48\n\t}\n}\nreturn res;", | ||
1005 | + "useLabelFunction": true, | ||
1006 | + "useDefaultCenterPosition": true | ||
1007 | + }, | ||
1008 | + "title": "New Markers Placement - OpenStreetMap", | ||
1009 | + "dropShadow": true, | ||
1010 | + "enableFullscreen": false, | ||
1011 | + "titleStyle": { | ||
1012 | + "fontSize": "16px", | ||
1013 | + "fontWeight": 400 | ||
1014 | + }, | ||
1015 | + "useDashboardTimewindow": true, | ||
1016 | + "showLegend": false, | ||
1017 | + "widgetStyle": {}, | ||
1018 | + "actions": { | ||
1019 | + "tooltipAction": [ | ||
1020 | + { | ||
1021 | + "id": "54c293c4-9ca6-e34f-dc6a-0271944c1c66", | ||
1022 | + "name": "delete", | ||
1023 | + "icon": "more_horiz", | ||
1024 | + "type": "custom", | ||
1025 | + "customFunction": "var $rootScope = widgetContext.$scope.$injector.get('$rootScope');\nvar entityDatasource = widgetContext.map.subscription.datasources.filter(\n function(entity) {\n return entity.entityId === entityId.id\n });\n\nwidgetContext.map.saveMarkerLocation(entityDatasource[0],\n widgetContext.map.locations[0], {\n \"lat\": null,\n \"lng\": null\n }).then(function succes() {\n $rootScope.$broadcast('widgetForceReInit');\n });" | ||
1026 | + } | ||
1027 | + ] | ||
1028 | + }, | ||
1029 | + "showTitleIcon": false, | ||
1030 | + "titleIcon": null, | ||
1031 | + "iconColor": "rgba(0, 0, 0, 0.87)", | ||
1032 | + "iconSize": "24px", | ||
1033 | + "titleTooltip": "", | ||
1034 | + "displayTimewindow": true | ||
1035 | + }, | ||
1036 | + "id": "0a430429-9078-9ae6-2b67-e4a15a2bf8bf" | ||
1037 | + } | ||
1038 | + }, | ||
1039 | + "states": { | ||
1040 | + "default": { | ||
1041 | + "name": "Thermostats", | ||
1042 | + "root": true, | ||
1043 | + "layouts": { | ||
1044 | + "main": { | ||
1045 | + "widgets": { | ||
1046 | + "f33c746c-0dfc-c212-395b-b448c8a17209": { | ||
1047 | + "sizeX": 11, | ||
1048 | + "sizeY": 11, | ||
1049 | + "row": 0, | ||
1050 | + "col": 0 | ||
1051 | + }, | ||
1052 | + "7943196b-eedb-d422-f9c3-b32d379ad172": { | ||
1053 | + "sizeX": 13, | ||
1054 | + "sizeY": 5, | ||
1055 | + "row": 0, | ||
1056 | + "col": 11 | ||
1057 | + }, | ||
1058 | + "3da9a9a1-0b9a-2e1f-0dcb-0ff34a695abb": { | ||
1059 | + "sizeX": 13, | ||
1060 | + "sizeY": 6, | ||
1061 | + "row": 5, | ||
1062 | + "col": 11 | ||
1063 | + } | ||
1064 | + }, | ||
1065 | + "gridSettings": { | ||
1066 | + "backgroundColor": "#eeeeee", | ||
1067 | + "color": "rgba(0,0,0,0.870588)", | ||
1068 | + "columns": 24, | ||
1069 | + "margins": [ | ||
1070 | + 10, | ||
1071 | + 10 | ||
1072 | + ], | ||
1073 | + "backgroundSizeMode": "100%", | ||
1074 | + "autoFillHeight": true, | ||
1075 | + "mobileAutoFillHeight": false, | ||
1076 | + "mobileRowHeight": 70 | ||
1077 | + } | ||
1078 | + } | ||
1079 | + } | ||
1080 | + }, | ||
1081 | + "map": { | ||
1082 | + "name": "Edit location", | ||
1083 | + "root": false, | ||
1084 | + "layouts": { | ||
1085 | + "main": { | ||
1086 | + "widgets": { | ||
1087 | + "00fb2742-ba1f-7e43-673f-d6c08b72ed06": { | ||
1088 | + "sizeX": 24, | ||
1089 | + "sizeY": 12, | ||
1090 | + "row": 0, | ||
1091 | + "col": 0 | ||
1092 | + } | ||
1093 | + }, | ||
1094 | + "gridSettings": { | ||
1095 | + "backgroundColor": "#eeeeee", | ||
1096 | + "color": "rgba(0,0,0,0.870588)", | ||
1097 | + "columns": 24, | ||
1098 | + "margins": [ | ||
1099 | + 10, | ||
1100 | + 10 | ||
1101 | + ], | ||
1102 | + "backgroundSizeMode": "100%", | ||
1103 | + "autoFillHeight": true, | ||
1104 | + "mobileAutoFillHeight": false, | ||
1105 | + "mobileRowHeight": 70 | ||
1106 | + } | ||
1107 | + } | ||
1108 | + } | ||
1109 | + }, | ||
1110 | + "chart": { | ||
1111 | + "name": "${entityName}", | ||
1112 | + "root": false, | ||
1113 | + "layouts": { | ||
1114 | + "main": { | ||
1115 | + "widgets": { | ||
1116 | + "14a19183-f0b2-d6be-0f62-9863f0a51111": { | ||
1117 | + "sizeX": 18, | ||
1118 | + "sizeY": 6, | ||
1119 | + "mobileHeight": null, | ||
1120 | + "row": 0, | ||
1121 | + "col": 6 | ||
1122 | + }, | ||
1123 | + "07f49fd5-a73b-d74c-c220-362c20af81f4": { | ||
1124 | + "sizeX": 18, | ||
1125 | + "sizeY": 6, | ||
1126 | + "mobileHeight": null, | ||
1127 | + "row": 6, | ||
1128 | + "col": 6 | ||
1129 | + }, | ||
1130 | + "c4631f94-2db3-523b-4d09-2a1a0a75d93f": { | ||
1131 | + "sizeX": 6, | ||
1132 | + "sizeY": 6, | ||
1133 | + "row": 0, | ||
1134 | + "col": 0 | ||
1135 | + }, | ||
1136 | + "0a430429-9078-9ae6-2b67-e4a15a2bf8bf": { | ||
1137 | + "sizeX": 6, | ||
1138 | + "sizeY": 6, | ||
1139 | + "row": 6, | ||
1140 | + "col": 0 | ||
1141 | + } | ||
1142 | + }, | ||
1143 | + "gridSettings": { | ||
1144 | + "backgroundColor": "#eeeeee", | ||
1145 | + "color": "rgba(0,0,0,0.870588)", | ||
1146 | + "columns": 24, | ||
1147 | + "margins": [ | ||
1148 | + 10, | ||
1149 | + 10 | ||
1150 | + ], | ||
1151 | + "backgroundSizeMode": "100%", | ||
1152 | + "autoFillHeight": true, | ||
1153 | + "mobileAutoFillHeight": false, | ||
1154 | + "mobileRowHeight": 70 | ||
1155 | + } | ||
1156 | + } | ||
1157 | + } | ||
1158 | + } | ||
1159 | + }, | ||
1160 | + "entityAliases": { | ||
1161 | + "68a058e1-fdda-8482-715b-3ae4a488568e": { | ||
1162 | + "id": "68a058e1-fdda-8482-715b-3ae4a488568e", | ||
1163 | + "alias": "Thermostats", | ||
1164 | + "filter": { | ||
1165 | + "type": "deviceType", | ||
1166 | + "resolveMultiple": true, | ||
1167 | + "deviceType": "thermostat", | ||
1168 | + "deviceNameFilter": "" | ||
1169 | + } | ||
1170 | + }, | ||
1171 | + "12ae98c7-1ea2-52cf-64d5-763e9d993547": { | ||
1172 | + "id": "12ae98c7-1ea2-52cf-64d5-763e9d993547", | ||
1173 | + "alias": "Thermostat", | ||
1174 | + "filter": { | ||
1175 | + "type": "stateEntity", | ||
1176 | + "resolveMultiple": false, | ||
1177 | + "stateEntityParamName": null, | ||
1178 | + "defaultStateEntity": null | ||
1179 | + } | ||
1180 | + }, | ||
1181 | + "ce27a9d0-93bf-b7a4-054d-d0369a8cf813": { | ||
1182 | + "id": "ce27a9d0-93bf-b7a4-054d-d0369a8cf813", | ||
1183 | + "alias": "Thermostat-alarm", | ||
1184 | + "filter": { | ||
1185 | + "type": "entityName", | ||
1186 | + "resolveMultiple": false, | ||
1187 | + "entityType": "ASSET", | ||
1188 | + "entityNameFilter": "Thermostat Alarms" | ||
1189 | + } | ||
1190 | + } | ||
1191 | + }, | ||
1192 | + "timewindow": { | ||
1193 | + "displayValue": "", | ||
1194 | + "selectedTab": 0, | ||
1195 | + "hideInterval": false, | ||
1196 | + "hideAggregation": false, | ||
1197 | + "hideAggInterval": false, | ||
1198 | + "realtime": { | ||
1199 | + "interval": 1000, | ||
1200 | + "timewindowMs": 60000 | ||
1201 | + }, | ||
1202 | + "history": { | ||
1203 | + "historyType": 0, | ||
1204 | + "interval": 1000, | ||
1205 | + "timewindowMs": 60000, | ||
1206 | + "fixedTimewindow": { | ||
1207 | + "startTimeMs": 1587473857304, | ||
1208 | + "endTimeMs": 1587560257304 | ||
1209 | + } | ||
1210 | + }, | ||
1211 | + "aggregation": { | ||
1212 | + "type": "AVG", | ||
1213 | + "limit": 25000 | ||
1214 | + } | ||
1215 | + }, | ||
1216 | + "settings": { | ||
1217 | + "stateControllerId": "entity", | ||
1218 | + "showTitle": false, | ||
1219 | + "showDashboardsSelect": true, | ||
1220 | + "showEntitiesSelect": true, | ||
1221 | + "showDashboardTimewindow": true, | ||
1222 | + "showDashboardExport": true, | ||
1223 | + "toolbarAlwaysOpen": true | ||
1224 | + } | ||
1225 | + }, | ||
1226 | + "name": "Thermostats" | ||
1227 | +} |
1 | +{ | ||
2 | + "ruleChain": { | ||
3 | + "additionalInfo": null, | ||
4 | + "name": "Root Rule Chain", | ||
5 | + "firstRuleNodeId": null, | ||
6 | + "root": true, | ||
7 | + "debugMode": false, | ||
8 | + "configuration": null | ||
9 | + }, | ||
10 | + "metadata": { | ||
11 | + "firstNodeIndex": 3, | ||
12 | + "nodes": [ | ||
13 | + { | ||
14 | + "additionalInfo": { | ||
15 | + "layoutX": 1069, | ||
16 | + "layoutY": 267 | ||
17 | + }, | ||
18 | + "type": "org.thingsboard.rule.engine.filter.TbJsFilterNode", | ||
19 | + "name": "Is Thermostat?", | ||
20 | + "debugMode": false, | ||
21 | + "configuration": { | ||
22 | + "jsScript": "return msg.id.entityType === \"DEVICE\" && msg.type === \"thermostat\";" | ||
23 | + } | ||
24 | + }, | ||
25 | + { | ||
26 | + "additionalInfo": { | ||
27 | + "layoutX": 824, | ||
28 | + "layoutY": 156 | ||
29 | + }, | ||
30 | + "type": "org.thingsboard.rule.engine.telemetry.TbMsgTimeseriesNode", | ||
31 | + "name": "Save Timeseries", | ||
32 | + "debugMode": false, | ||
33 | + "configuration": { | ||
34 | + "defaultTTL": 0 | ||
35 | + } | ||
36 | + }, | ||
37 | + { | ||
38 | + "additionalInfo": { | ||
39 | + "layoutX": 825, | ||
40 | + "layoutY": 52 | ||
41 | + }, | ||
42 | + "type": "org.thingsboard.rule.engine.telemetry.TbMsgAttributesNode", | ||
43 | + "name": "Save Client Attributes", | ||
44 | + "debugMode": false, | ||
45 | + "configuration": { | ||
46 | + "scope": "CLIENT_SCOPE" | ||
47 | + } | ||
48 | + }, | ||
49 | + { | ||
50 | + "additionalInfo": { | ||
51 | + "layoutX": 347, | ||
52 | + "layoutY": 149 | ||
53 | + }, | ||
54 | + "type": "org.thingsboard.rule.engine.filter.TbMsgTypeSwitchNode", | ||
55 | + "name": "Message Type Switch", | ||
56 | + "debugMode": false, | ||
57 | + "configuration": { | ||
58 | + "version": 0 | ||
59 | + } | ||
60 | + }, | ||
61 | + { | ||
62 | + "additionalInfo": { | ||
63 | + "layoutX": 839, | ||
64 | + "layoutY": 345 | ||
65 | + }, | ||
66 | + "type": "org.thingsboard.rule.engine.action.TbLogNode", | ||
67 | + "name": "Log RPC from Device", | ||
68 | + "debugMode": false, | ||
69 | + "configuration": { | ||
70 | + "jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);" | ||
71 | + } | ||
72 | + }, | ||
73 | + { | ||
74 | + "additionalInfo": { | ||
75 | + "layoutX": 832, | ||
76 | + "layoutY": 407 | ||
77 | + }, | ||
78 | + "type": "org.thingsboard.rule.engine.action.TbLogNode", | ||
79 | + "name": "Log Other", | ||
80 | + "debugMode": false, | ||
81 | + "configuration": { | ||
82 | + "jsScript": "return '\\nIncoming message:\\n' + JSON.stringify(msg) + '\\nIncoming metadata:\\n' + JSON.stringify(metadata);" | ||
83 | + } | ||
84 | + }, | ||
85 | + { | ||
86 | + "additionalInfo": { | ||
87 | + "layoutX": 825, | ||
88 | + "layoutY": 468 | ||
89 | + }, | ||
90 | + "type": "org.thingsboard.rule.engine.rpc.TbSendRPCRequestNode", | ||
91 | + "name": "RPC Call Request", | ||
92 | + "debugMode": false, | ||
93 | + "configuration": { | ||
94 | + "timeoutInSeconds": 60 | ||
95 | + } | ||
96 | + }, | ||
97 | + { | ||
98 | + "additionalInfo": { | ||
99 | + "layoutX": 1069, | ||
100 | + "layoutY": 90 | ||
101 | + }, | ||
102 | + "type": "org.thingsboard.rule.engine.filter.TbJsFilterNode", | ||
103 | + "name": "Is Thermostat?", | ||
104 | + "debugMode": false, | ||
105 | + "configuration": { | ||
106 | + "jsScript": "return metadata[\"deviceType\"] === \"thermostat\";" | ||
107 | + } | ||
108 | + }, | ||
109 | + { | ||
110 | + "additionalInfo": { | ||
111 | + "layoutX": 1090, | ||
112 | + "layoutY": 360 | ||
113 | + }, | ||
114 | + "type": "org.thingsboard.rule.engine.action.TbCreateRelationNode", | ||
115 | + "name": "Relate to Asset", | ||
116 | + "debugMode": false, | ||
117 | + "configuration": { | ||
118 | + "direction": "FROM", | ||
119 | + "relationType": "ToAlarmPropagationAsset", | ||
120 | + "entityType": "ASSET", | ||
121 | + "entityNamePattern": "Thermostat Alarms", | ||
122 | + "entityTypePattern": "AlarmPropagationAsset", | ||
123 | + "entityCacheExpiration": 300, | ||
124 | + "createEntityIfNotExists": true, | ||
125 | + "changeOriginatorToRelatedEntity": false, | ||
126 | + "removeCurrentRelations": false | ||
127 | + } | ||
128 | + } | ||
129 | + ], | ||
130 | + "connections": [ | ||
131 | + { | ||
132 | + "fromIndex": 0, | ||
133 | + "toIndex": 8, | ||
134 | + "type": "True" | ||
135 | + }, | ||
136 | + { | ||
137 | + "fromIndex": 1, | ||
138 | + "toIndex": 7, | ||
139 | + "type": "Success" | ||
140 | + }, | ||
141 | + { | ||
142 | + "fromIndex": 3, | ||
143 | + "toIndex": 5, | ||
144 | + "type": "Other" | ||
145 | + }, | ||
146 | + { | ||
147 | + "fromIndex": 3, | ||
148 | + "toIndex": 2, | ||
149 | + "type": "Post attributes" | ||
150 | + }, | ||
151 | + { | ||
152 | + "fromIndex": 3, | ||
153 | + "toIndex": 1, | ||
154 | + "type": "Post telemetry" | ||
155 | + }, | ||
156 | + { | ||
157 | + "fromIndex": 3, | ||
158 | + "toIndex": 4, | ||
159 | + "type": "RPC Request from Device" | ||
160 | + }, | ||
161 | + { | ||
162 | + "fromIndex": 3, | ||
163 | + "toIndex": 6, | ||
164 | + "type": "RPC Request to Device" | ||
165 | + }, | ||
166 | + { | ||
167 | + "fromIndex": 3, | ||
168 | + "toIndex": 0, | ||
169 | + "type": "Entity Created" | ||
170 | + } | ||
171 | + ], | ||
172 | + "ruleChainConnections": [ | ||
173 | + { | ||
174 | + "fromIndex": 7, | ||
175 | + "targetRuleChainId": { | ||
176 | + "entityType": "RULE_CHAIN", | ||
177 | + "id": "25e26570-89ed-11ea-a650-cd6e14e633bd" | ||
178 | + }, | ||
179 | + "additionalInfo": { | ||
180 | + "layoutX": 1109, | ||
181 | + "layoutY": 182, | ||
182 | + "ruleChainNodeId": "rule-chain-node-10" | ||
183 | + }, | ||
184 | + "type": "True" | ||
185 | + } | ||
186 | + ] | ||
187 | + } | ||
188 | +} |
1 | +{ | ||
2 | + "ruleChain": { | ||
3 | + "additionalInfo": null, | ||
4 | + "name": "Thermostat Alarms", | ||
5 | + "firstRuleNodeId": null, | ||
6 | + "root": false, | ||
7 | + "debugMode": false, | ||
8 | + "configuration": null | ||
9 | + }, | ||
10 | + "metadata": { | ||
11 | + "firstNodeIndex": 5, | ||
12 | + "nodes": [ | ||
13 | + { | ||
14 | + "additionalInfo": { | ||
15 | + "layoutX": 929, | ||
16 | + "layoutY": 67 | ||
17 | + }, | ||
18 | + "type": "org.thingsboard.rule.engine.action.TbCreateAlarmNode", | ||
19 | + "name": "Create Temp Alarm", | ||
20 | + "debugMode": false, | ||
21 | + "configuration": { | ||
22 | + "alarmType": "High Temperature", | ||
23 | + "alarmDetailsBuildJs": "var details = {};\nif (metadata.prevAlarmDetails) {\n details = JSON.parse(metadata.prevAlarmDetails);\n}\ndetails.triggerValue = msg.temperature;\nreturn details;", | ||
24 | + "severity": "MAJOR", | ||
25 | + "propagate": true, | ||
26 | + "useMessageAlarmData": false, | ||
27 | + "relationTypes": [ | ||
28 | + "ToAlarmPropagationAsset" | ||
29 | + ] | ||
30 | + } | ||
31 | + }, | ||
32 | + { | ||
33 | + "additionalInfo": { | ||
34 | + "layoutX": 930, | ||
35 | + "layoutY": 201 | ||
36 | + }, | ||
37 | + "type": "org.thingsboard.rule.engine.action.TbClearAlarmNode", | ||
38 | + "name": "Clear Temp Alarm", | ||
39 | + "debugMode": false, | ||
40 | + "configuration": { | ||
41 | + "alarmType": "High Temperature", | ||
42 | + "alarmDetailsBuildJs": "var details = {};\nif (metadata.prevAlarmDetails) {\n details = JSON.parse(metadata.prevAlarmDetails);\n}\nreturn details;" | ||
43 | + } | ||
44 | + }, | ||
45 | + { | ||
46 | + "additionalInfo": { | ||
47 | + "layoutX": 930, | ||
48 | + "layoutY": 131 | ||
49 | + }, | ||
50 | + "type": "org.thingsboard.rule.engine.action.TbCreateAlarmNode", | ||
51 | + "name": "Create Humidity Alarm", | ||
52 | + "debugMode": false, | ||
53 | + "configuration": { | ||
54 | + "alarmType": "Low Humidity", | ||
55 | + "alarmDetailsBuildJs": "var details = {};\nif (metadata.prevAlarmDetails) {\n details = JSON.parse(metadata.prevAlarmDetails);\n}\ndetails.triggerValue = msg.humidity;\nreturn details;", | ||
56 | + "severity": "MINOR", | ||
57 | + "propagate": true, | ||
58 | + "useMessageAlarmData": false, | ||
59 | + "relationTypes": [ | ||
60 | + "ToAlarmPropagationAsset" | ||
61 | + ] | ||
62 | + } | ||
63 | + }, | ||
64 | + { | ||
65 | + "additionalInfo": { | ||
66 | + "layoutX": 929, | ||
67 | + "layoutY": 275 | ||
68 | + }, | ||
69 | + "type": "org.thingsboard.rule.engine.action.TbClearAlarmNode", | ||
70 | + "name": "Clear Humidity Alarm", | ||
71 | + "debugMode": false, | ||
72 | + "configuration": { | ||
73 | + "alarmType": "Low Humidity", | ||
74 | + "alarmDetailsBuildJs": "var details = {};\nif (metadata.prevAlarmDetails) {\n details = JSON.parse(metadata.prevAlarmDetails);\n}\nreturn details;" | ||
75 | + } | ||
76 | + }, | ||
77 | + { | ||
78 | + "additionalInfo": { | ||
79 | + "layoutX": 586, | ||
80 | + "layoutY": 148 | ||
81 | + }, | ||
82 | + "type": "org.thingsboard.rule.engine.filter.TbJsSwitchNode", | ||
83 | + "name": "Check Alarms", | ||
84 | + "debugMode": false, | ||
85 | + "configuration": { | ||
86 | + "jsScript": "var relations = [];\nif(metadata[\"ss_alarmTemperature\"] === \"true\"){\n if(msg.temperature > metadata[\"ss_thresholdTemperature\"]){\n relations.push(\"NewTempAlarm\");\n } else {\n relations.push(\"ClearTempAlarm\");\n }\n}\nif(metadata[\"ss_alarmHumidity\"] === \"true\"){\n if(msg.humidity < metadata[\"ss_thresholdHumidity\"]){\n relations.push(\"NewHumidityAlarm\");\n } else {\n relations.push(\"ClearHumidityAlarm\");\n }\n}\n\nreturn relations;" | ||
87 | + } | ||
88 | + }, | ||
89 | + { | ||
90 | + "additionalInfo": { | ||
91 | + "layoutX": 321, | ||
92 | + "layoutY": 149 | ||
93 | + }, | ||
94 | + "type": "org.thingsboard.rule.engine.metadata.TbGetAttributesNode", | ||
95 | + "name": "Fetch Configuration", | ||
96 | + "debugMode": false, | ||
97 | + "configuration": { | ||
98 | + "clientAttributeNames": [], | ||
99 | + "sharedAttributeNames": [], | ||
100 | + "serverAttributeNames": [ | ||
101 | + "alarmTemperature", | ||
102 | + "thresholdTemperature", | ||
103 | + "alarmHumidity", | ||
104 | + "thresholdHumidity" | ||
105 | + ], | ||
106 | + "latestTsKeyNames": [], | ||
107 | + "tellFailureIfAbsent": false, | ||
108 | + "getLatestValueWithTs": false | ||
109 | + } | ||
110 | + } | ||
111 | + ], | ||
112 | + "connections": [ | ||
113 | + { | ||
114 | + "fromIndex": 4, | ||
115 | + "toIndex": 0, | ||
116 | + "type": "NewTempAlarm" | ||
117 | + }, | ||
118 | + { | ||
119 | + "fromIndex": 4, | ||
120 | + "toIndex": 1, | ||
121 | + "type": "ClearTempAlarm" | ||
122 | + }, | ||
123 | + { | ||
124 | + "fromIndex": 4, | ||
125 | + "toIndex": 2, | ||
126 | + "type": "NewHumidityAlarm" | ||
127 | + }, | ||
128 | + { | ||
129 | + "fromIndex": 4, | ||
130 | + "toIndex": 3, | ||
131 | + "type": "ClearHumidityAlarm" | ||
132 | + }, | ||
133 | + { | ||
134 | + "fromIndex": 5, | ||
135 | + "toIndex": 4, | ||
136 | + "type": "Success" | ||
137 | + } | ||
138 | + ], | ||
139 | + "ruleChainConnections": null | ||
140 | + } | ||
141 | +} |
@@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
6 | }, | 6 | }, |
7 | "widgetTypes": [ | 7 | "widgetTypes": [ |
8 | { | 8 | { |
9 | - "alias": "device_admin_table2", | 9 | + "alias": "device_admin_table", |
10 | "name": "Device admin table", | 10 | "name": "Device admin table", |
11 | "descriptor": { | 11 | "descriptor": { |
12 | "type": "latest", | 12 | "type": "latest", |
@@ -22,7 +22,7 @@ | @@ -22,7 +22,7 @@ | ||
22 | } | 22 | } |
23 | }, | 23 | }, |
24 | { | 24 | { |
25 | - "alias": "device_admin_table", | 25 | + "alias": "asset_admin_table", |
26 | "name": "Asset admin table", | 26 | "name": "Asset admin table", |
27 | "descriptor": { | 27 | "descriptor": { |
28 | "type": "latest", | 28 | "type": "latest", |
@@ -6,6 +6,38 @@ | @@ -6,6 +6,38 @@ | ||
6 | }, | 6 | }, |
7 | "widgetTypes": [ | 7 | "widgetTypes": [ |
8 | { | 8 | { |
9 | + "alias": "attributes_card", | ||
10 | + "name": "Gateway events", | ||
11 | + "descriptor": { | ||
12 | + "type": "latest", | ||
13 | + "sizeX": 7.5, | ||
14 | + "sizeY": 8, | ||
15 | + "resources": [], | ||
16 | + "templateHtml": "", | ||
17 | + "templateCss": "#container {\n overflow: auto;\n}\n\n.tbDatasource-container {\n margin: 5px;\n padding: 8px;\n}\n\n.tbDatasource-title {\n font-size: 1.200rem;\n font-weight: 500;\n padding-bottom: 10px;\n}\n\n.tbDatasource-table {\n width: 100%;\n box-shadow: 0 0 10px #ccc;\n border-collapse: collapse;\n white-space: nowrap;\n font-size: 1.000rem;\n color: #757575;\n}\n\n.tbDatasource-table td {\n position: relative;\n border-top: 1px solid rgba(0, 0, 0, 0.12);\n border-bottom: 1px solid rgba(0, 0, 0, 0.12);\n padding: 0px 18px;\n box-sizing: border-box;\n}", | ||
18 | + "controllerScript": "let types;\nlet eventsReg = \"eventsReg\";\n\nself.onInit = function() {\n \n self.ctx.datasourceTitleCells = [];\n self.ctx.valueCells = [];\n self.ctx.labelCells = [];\n types = self.ctx.$scope.$injector.get('types');\n \n if (self.ctx.datasources.length && self.ctx.datasources[0].type === types.datasourceType.entity) {\n getDatasourceKeys(self.ctx.datasources[0]);\n } else {\n processDatasources(self.ctx.datasources);\n }\n}\n\nself.onDataUpdated = function() {\n for (var i = 0; i < self.ctx.valueCells.length; i++) {\n var cellData = self.ctx.data[i];\n if (cellData && cellData.data && cellData.data.length > 0) {\n var tvPair = cellData.data[cellData.data.length -\n 1];\n var value = tvPair[1];\n var textValue;\n //toDo -> + IsNumber\n \n if (isNumber(value)) {\n var decimals = self.ctx.decimals;\n var units = self.ctx.units;\n if (cellData.dataKey.decimals || cellData.dataKey.decimals === 0) {\n decimals = cellData.dataKey.decimals;\n }\n if (cellData.dataKey.units) {\n units = cellData.dataKey.units;\n }\n txtValue = self.ctx.utils.formatValue(value, decimals, units, false);\n }\n else {\n txtValue = value;\n }\n self.ctx.valueCells[i].html(txtValue);\n }\n }\n \n function isNumber(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n }\n}\n\nself.onResize = function() {\n var datasourceTitleFontSize = self.ctx.height/8;\n if (self.ctx.width/self.ctx.height <= 1.5) {\n datasourceTitleFontSize = self.ctx.width/12;\n }\n datasourceTitleFontSize = Math.min(datasourceTitleFontSize, 20);\n for (var i = 0; i < self.ctx.datasourceTitleCells.length; i++) {\n self.ctx.datasourceTitleCells[i].css('font-size', datasourceTitleFontSize+'px');\n }\n var valueFontSize = self.ctx.height/9;\n var labelFontSize = self.ctx.height/9;\n if (self.ctx.width/self.ctx.height <= 1.5) {\n valueFontSize = self.ctx.width/15;\n labelFontSize = self.ctx.width/15;\n }\n valueFontSize = Math.min(valueFontSize, 18);\n labelFontSize = Math.min(labelFontSize, 18);\n\n for (i = 0; i < self.ctx.valueCells; i++) {\n self.ctx.valueCells[i].css('font-size', valueFontSize+'px');\n self.ctx.valueCells[i].css('height', valueFontSize*2.5+'px');\n self.ctx.valueCells[i].css('padding', '0px ' + valueFontSize + 'px');\n self.ctx.labelCells[i].css('font-size', labelFontSize+'px');\n self.ctx.labelCells[i].css('height', labelFontSize*2.5+'px');\n self.ctx.labelCells[i].css('padding', '0px ' + labelFontSize + 'px');\n } \n}\n\nfunction processDatasources(datasources) {\n var i = 0;\n var tbDatasource = datasources[i];\n var datasourceId = 'tbDatasource' + i;\n self.ctx.$container.append(\n \"<div id='\" + datasourceId +\n \"' class='tbDatasource-container'></div>\"\n );\n\n var datasourceContainer = $('#' + datasourceId,\n self.ctx.$container);\n\n datasourceContainer.append(\n \"<div class='tbDatasource-title'>\" +\n tbDatasource.name + \"</div>\"\n );\n \n var datasourceTitleCell = $('.tbDatasource-title', datasourceContainer);\n self.ctx.datasourceTitleCells.push(datasourceTitleCell);\n \n var tableId = 'table' + i;\n datasourceContainer.append(\n \"<table id='\" + tableId +\n \"' class='tbDatasource-table'><col width='30%'><col width='70%'></table>\"\n );\n var table = $('#' + tableId, self.ctx.$container);\n\n for (var a = 0; a < tbDatasource.dataKeys.length; a++) {\n var dataKey = tbDatasource.dataKeys[a];\n var labelCellId = 'labelCell' + a;\n var cellId = 'cell' + a;\n table.append(\"<tr><td id='\" + labelCellId + \"'>\" + dataKey.label +\n \"</td><td id='\" + cellId +\n \"'></td></tr>\");\n var labelCell = $('#' + labelCellId, table);\n self.ctx.labelCells.push(labelCell);\n var valueCell = $('#' + cellId, table);\n self.ctx.valueCells.push(valueCell);\n }\n self.onResize();\n}\n\nfunction getDatasourceKeys (datasource) {\n let attributeService = self.ctx.$scope.$injector.get('attributeService');\n if (datasource.entityId && datasource.entityType) {\n attributeService.getEntityKeys(datasource.entityType, datasource.entityId, \"\" , types.dataKeyType.timeseries).then(\n function(data){\n if (data.length) {\n subscribeForKeys (datasource, data);\n }\n });\n }\n}\n\nfunction subscribeForKeys (datasource, data) {\n let eventsRegVals = self.ctx.settings[eventsReg];\n if (eventsRegVals && eventsRegVals.length > 0) {\n var dataKeys = [];\n data.sort();\n data.forEach(dataValue => {eventsRegVals.forEach(event => {\n if (dataValue.toLowerCase().includes(event.toLowerCase())) {\n var dataKey = {\n type: types.dataKeyType.timeseries,\n name: dataValue,\n label: dataValue,\n settings: {},\n _hash: Math.random()\n };\n dataKeys.push(dataKey);\n }\n })});\n\n if (dataKeys.length) {\n updateSubscription (datasource, dataKeys);\n }\n }\n}\n\nfunction updateSubscription (datasource, dataKeys) {\n var datasources = [\n {\n type: types.datasourceType.entity,\n name: datasource.aliasName,\n aliasName: datasource.aliasName,\n entityAliasId: datasource.entityAliasId,\n dataKeys: dataKeys\n }\n ];\n \n var subscriptionOptions = {\n datasources: datasources,\n useDashboardTimewindow: false,\n type: types.widgetType.latest.value,\n callbacks: {\n onDataUpdated: (subscription) => {\n self.ctx.data = subscription.data;\n self.onDataUpdated();\n }\n }\n };\n \n processDatasources(datasources);\n self.ctx.subscriptionApi.createSubscription(subscriptionOptions, true).then(\n (subscription) => {\n self.ctx.defaultSubscription = subscription;\n }\n );\n}\n\nself.onDestroy = function() {\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\t\n dataKeysOptional: true\n };\n}\n\n", | ||
19 | + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"GatewayEventsForm\",\n \"properties\": {\n \"eventsTitle\": {\n \"title\": \"Gateway events form title\",\n \"type\": \"string\",\n \"default\": \"Gateway Events Form\"\n },\n \"eventsReg\": {\n \"title\": \"Events filten.\",\n \"type\": \"array\",\n \"items\": {\n \"title\": \"Event key contains\",\n \"type\": \"string\"\n }\n }\n }\n },\n \"form\": [\n \"eventsTitle\",\n \"eventsReg\"\n ]\n}", | ||
20 | + "dataKeySettingsSchema": "{}\n", | ||
21 | + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Function Math.round\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.826503672916844,\"funcBody\":\"return Math.round(1000*Math.sin(time/5000));\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"eventsTitle\":\"Gateway Events Form\",\"eventsReg\":[]},\"title\":\"Gateway events\",\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"showLegend\":false,\"actions\":{}}" | ||
22 | + } | ||
23 | + }, | ||
24 | + { | ||
25 | + "alias": "config_form_latest", | ||
26 | + "name": "Gateway configuration (Single device)", | ||
27 | + "descriptor": { | ||
28 | + "type": "latest", | ||
29 | + "sizeX": 7.5, | ||
30 | + "sizeY": 9, | ||
31 | + "resources": [], | ||
32 | + "templateHtml": "<tb-gateway-form\n form-id=\"formId\"\n ctx=\"ctx\"\n is-state-form=\"isStateForm\">\n</tb-gateway-form>", | ||
33 | + "templateCss": "#container {\n overflow: auto;\n}\n\n.tbDatasource-container {\n margin: 5px;\n padding: 8px;\n}\n\n.tbDatasource-title {\n font-size: 1.200rem;\n font-weight: 500;\n padding-bottom: 10px;\n}\n\n.tbDatasource-table {\n width: 100%;\n box-shadow: 0 0 10px #ccc;\n border-collapse: collapse;\n white-space: nowrap;\n font-size: 1.000rem;\n color: #757575;\n}\n\n.tbDatasource-table td {\n position: relative;\n border-top: 1px solid rgba(0, 0, 0, 0.12);\n border-bottom: 1px solid rgba(0, 0, 0, 0.12);\n padding: 0px 18px;\n box-sizing: border-box;\n}", | ||
34 | + "controllerScript": "self.onInit = function() {\n var scope = self.ctx.$scope;\n var id = self.ctx.$scope.$injector.get('utils').guid();\n scope.formId = \"form-\"+id;\n scope.ctx = self.ctx;\n scope.isStateForm = true;\n}\n\nself.onResize = function() {\n self.ctx.$scope.$broadcast('gateway-form-resize', self.ctx.$scope.formId);\n}\n\n\nself.onDestroy = function() {\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\t\t\t\n dataKeysOptional: true\t\t\n };\n}\n\n", | ||
35 | + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"GatewayConfigForm\",\n \"properties\": {\n \"gatewayTitle\": {\n \"title\": \"Gateway form\",\n \"type\": \"string\",\n \"default\": \"Gateway configuration (Single device)\"\n },\n \"readOnly\": {\n \"title\": \"Read Only\",\n \"type\": \"boolean\",\n \"default\": false\n }\n }\n },\n \"form\": [\n \"gatewayTitle\",\n \"readOnly\"\n ]\n}\n", | ||
36 | + "dataKeySettingsSchema": "{}\n", | ||
37 | + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{},\"title\":\"Gateway configuration (Single device)\"}" | ||
38 | + } | ||
39 | + }, | ||
40 | + { | ||
9 | "alias": "extension_configuration_widget", | 41 | "alias": "extension_configuration_widget", |
10 | "name": "Extensions table", | 42 | "name": "Extensions table", |
11 | "descriptor": { | 43 | "descriptor": { |
@@ -20,6 +52,22 @@ | @@ -20,6 +52,22 @@ | ||
20 | "dataKeySettingsSchema": "{}\n", | 52 | "dataKeySettingsSchema": "{}\n", |
21 | "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{},\"title\":\"Extensions table\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"18px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}" | 53 | "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"4px\",\"settings\":{},\"title\":\"Extensions table\",\"dropShadow\":true,\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"18px\",\"fontWeight\":400,\"padding\":\"5px 10px 5px 10px\"},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{}}" |
22 | } | 54 | } |
55 | + }, | ||
56 | + { | ||
57 | + "alias": "gateway_configuration", | ||
58 | + "name": "Gateway Configuration", | ||
59 | + "descriptor": { | ||
60 | + "type": "static", | ||
61 | + "sizeX": 8, | ||
62 | + "sizeY": 6.5, | ||
63 | + "resources": [], | ||
64 | + "templateHtml": "<tb-gateway-form\n form-id=\"formId\"\n ctx=\"ctx\">\n</tb-gateway-form>\n", | ||
65 | + "templateCss": "", | ||
66 | + "controllerScript": "self.onInit = function() {\n var scope = self.ctx.$scope;\n var id = self.ctx.$scope.$injector.get('utils').guid();\n scope.formId = \"form-\"+id;\n scope.ctx = self.ctx;\n}\n\nself.onResize = function() {\n self.ctx.$scope.$broadcast('gateway-form-resize', self.ctx.$scope.formId);\n}\n", | ||
67 | + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"widgetTitle\": {\n \"title\": \"Widget title\",\n \"type\": \"string\",\n \"default\": \"Gateway Configuration\"\n },\n \"archiveFileName\": {\n \"title\": \"Default archive file name\",\n \"type\": \"string\",\n \"default\": \"gatewayConfiguration\"\n },\n \"gatewayType\": {\n \"title\": \"Device type for new gateway\",\n \"type\": \"string\",\n \"default\": \"Gateway\"\n },\n \"successfulSave\": {\n \"title\": \"Text message about successfully saved gateway configuration\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"gatewayNameExists\": {\n \"title\": \"Text message when device with entered name is already exists\",\n \"type\": \"string\",\n \"default\": \"\"\n }\n },\n \"required\": []\n },\n \"form\": [\n [\n \"widgetTitle\",\n \"archiveFileName\",\n \"gatewayType\"\n ],\n [\n \"successfulSave\",\n \"gatewayNameExists\"\n ]\n ],\n \"groupInfoes\": [{\n \"formIndex\": 0,\n \"GroupTitle\": \"General settings\"\n }, {\n \"formIndex\": 1,\n \"GroupTitle\": \"Messages settings\"\n }]\n}", | ||
68 | + "dataKeySettingsSchema": "{}\n", | ||
69 | + "defaultConfig": "{\"datasources\":[{\"type\":\"static\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"rgb(255, 255, 255)\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"widgetTitle\":\"Gateway Configuration\",\"archiveFileName\":\"configurationGateway\"},\"title\":\"Gateway Configuration\",\"dropShadow\":true,\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"enableFullscreen\":true,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"showLegend\":false,\"actions\":{}}" | ||
70 | + } | ||
23 | } | 71 | } |
24 | ] | 72 | ] |
25 | -} | ||
73 | +} |
@@ -330,13 +330,13 @@ | @@ -330,13 +330,13 @@ | ||
330 | "name": "Web Camera Input", | 330 | "name": "Web Camera Input", |
331 | "descriptor": { | 331 | "descriptor": { |
332 | "type": "latest", | 332 | "type": "latest", |
333 | - "sizeX": 9.5, | ||
334 | - "sizeY": 6.5, | 333 | + "sizeX": 7.5, |
334 | + "sizeY": 3, | ||
335 | "resources": [], | 335 | "resources": [], |
336 | "templateHtml": "<tb-web-camera-widget ctx=\"ctx\">\n</tb-web-camera-widget>", | 336 | "templateHtml": "<tb-web-camera-widget ctx=\"ctx\">\n</tb-web-camera-widget>", |
337 | - "templateCss": "#container {\n overflow: auto;\n}\n\n.tbDatasource-container {\n margin: 5px;\n padding: 8px;\n}\n\n.tbDatasource-title {\n font-size: 1.200rem;\n font-weight: 500;\n padding-bottom: 10px;\n}\n\n.tbDatasource-table {\n width: 100%;\n box-shadow: 0 0 10px #ccc;\n border-collapse: collapse;\n white-space: nowrap;\n font-size: 1.000rem;\n color: #757575;\n}\n\n.tbDatasource-table td {\n position: relative;\n border-top: 1px solid rgba(0, 0, 0, 0.12);\n border-bottom: 1px solid rgba(0, 0, 0, 0.12);\n padding: 0px 18px;\n box-sizing: border-box;\n}", | 337 | + "templateCss": "", |
338 | "controllerScript": "self.onInit = function() {\n var scope = self.ctx.$scope;\n scope.ctx = self.ctx;\n}\n\nself.onDataUpdated = function() {\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n maxDataKeys: 1\n }\n}\n\nself.onDestroy = function() {\n}\n", | 338 | "controllerScript": "self.onInit = function() {\n var scope = self.ctx.$scope;\n scope.ctx = self.ctx;\n}\n\nself.onDataUpdated = function() {\n}\n\nself.typeParameters = function() {\n return {\n maxDatasources: 1,\n maxDataKeys: 1\n }\n}\n\nself.onDestroy = function() {\n}\n", |
339 | - "settingsSchema": "{}", | 339 | + "settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Web Camera\",\n \"properties\": {\n \"widgetTitle\": {\n \"title\": \"Widget title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"imageFormat\": {\n \"title\": \"Image Format\",\n \"type\": \"string\",\n \"default\": \"image/png\"\n },\n \"imageQuality\":{\n \"title\":\"Image quality that use lossy compression such as jpeg and webp\",\n \"type\":\"number\",\n \"default\": 0.92,\n \"min\": 0,\n \"max\": 1\n },\n \"maxWidth\": {\n \"title\": \"The maximal image width\",\n \"type\": \"number\",\n \"default\": 640\n }, \n \"maxHeight\": {\n \"title\": \"The maximal image heigth\",\n \"type\": \"number\",\n \"default\": 480\n }\n },\n \"required\": []\n },\n \"form\": [\n \"widgetTitle\",\n {\n \"key\": \"imageFormat\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [\n {\n \"value\": \"image/jpeg\",\n \"label\": \"JPEG\"\n },\n {\n \"value\": \"image/png\",\n \"label\": \"PNG\"\n },\n {\n \"value\": \"image/webp\",\n \"label\": \"WEBP\"\n }\n ]\n },\n \"imageQuality\",\n \"maxWidth\",\n \"maxHeight\"\n ]\n}", |
340 | "dataKeySettingsSchema": "{}\n", | 340 | "dataKeySettingsSchema": "{}\n", |
341 | "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{},\"title\":\"Web Camera Input\",\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"showLegend\":false,\"actions\":{}}" | 341 | "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{},\"title\":\"Web Camera Input\",\"showTitleIcon\":false,\"titleIcon\":\"more_horiz\",\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"showLegend\":false,\"actions\":{}}" |
342 | } | 342 | } |
@@ -128,10 +128,10 @@ | @@ -128,10 +128,10 @@ | ||
128 | "templateHtml": "<trip-animation self=\"self\" ctx=\"self.ctx\" ></trip-animation>", | 128 | "templateHtml": "<trip-animation self=\"self\" ctx=\"self.ctx\" ></trip-animation>", |
129 | "templateCss": ".legend {\n font-size: 13px;\n line-height: 10px;\n}\n\n.legend table { \n border-spacing: 0px;\n border-collapse: separate;\n}\n\n.mouse-events .flot-overlay {\n cursor: crosshair; \n}\n\n", | 129 | "templateCss": ".legend {\n font-size: 13px;\n line-height: 10px;\n}\n\n.legend table { \n border-spacing: 0px;\n border-collapse: separate;\n}\n\n.mouse-events .flot-overlay {\n cursor: crosshair; \n}\n\n", |
130 | "controllerScript": " self.onInit = function() {\n var $scope = self.ctx.$scope;\n $scope.self = self;\n }\n \n \n self.actionSources = function () {\n return {\n 'tooltipAction': {\n name: 'widget-action.tooltip-tag-action',\n multiple: false\n }\n }\n };\n", | 130 | "controllerScript": " self.onInit = function() {\n var $scope = self.ctx.$scope;\n $scope.self = self;\n }\n \n \n self.actionSources = function () {\n return {\n 'tooltipAction': {\n name: 'widget-action.tooltip-tag-action',\n multiple: false\n }\n }\n };\n", |
131 | - "settingsSchema": "{\n \"schema\": {\n \"title\": \"Openstreet Map Configuration\",\n \"type\": \"object\",\n \"properties\": {\n \"mapProvider\": {\n \"title\": \"Map provider\",\n \"type\": \"string\",\n \"default\": \"OpenStreetMap.Mapnik\"\n },\n \"normalizationStep\": {\n \"title\": \"Normalization data step (ms)\",\n \"type\": \"number\",\n \"default\": 1000\n },\n \"latKeyName\": {\n \"title\": \"Latitude key name\",\n \"type\": \"string\",\n \"default\": \"latitude\"\n },\n \"lngKeyName\": {\n \"title\": \"Longitude key name\",\n \"type\": \"string\",\n \"default\": \"longitude\"\n },\n \"polKeyName\": {\n \"title\": \"Polygon key name\",\n \"type\": \"string\",\n \"default\": \"coordinates\"\n },\n \"showLabel\": {\n \"title\": \"Show label\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"label\": {\n \"title\": \"Label (pattern examples: '${entityName}', '${entityName}: (Text ${keyName} units.)' )\",\n \"type\": \"string\",\n \"default\": \"${entityName}\"\n },\n \"useLabelFunction\": {\n \"title\": \"Use label function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"labelFunction\": {\n \"title\": \"Label function: f(data, dsData, dsIndex)\",\n \"type\": \"string\"\n },\n \"showTooltip\": {\n \"title\": \"Show tooltip\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"tooltipColor\": {\n \"title\": \"Tooltip background color\",\n \"type\": \"string\",\n \"default\": \"#fff\"\n },\n \"tooltipFontColor\": {\n \"title\": \"Tooltip font color\",\n \"type\": \"string\",\n \"default\": \"#000\"\n },\n \"tooltipOpacity\": {\n \"title\": \"Tooltip opacity (0-1)\",\n \"type\": \"number\",\n \"default\": 1\n },\n \"tooltipPattern\": {\n \"title\": \"Tooltip (for ex. 'Text ${keyName} units.' or <link-act name='my-action'>Link text</link-act>')\",\n \"type\": \"string\",\n \"default\": \"<b>${entityName}</b><br/><br/><b>Latitude:</b> ${latitude:7}<br/><b>Longitude:</b> ${longitude:7}\"\n },\n \"useTooltipFunction\": {\n \"title\": \"Use tooltip function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"tooltipFunction\": {\n \"title\": \"Tooltip function: f(data, dsData, dsIndex)\",\n \"type\": \"string\"\n },\n \"color\": {\n \"title\": \"Path color\",\n \"type\": \"string\"\n },\n \"strokeWeight\": {\n \"title\": \"Stroke weight\",\n \"type\": \"number\",\n \"default\": 2\n },\n \"strokeOpacity\": {\n \"title\": \"Stroke opacity\",\n \"type\": \"number\",\n \"default\": 1\n },\n \"useColorFunction\": {\n \"title\": \"Use path color function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"colorFunction\": {\n \"title\": \"Path color function: f(data, dsData, dsIndex)\",\n \"type\": \"string\"\n },\n \"usePolylineDecorator\": {\n \"title\": \"Use path decorator\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"decoratorSymbol\": {\n \"title\": \"Decorator symbol\",\n \"type\": \"string\",\n \"default\": \"arrowHead\"\n },\n \"decoratorSymbolSize\": {\n \"title\": \"Decorator symbol size (px)\",\n \"type\": \"number\",\n \"default\": 10\n },\n \"useDecoratorCustomColor\": {\n \"title\": \"Use path decorator custom color\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"decoratorCustomColor\": {\n \"title\": \"Decorator custom color\",\n \"type\": \"string\",\n \"default\": \"#000\"\n },\n \"decoratorOffset\": {\n \"title\": \"Decorator offset\",\n \"type\": \"string\",\n \"default\": \"20px\"\n },\n \"endDecoratorOffset\": {\n \"title\": \"End decorator offset\",\n \"type\": \"string\",\n \"default\": \"20px\"\n },\n \"decoratorRepeat\": {\n \"title\": \"Decorator repeat\",\n \"type\": \"string\",\n \"default\": \"20px\"\n },\n \"showPolygon\": {\n \"title\": \"Show polygon\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"polygonTooltipPattern\": {\n \"title\": \"Tooltip (for ex. 'Text ${keyName} units.' or <link-act name='my-action'>Link text</link-act>')\",\n \"type\": \"string\",\n \"default\": \"<b>${entityName}</b><br/><br/><b>TimeStamp:</b> ${ts:7}\"\n },\n \"usePolygonTooltipFunction\": {\n \"title\": \"Use polygon tooltip function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"polygonTooltipFunction\": {\n \"title\": \"Polygon tooltip function: f(data, dsData, dsIndex)\",\n \"type\": \"string\"\n },\n \"polygonColor\": {\n \"title\": \"Polygon color\",\n \"type\": \"string\"\n },\n \"polygonOpacity\": {\n \"title\": \"Polygon opacity\",\n \"type\": \"number\",\n \"default\": 0.5\n },\n \"polygonStrokeColor\": {\n \"title\": \"Polygon border color\",\n \"type\": \"string\"\n },\n \"polygonStrokeOpacity\": {\n \"title\": \"Polygon border opacity\",\n \"type\": \"number\",\n \"default\": 1\n },\n \"polygonStrokeWeight\": {\n \"title\": \"Polygon border weight\",\n \"type\": \"number\",\n \"default\": 1\n },\n \"usePolygonColorFunction\": {\n \"title\": \"Use polygon color function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"polygonColorFunction\": {\n \"title\": \"Polygon Color function: f(data, dsData, dsIndex)\",\n \"type\": \"string\"\n },\n \"showPoints\": {\n \"title\": \"Show points\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"pointColor\": {\n \"title\": \"Point color\",\n \"type\": \"string\"\n },\n \"pointSize\": {\n \"title\": \"Point size (px)\",\n \"type\": \"number\",\n \"default\": 10\n },\n \"usePointAsAnchor\": {\n \"title\": \"Use point as anchor\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"pointAsAnchorFunction\": {\n \"title\": \"Point as anchor function: f(data, dsData, dsIndex)\",\n \"type\": \"string\"\n },\n \"pointTooltipOnRightPanel\": {\n \"title\": \"Independant point tooltip\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"autocloseTooltip\": {\n \"title\": \"Auto-close point popup\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"defaultMarkerColor\": {\n \"title\": \"color for default marker\",\n \"type\": \"string\"\n },\n \"markerImage\": {\n \"title\": \"Custom marker image\",\n \"type\": \"string\"\n },\n \"markerImageSize\": {\n \"title\": \"Custom marker image size (px)\",\n \"type\": \"number\",\n \"default\": 34\n },\n \"rotationAngle\": {\n \"title\": \"Set additional rotation angle for marker (deg)\",\n \"type\": \"number\",\n \"default\": 180\n },\n \"useMarkerImageFunction\":{\n \"title\":\"Use marker image function\",\n \"type\":\"boolean\",\n \"default\":false\n },\n \"markerImageFunction\":{\n \"title\":\"Marker image function: f(data, images, dsData, dsIndex)\",\n \"type\":\"string\"\n },\n \"markerImages\":{\n \"title\":\"Marker images\",\n \"type\":\"array\",\n \"items\":{\n \"title\":\"Marker image\",\n \"type\":\"string\"\n }\n }\n },\n \"required\": []\n },\n \"form\": [{\n \"key\": \"mapProvider\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [{\n \"value\": \"OpenStreetMap.Mapnik\",\n \"label\": \"OpenStreetMap.Mapnik (Default)\"\n }, {\n \"value\": \"OpenStreetMap.BlackAndWhite\",\n \"label\": \"OpenStreetMap.BlackAndWhite\"\n }, {\n \"value\": \"OpenStreetMap.HOT\",\n \"label\": \"OpenStreetMap.HOT\"\n }, {\n \"value\": \"Esri.WorldStreetMap\",\n \"label\": \"Esri.WorldStreetMap\"\n }, {\n \"value\": \"Esri.WorldTopoMap\",\n \"label\": \"Esri.WorldTopoMap\"\n }, {\n \"value\": \"CartoDB.Positron\",\n \"label\": \"CartoDB.Positron\"\n }, {\n \"value\": \"CartoDB.DarkMatter\",\n \"label\": \"CartoDB.DarkMatter\"\n }]\n }, \"normalizationStep\", \"latKeyName\", \"lngKeyName\", \"polKeyName\", \"showLabel\", \"label\", \"useLabelFunction\", {\n \"key\": \"labelFunction\",\n \"type\": \"javascript\"\n }, \"showTooltip\", {\n \"key\": \"tooltipColor\",\n \"type\": \"color\"\n }, {\n \"key\": \"tooltipFontColor\",\n \"type\": \"color\"\n },\"tooltipOpacity\", {\n \"key\": \"tooltipPattern\",\n \"type\": \"textarea\"\n }, \"useTooltipFunction\", {\n \"key\": \"tooltipFunction\",\n \"type\": \"javascript\"\n }, {\n \"key\": \"color\",\n \"type\": \"color\"\n }, \"useColorFunction\", {\n \"key\": \"colorFunction\",\n \"type\": \"javascript\"\n }, \"usePolylineDecorator\", {\n \"key\": \"decoratorSymbol\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [{\n \"value\": \"arrowHead\",\n \"label\": \"Arrow\"\n }, {\n \"value\": \"dash\",\n \"label\": \"Dash\"\n }]\n }, \"decoratorSymbolSize\", \"useDecoratorCustomColor\", {\n \"key\": \"decoratorCustomColor\",\n \"type\": \"color\"\n }, {\n \"key\": \"decoratorOffset\",\n \"type\": \"textarea\"\n },{\n \"key\": \"endDecoratorOffset\",\n \"type\": \"textarea\"\n }, {\n \"key\": \"decoratorRepeat\",\n \"type\": \"textarea\"\n }, \"strokeWeight\", \"strokeOpacity\", \"showPolygon\", {\n \"key\": \"polygonTooltipPattern\",\n \"type\": \"textarea\"\n },\"usePolygonTooltipFunction\", {\n \"key\": \"polygonTooltipFunction\",\n \"type\": \"javascript\"\n },{\n \"key\": \"polygonColor\",\n \"type\": \"color\"\n },\t\"polygonOpacity\", {\n \"key\": \"polygonStrokeColor\",\n \"type\": \"color\"\n },\t\"polygonStrokeOpacity\",\"polygonStrokeWeight\",\"usePolygonColorFunction\",\t{\n \"key\": \"polygonColorFunction\",\n \"type\": \"javascript\"\n },\"showPoints\",{\n \"key\": \"pointColor\",\n \"type\": \"color\"\n }, \"pointSize\",\"usePointAsAnchor\", {\n \"key\": \"pointAsAnchorFunction\",\n \"type\": \"javascript\"\n },\"pointTooltipOnRightPanel\", \"autocloseTooltip\", {\n \"key\": \"defaultMarkerColor\",\n \"type\": \"color\"\n }, {\n \"key\": \"markerImage\",\n \"type\": \"image\"\n }, \"markerImageSize\", \"rotationAngle\",\"useMarkerImageFunction\",\n {\n \"key\":\"markerImageFunction\",\n \"type\":\"javascript\"\n }, {\n \"key\":\"markerImages\",\n \"items\":[\n {\n \"key\":\"markerImages[]\",\n \"type\":\"image\"\n }\n ]\n }]\n}", | 131 | + "settingsSchema": "{\n \"schema\": {\n \"title\": \"Openstreet Map Configuration\",\n \"type\": \"object\",\n \"properties\": {\n \"mapProvider\": {\n \"title\": \"Map provider\",\n \"type\": \"string\",\n \"default\": \"OpenStreetMap.Mapnik\"\n },\n \"normalizationStep\": {\n \"title\": \"Normalization data step (ms)\",\n \"type\": \"number\",\n \"default\": 1000\n },\n \"latKeyName\": {\n \"title\": \"Latitude key name\",\n \"type\": \"string\",\n \"default\": \"latitude\"\n },\n \"lngKeyName\": {\n \"title\": \"Longitude key name\",\n \"type\": \"string\",\n \"default\": \"longitude\"\n },\n \"polKeyName\": {\n \"title\": \"Polygon key name\",\n \"type\": \"string\",\n \"default\": \"coordinates\"\n },\n \"showLabel\": {\n \"title\": \"Show label\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"label\": {\n \"title\": \"Label (pattern examples: '${entityName}', '${entityName}: (Text ${keyName} units.)' )\",\n \"type\": \"string\",\n \"default\": \"${entityName}\"\n },\n \"useLabelFunction\": {\n \"title\": \"Use label function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"labelFunction\": {\n \"title\": \"Label function: f(data, dsData, dsIndex)\",\n \"type\": \"string\"\n },\n \"showTooltip\": {\n \"title\": \"Show tooltip\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"tooltipColor\": {\n \"title\": \"Tooltip background color\",\n \"type\": \"string\",\n \"default\": \"#fff\"\n },\n \"tooltipFontColor\": {\n \"title\": \"Tooltip font color\",\n \"type\": \"string\",\n \"default\": \"#000\"\n },\n \"tooltipOpacity\": {\n \"title\": \"Tooltip opacity (0-1)\",\n \"type\": \"number\",\n \"default\": 1\n },\n \"tooltipPattern\": {\n \"title\": \"Tooltip (for ex. 'Text ${keyName} units.' or <link-act name='my-action'>Link text</link-act>')\",\n \"type\": \"string\",\n \"default\": \"<b>${entityName}</b><br/><br/><b>Latitude:</b> ${latitude:7}<br/><b>Longitude:</b> ${longitude:7}\"\n },\n \"useTooltipFunction\": {\n \"title\": \"Use tooltip function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"tooltipFunction\": {\n \"title\": \"Tooltip function: f(data, dsData, dsIndex)\",\n \"type\": \"string\"\n },\n \"color\": {\n \"title\": \"Path color\",\n \"type\": \"string\"\n },\n \"strokeWeight\": {\n \"title\": \"Stroke weight\",\n \"type\": \"number\",\n \"default\": 2\n },\n \"strokeOpacity\": {\n \"title\": \"Stroke opacity\",\n \"type\": \"number\",\n \"default\": 1\n },\n \"useColorFunction\": {\n \"title\": \"Use path color function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"colorFunction\": {\n \"title\": \"Path color function: f(data, dsData, dsIndex)\",\n \"type\": \"string\"\n },\n \"usePolylineDecorator\": {\n \"title\": \"Use path decorator\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"decoratorSymbol\": {\n \"title\": \"Decorator symbol\",\n \"type\": \"string\",\n \"default\": \"arrowHead\"\n },\n \"decoratorSymbolSize\": {\n \"title\": \"Decorator symbol size (px)\",\n \"type\": \"number\",\n \"default\": 10\n },\n \"useDecoratorCustomColor\": {\n \"title\": \"Use path decorator custom color\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"decoratorCustomColor\": {\n \"title\": \"Decorator custom color\",\n \"type\": \"string\",\n \"default\": \"#000\"\n },\n \"decoratorOffset\": {\n \"title\": \"Decorator offset\",\n \"type\": \"string\",\n \"default\": \"20px\"\n },\n \"endDecoratorOffset\": {\n \"title\": \"End decorator offset\",\n \"type\": \"string\",\n \"default\": \"20px\"\n },\n \"decoratorRepeat\": {\n \"title\": \"Decorator repeat\",\n \"type\": \"string\",\n \"default\": \"20px\"\n },\n \"showPolygon\": {\n \"title\": \"Show polygon\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"polygonTooltipPattern\": {\n \"title\": \"Tooltip (for ex. 'Text ${keyName} units.' or <link-act name='my-action'>Link text</link-act>')\",\n \"type\": \"string\",\n \"default\": \"<b>${entityName}</b><br/><br/><b>TimeStamp:</b> ${ts:7}\"\n },\n \"usePolygonTooltipFunction\": {\n \"title\": \"Use polygon tooltip function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"polygonTooltipFunction\": {\n \"title\": \"Polygon tooltip function: f(data, dsData, dsIndex)\",\n \"type\": \"string\"\n },\n \"polygonColor\": {\n \"title\": \"Polygon color\",\n \"type\": \"string\"\n },\n \"polygonOpacity\": {\n \"title\": \"Polygon opacity\",\n \"type\": \"number\",\n \"default\": 0.5\n },\n \"polygonStrokeColor\": {\n \"title\": \"Polygon border color\",\n \"type\": \"string\"\n },\n \"polygonStrokeOpacity\": {\n \"title\": \"Polygon border opacity\",\n \"type\": \"number\",\n \"default\": 1\n },\n \"polygonStrokeWeight\": {\n \"title\": \"Polygon border weight\",\n \"type\": \"number\",\n \"default\": 1\n },\n \"usePolygonColorFunction\": {\n \"title\": \"Use polygon color function\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"polygonColorFunction\": {\n \"title\": \"Polygon Color function: f(data, dsData, dsIndex)\",\n \"type\": \"string\"\n },\n \"showPoints\": {\n \"title\": \"Show points\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"pointColor\": {\n \"title\": \"Point color\",\n \"type\": \"string\"\n },\n \"pointSize\": {\n \"title\": \"Point size (px)\",\n \"type\": \"number\",\n \"default\": 10\n },\n \"usePointAsAnchor\": {\n \"title\": \"Use point as anchor\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"pointAsAnchorFunction\": {\n \"title\": \"Point as anchor function: f(data, dsData, dsIndex)\",\n \"type\": \"string\"\n },\n \"pointTooltipOnRightPanel\": {\n \"title\": \"Independant point tooltip\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"autocloseTooltip\": {\n \"title\": \"Auto-close point popup\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"markerImage\": {\n \"title\": \"Custom marker image\",\n \"type\": \"string\"\n },\n \"markerImageSize\": {\n \"title\": \"Custom marker image size (px)\",\n \"type\": \"number\",\n \"default\": 34\n },\n \"rotationAngle\": {\n \"title\": \"Set additional rotation angle for marker (deg)\",\n \"type\": \"number\",\n \"default\": 180\n },\n \"useMarkerImageFunction\":{\n \"title\":\"Use marker image function\",\n \"type\":\"boolean\",\n \"default\":false\n },\n \"markerImageFunction\":{\n \"title\":\"Marker image function: f(data, images, dsData, dsIndex)\",\n \"type\":\"string\"\n },\n \"markerImages\":{\n \"title\":\"Marker images\",\n \"type\":\"array\",\n \"items\":{\n \"title\":\"Marker image\",\n \"type\":\"string\"\n }\n }\n },\n \"required\": []\n },\n \"form\": [{\n \"key\": \"mapProvider\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [{\n \"value\": \"OpenStreetMap.Mapnik\",\n \"label\": \"OpenStreetMap.Mapnik (Default)\"\n }, {\n \"value\": \"OpenStreetMap.BlackAndWhite\",\n \"label\": \"OpenStreetMap.BlackAndWhite\"\n }, {\n \"value\": \"OpenStreetMap.HOT\",\n \"label\": \"OpenStreetMap.HOT\"\n }, {\n \"value\": \"Esri.WorldStreetMap\",\n \"label\": \"Esri.WorldStreetMap\"\n }, {\n \"value\": \"Esri.WorldTopoMap\",\n \"label\": \"Esri.WorldTopoMap\"\n }, {\n \"value\": \"CartoDB.Positron\",\n \"label\": \"CartoDB.Positron\"\n }, {\n \"value\": \"CartoDB.DarkMatter\",\n \"label\": \"CartoDB.DarkMatter\"\n }]\n }, \"normalizationStep\", \"latKeyName\", \"lngKeyName\", \"polKeyName\", \"showLabel\", \"label\", \"useLabelFunction\", {\n \"key\": \"labelFunction\",\n \"type\": \"javascript\"\n }, \"showTooltip\", {\n \"key\": \"tooltipColor\",\n \"type\": \"color\"\n }, {\n \"key\": \"tooltipFontColor\",\n \"type\": \"color\"\n },\"tooltipOpacity\", {\n \"key\": \"tooltipPattern\",\n \"type\": \"textarea\"\n }, \"useTooltipFunction\", {\n \"key\": \"tooltipFunction\",\n \"type\": \"javascript\"\n }, {\n \"key\": \"color\",\n \"type\": \"color\"\n }, \"useColorFunction\", {\n \"key\": \"colorFunction\",\n \"type\": \"javascript\"\n }, \"usePolylineDecorator\", {\n \"key\": \"decoratorSymbol\",\n \"type\": \"rc-select\",\n \"multiple\": false,\n \"items\": [{\n \"value\": \"arrowHead\",\n \"label\": \"Arrow\"\n }, {\n \"value\": \"dash\",\n \"label\": \"Dash\"\n }]\n }, \"decoratorSymbolSize\", \"useDecoratorCustomColor\", {\n \"key\": \"decoratorCustomColor\",\n \"type\": \"color\"\n }, {\n \"key\": \"decoratorOffset\",\n \"type\": \"textarea\"\n },{\n \"key\": \"endDecoratorOffset\",\n \"type\": \"textarea\"\n }, {\n \"key\": \"decoratorRepeat\",\n \"type\": \"textarea\"\n }, \"strokeWeight\", \"strokeOpacity\", \"showPolygon\", {\n \"key\": \"polygonTooltipPattern\",\n \"type\": \"textarea\"\n },\"usePolygonTooltipFunction\", {\n \"key\": \"polygonTooltipFunction\",\n \"type\": \"javascript\"\n },{\n \"key\": \"polygonColor\",\n \"type\": \"color\"\n },\t\"polygonOpacity\", {\n \"key\": \"polygonStrokeColor\",\n \"type\": \"color\"\n },\t\"polygonStrokeOpacity\",\"polygonStrokeWeight\",\"usePolygonColorFunction\",\t{\n \"key\": \"polygonColorFunction\",\n \"type\": \"javascript\"\n },\"showPoints\",{\n \"key\": \"pointColor\",\n \"type\": \"color\"\n }, \"pointSize\",\"usePointAsAnchor\", {\n \"key\": \"pointAsAnchorFunction\",\n \"type\": \"javascript\"\n },\"pointTooltipOnRightPanel\", \"autocloseTooltip\", {\n \"key\": \"markerImage\",\n \"type\": \"image\"\n }, \"markerImageSize\", \"rotationAngle\",\"useMarkerImageFunction\",\n {\n \"key\":\"markerImageFunction\",\n \"type\":\"javascript\"\n }, {\n \"key\":\"markerImages\",\n \"items\":[\n {\n \"key\":\"markerImages[]\",\n \"type\":\"image\"\n }\n ]\n }]\n}", |
132 | "dataKeySettingsSchema": "{}", | 132 | "dataKeySettingsSchema": "{}", |
133 | "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#2196f3\",\"settings\":{\"showLines\":true,\"fillLines\":true,\"showPoints\":false},\"_hash\":0.8587686344902596,\"funcBody\":\"var gpsData = [\\n\\t37.771210000,-122.510960000,\\n\\t37.771340000,-122.510980000,\\n\\t37.771340000,-122.510980000,\\n\\t37.771360000,-122.510850000,\\n\\t37.771380000,-122.510550000,\\n\\t37.771400000,-122.509900000,\\n\\t37.771410000,-122.509660000,\\n\\t37.771430000,-122.509360000,\\n\\t37.771430000,-122.509270000,\\n\\t37.771450000,-122.508840000,\\n\\t37.771490000,-122.507880000,\\n\\t37.771490000,-122.507780000,\\n\\t37.771530000,-122.507140000,\\n\\t37.771550000,-122.506690000,\\n\\t37.771560000,-122.506310000,\\n\\t37.771600000,-122.505640000,\\n\\t37.771650000,-122.504540000,\\n\\t37.771670000,-122.503990000,\\n\\t37.771700000,-122.503490000,\\n\\t37.771740000,-122.502430000,\\n\\t37.771790000,-122.501360000,\\n\\t37.771840000,-122.500290000,\\n\\t37.771870000,-122.499730000,\\n\\t37.771890000,-122.499210000,\\n\\t37.771940000,-122.498140000,\\n\\t37.771990000,-122.497070000,\\n\\t37.772000000,-122.496690000,\\n\\t37.772020000,-122.496350000,\\n\\t37.772030000,-122.496110000,\\n\\t37.772040000,-122.496000000,\\n\\t37.772040000,-122.495890000,\\n\\t37.772060000,-122.495440000,\\n\\t37.772090000,-122.494930000,\\n\\t37.772120000,-122.494160000,\\n\\t37.772130000,-122.493860000,\\n\\t37.772180000,-122.492790000,\\n\\t37.772200000,-122.492300000,\\n\\t37.772220000,-122.491840000,\\n\\t37.772230000,-122.491710000,\\n\\t37.772280000,-122.490630000,\\n\\t37.772330000,-122.489560000,\\n\\t37.772330000,-122.489470000,\\n\\t37.772360000,-122.489030000,\\n\\t37.772380000,-122.488490000,\\n\\t37.772430000,-122.487420000,\\n\\t37.772450000,-122.486980000,\\n\\t37.772480000,-122.486360000,\\n\\t37.772520000,-122.485280000,\\n\\t37.772560000,-122.484400000,\\n\\t37.772570000,-122.484300000,\\n\\t37.772570000,-122.484150000,\\n\\t37.772620000,-122.483140000,\\n\\t37.772680000,-122.482050000,\\n\\t37.772700000,-122.481370000,\\n\\t37.772710000,-122.481000000,\\n\\t37.772730000,-122.480740000,\\n\\t37.772770000,-122.479930000,\\n\\t37.772820000,-122.478860000,\\n\\t37.772870000,-122.477790000,\\n\\t37.772900000,-122.477110000,\\n\\t37.772920000,-122.476710000,\\n\\t37.772960000,-122.475650000,\\n\\t37.772990000,-122.474950000,\\n\\t37.773010000,-122.474580000,\\n\\t37.773060000,-122.473450000,\\n\\t37.773120000,-122.472330000,\\n\\t37.773140000,-122.471850000,\\n\\t37.773140000,-122.471730000,\\n\\t37.773150000,-122.471640000,\\n\\t37.773170000,-122.471260000,\\n\\t37.773190000,-122.470570000,\\n\\t37.773210000,-122.470190000,\\n\\t37.773230000,-122.469770000,\\n\\t37.773250000,-122.469370000,\\n\\t37.773260000,-122.469120000,\\n\\t37.773290000,-122.468490000,\\n\\t37.773300000,-122.468150000,\\n\\t37.773310000,-122.468050000,\\n\\t37.773310000,-122.467940000,\\n\\t37.773320000,-122.467740000,\\n\\t37.773350000,-122.467270000,\\n\\t37.773360000,-122.466980000,\\n\\t37.773360000,-122.466870000,\\n\\t37.773370000,-122.466610000,\\n\\t37.773390000,-122.466300000,\\n\\t37.773400000,-122.466000000,\\n\\t37.773400000,-122.465910000,\\n\\t37.773410000,-122.465790000,\\n\\t37.773430000,-122.465520000,\\n\\t37.773460000,-122.465210000,\\n\\t37.773490000,-122.464980000,\\n\\t37.773500000,-122.464910000,\\n\\t37.773460000,-122.464830000,\\n\\t37.773560000,-122.464070000,\\n\\t37.773580000,-122.463900000,\\n\\t37.773590000,-122.463810000,\\n\\t37.773600000,-122.463780000,\\n\\t37.773610000,-122.463670000,\\n\\t37.773660000,-122.463320000,\\n\\t37.773740000,-122.462700000,\\n\\t37.773770000,-122.462440000,\\n\\t37.773860000,-122.461730000,\\n\\t37.773870000,-122.461640000,\\n\\t37.773920000,-122.461260000,\\n\\t37.773970000,-122.460890000,\\n\\t37.774010000,-122.460570000,\\n\\t37.774110000,-122.459760000,\\n\\t37.774140000,-122.459490000,\\n\\t37.774270000,-122.458520000,\\n\\t37.774270000,-122.458440000,\\n\\t37.774270000,-122.458380000,\\n\\t37.774320000,-122.458270000,\\n\\t37.774340000,-122.458050000,\\n\\t37.774510000,-122.456680000,\\n\\t37.774560000,-122.456310000,\\n\\t37.774700000,-122.455280000,\\n\\t37.774760000,-122.454780000,\\n\\t37.774770000,-122.454670000,\\n\\t37.774770000,-122.454670000,\\n\\t37.774670000,-122.454650000,\\n\\t37.774670000,-122.454650000,\\n\\t37.774580000,-122.454640000,\\n\\t37.774300000,-122.454580000,\\n\\t37.774190000,-122.454560000,\\n\\t37.773700000,-122.454460000,\\n\\t37.772910000,-122.454310000,\\n\\t37.772620000,-122.454260000,\\n\\t37.772430000,-122.454220000,\\n\\t37.771980000,-122.454110000,\\n\\t37.771910000,-122.454100000,\\n\\t37.771760000,-122.454060000,\\n\\t37.771690000,-122.454050000,\\n\\t37.771620000,-122.454030000,\\n\\t37.771530000,-122.454010000,\\n\\t37.771380000,-122.453970000,\\n\\t37.771250000,-122.453950000,\\n\\t37.771100000,-122.453930000,\\n\\t37.771020000,-122.453920000,\\n\\t37.770920000,-122.453900000,\\n\\t37.770810000,-122.453890000,\\n\\t37.770660000,-122.453860000,\\n\\t37.770110000,-122.453750000,\\n\\t37.769560000,-122.453640000,\\n\\t37.769360000,-122.453600000,\\n\\t37.769250000,-122.453580000,\\n\\t37.769180000,-122.453560000,\\n\\t37.769090000,-122.453540000,\\n\\t37.768780000,-122.453480000,\\n\\t37.768250000,-122.453380000,\\n\\t37.768160000,-122.453360000,\\n\\t37.767820000,-122.453290000,\\n\\t37.767310000,-122.453190000,\\n\\t37.767160000,-122.453160000,\\n\\t37.767010000,-122.453130000,\\n\\t37.766760000,-122.453070000,\\n\\t37.766550000,-122.453030000,\\n\\t37.766550000,-122.453030000,\\n\\t37.766390000,-122.452990000,\\n\\t37.766390000,-122.452990000,\\n\\t37.766290000,-122.453720000,\\n\\t37.766180000,-122.454610000,\\n\\t37.766130000,-122.454980000,\\n\\t37.765960000,-122.456290000,\\n\\t37.765960000,-122.456340000,\\n\\t37.765960000,-122.456360000,\\n\\t37.765960000,-122.456380000,\\n\\t37.765960000,-122.456410000,\\n\\t37.765960000,-122.456460000,\\n\\t37.765940000,-122.456630000,\\n\\t37.765930000,-122.456700000,\\n\\t37.765920000,-122.456810000,\\n\\t37.765910000,-122.456930000,\\n\\t37.765910000,-122.457020000,\\n\\t37.765920000,-122.457160000,\\n\\t37.765930000,-122.457270000,\\n\\t37.765940000,-122.457360000,\\n\\t37.765950000,-122.457410000,\\n\\t37.765960000,-122.457470000,\\n\\t37.765980000,-122.457560000,\\n\\t37.766010000,-122.457660000,\\n\\t37.766070000,-122.457830000,\\n\\t37.766070000,-122.457830000,\\n\\t37.766120000,-122.457980000,\\n\\t37.766180000,-122.458180000,\\n\\t37.766190000,-122.458200000,\\n\\t37.766240000,-122.458400000,\\n\\t37.766270000,-122.458530000,\\n\\t37.766290000,-122.458600000,\\n\\t37.766300000,-122.458690000,\\n\\t37.766300000,-122.458880000,\\n\\t37.766300000,-122.458970000,\\n\\t37.766280000,-122.459470000,\\n\\t37.766270000,-122.459520000,\\n\\t37.766270000,-122.459560000,\\n\\t37.766280000,-122.459600000,\\n\\t37.766280000,-122.459630000,\\n\\t37.766290000,-122.459670000,\\n\\t37.766300000,-122.459700000,\\n\\t37.766310000,-122.459730000,\\n\\t37.766320000,-122.459750000,\\n\\t37.766330000,-122.459770000,\\n\\t37.766350000,-122.459800000,\\n\\t37.766390000,-122.459860000,\\n\\t37.766340000,-122.459970000,\\n\\t37.766290000,-122.460150000,\\n\\t37.766290000,-122.460230000,\\n\\t37.766280000,-122.460280000,\\n\\t37.766260000,-122.460330000,\\n\\t37.766250000,-122.460420000,\\n\\t37.766240000,-122.460520000,\\n\\t37.766230000,-122.460670000,\\n\\t37.766230000,-122.460800000,\\n\\t37.766230000,-122.460900000,\\n\\t37.766210000,-122.461110000,\\n\\t37.766170000,-122.462030000,\\n\\t37.766160000,-122.462170000,\\n\\t37.766150000,-122.462520000,\\n\\t37.766120000,-122.463260000,\\n\\t37.766090000,-122.464130000,\\n\\t37.766070000,-122.464350000,\\n\\t37.766070000,-122.464440000,\\n\\t37.766060000,-122.464620000,\\n\\t37.766030000,-122.465400000,\\n\\t37.765980000,-122.466470000,\\n\\t37.765940000,-122.467530000,\\n\\t37.765930000,-122.467680000,\\n\\t37.765890000,-122.468600000,\\n\\t37.765860000,-122.468980000,\\n\\t37.765830000,-122.469660000,\\n\\t37.765780000,-122.470740000,\\n\\t37.765770000,-122.471030000,\\n\\t37.765770000,-122.471140000,\\n\\t37.765760000,-122.471380000,\\n\\t37.765740000,-122.471820000,\\n\\t37.765690000,-122.472950000,\\n\\t37.765680000,-122.473220000,\\n\\t37.765670000,-122.473320000,\\n\\t37.765640000,-122.474070000,\\n\\t37.765590000,-122.475140000,\\n\\t37.765590000,-122.475400000,\\n\\t37.765580000,-122.475520000,\\n\\t37.765550000,-122.476200000,\\n\\t37.765500000,-122.477180000,\\n\\t37.765500000,-122.477280000,\\n\\t37.765490000,-122.477400000,\\n\\t37.765490000,-122.477440000,\\n\\t37.765490000,-122.477440000,\\n\\t37.765490000,-122.477490000,\\n\\t37.765470000,-122.477770000,\\n\\t37.765450000,-122.478340000,\\n\\t37.765450000,-122.478420000,\\n\\t37.765430000,-122.478870000,\\n\\t37.765400000,-122.479430000,\\n\\t37.765380000,-122.479810000,\\n\\t37.765350000,-122.480480000,\\n\\t37.765300000,-122.481570000,\\n\\t37.765300000,-122.481660000,\\n\\t37.765290000,-122.481950000,\\n\\t37.765260000,-122.482640000,\\n\\t37.765220000,-122.483570000,\\n\\t37.765210000,-122.483710000,\\n\\t37.765210000,-122.483810000,\\n\\t37.765190000,-122.484130000,\\n\\t37.765160000,-122.484780000,\\n\\t37.765120000,-122.485860000,\\n\\t37.765110000,-122.485960000,\\n\\t37.765100000,-122.486170000,\\n\\t37.765070000,-122.486930000,\\n\\t37.765020000,-122.488000000,\\n\\t37.765020000,-122.488100000,\\n\\t37.765000000,-122.488360000,\\n\\t37.764980000,-122.488970000,\\n\\t37.764970000,-122.489070000,\\n\\t37.764930000,-122.490150000,\\n\\t37.764920000,-122.490240000,\\n\\t37.764910000,-122.490490000,\\n\\t37.764880000,-122.491210000,\\n\\t37.764830000,-122.492290000,\\n\\t37.764790000,-122.493260000,\\n\\t37.764780000,-122.493350000,\\n\\t37.764740000,-122.494420000,\\n\\t37.764720000,-122.494730000,\\n\\t37.764710000,-122.495500000,\\n\\t37.764700000,-122.495630000,\\n\\t37.764690000,-122.495940000,\\n\\t37.764680000,-122.496260000,\\n\\t37.764670000,-122.496480000,\\n\\t37.764600000,-122.497490000,\\n\\t37.764590000,-122.497650000,\\n\\t37.764550000,-122.498720000,\\n\\t37.764500000,-122.499780000,\\n\\t37.764450000,-122.500870000,\\n\\t37.764440000,-122.501060000,\\n\\t37.764400000,-122.501930000,\\n\\t37.764360000,-122.502990000,\\n\\t37.764310000,-122.504080000,\\n\\t37.764260000,-122.505140000,\\n\\t37.764260000,-122.505250000,\\n\\t37.764220000,-122.506220000,\\n\\t37.764170000,-122.507280000,\\n\\t37.764120000,-122.508360000,\\n\\t37.764100000,-122.508850000,\\n\\t37.764100000,-122.509150000,\\n\\t37.764100000,-122.509440000,\\n\\t37.764090000,-122.509760000,\\n\\t37.764080000,-122.510200000,\\n\\t37.764070000,-122.510320000,\\n\\t37.764060000,-122.510430000,\\n\\t37.764030000,-122.510430000,\\n\\t37.764030000,-122.510430000,\\n\\t37.763960000,-122.510430000,\\n\\t37.763960000,-122.510290000,\\n\\t37.764070000,-122.510320000,\\n\\t37.764170000,-122.510320000,\\n\\t37.764410000,-122.510340000,\\n\\t37.764610000,-122.510350000,\\n\\t37.764780000,-122.510330000,\\n\\t37.764960000,-122.510310000,\\n\\t37.765340000,-122.510280000,\\n\\t37.765570000,-122.510260000,\\n\\t37.765840000,-122.510250000,\\n\\t37.765900000,-122.510250000,\\n\\t37.766140000,-122.510260000,\\n\\t37.766410000,-122.510260000,\\n\\t37.766620000,-122.510270000,\\n\\t37.767040000,-122.510310000,\\n\\t37.767270000,-122.510330000,\\n\\t37.767620000,-122.510390000,\\n\\t37.767670000,-122.510390000,\\n\\t37.767740000,-122.510410000,\\n\\t37.767840000,-122.510430000,\\n\\t37.768280000,-122.510530000,\\n\\t37.768620000,-122.510600000,\\n\\t37.768690000,-122.510620000,\\n\\t37.769020000,-122.510690000,\\n\\t37.769260000,-122.510730000,\\n\\t37.769420000,-122.510750000,\\n\\t37.770010000,-122.510830000,\\n\\t37.770340000,-122.510860000,\\n\\t37.770460000,-122.510870000,\\n\\t37.770930000,-122.510930000,\\n\\t37.770980000,-122.510930000,\\n];\\n let value = gpsData.indexOf(prevValue); \\nreturn gpsData[(value == -1 ? 0 : value + 2)];\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#ffc107\",\"settings\":{\"showLines\":true,\"fillLines\":false,\"showPoints\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var gpsData = [\\n\\t37.771210000,-122.510960000,\\n\\t37.771340000,-122.510980000,\\n\\t37.771340000,-122.510980000,\\n\\t37.771360000,-122.510850000,\\n\\t37.771380000,-122.510550000,\\n\\t37.771400000,-122.509900000,\\n\\t37.771410000,-122.509660000,\\n\\t37.771430000,-122.509360000,\\n\\t37.771430000,-122.509270000,\\n\\t37.771450000,-122.508840000,\\n\\t37.771490000,-122.507880000,\\n\\t37.771490000,-122.507780000,\\n\\t37.771530000,-122.507140000,\\n\\t37.771550000,-122.506690000,\\n\\t37.771560000,-122.506310000,\\n\\t37.771600000,-122.505640000,\\n\\t37.771650000,-122.504540000,\\n\\t37.771670000,-122.503990000,\\n\\t37.771700000,-122.503490000,\\n\\t37.771740000,-122.502430000,\\n\\t37.771790000,-122.501360000,\\n\\t37.771840000,-122.500290000,\\n\\t37.771870000,-122.499730000,\\n\\t37.771890000,-122.499210000,\\n\\t37.771940000,-122.498140000,\\n\\t37.771990000,-122.497070000,\\n\\t37.772000000,-122.496690000,\\n\\t37.772020000,-122.496350000,\\n\\t37.772030000,-122.496110000,\\n\\t37.772040000,-122.496000000,\\n\\t37.772040000,-122.495890000,\\n\\t37.772060000,-122.495440000,\\n\\t37.772090000,-122.494930000,\\n\\t37.772120000,-122.494160000,\\n\\t37.772130000,-122.493860000,\\n\\t37.772180000,-122.492790000,\\n\\t37.772200000,-122.492300000,\\n\\t37.772220000,-122.491840000,\\n\\t37.772230000,-122.491710000,\\n\\t37.772280000,-122.490630000,\\n\\t37.772330000,-122.489560000,\\n\\t37.772330000,-122.489470000,\\n\\t37.772360000,-122.489030000,\\n\\t37.772380000,-122.488490000,\\n\\t37.772430000,-122.487420000,\\n\\t37.772450000,-122.486980000,\\n\\t37.772480000,-122.486360000,\\n\\t37.772520000,-122.485280000,\\n\\t37.772560000,-122.484400000,\\n\\t37.772570000,-122.484300000,\\n\\t37.772570000,-122.484150000,\\n\\t37.772620000,-122.483140000,\\n\\t37.772680000,-122.482050000,\\n\\t37.772700000,-122.481370000,\\n\\t37.772710000,-122.481000000,\\n\\t37.772730000,-122.480740000,\\n\\t37.772770000,-122.479930000,\\n\\t37.772820000,-122.478860000,\\n\\t37.772870000,-122.477790000,\\n\\t37.772900000,-122.477110000,\\n\\t37.772920000,-122.476710000,\\n\\t37.772960000,-122.475650000,\\n\\t37.772990000,-122.474950000,\\n\\t37.773010000,-122.474580000,\\n\\t37.773060000,-122.473450000,\\n\\t37.773120000,-122.472330000,\\n\\t37.773140000,-122.471850000,\\n\\t37.773140000,-122.471730000,\\n\\t37.773150000,-122.471640000,\\n\\t37.773170000,-122.471260000,\\n\\t37.773190000,-122.470570000,\\n\\t37.773210000,-122.470190000,\\n\\t37.773230000,-122.469770000,\\n\\t37.773250000,-122.469370000,\\n\\t37.773260000,-122.469120000,\\n\\t37.773290000,-122.468490000,\\n\\t37.773300000,-122.468150000,\\n\\t37.773310000,-122.468050000,\\n\\t37.773310000,-122.467940000,\\n\\t37.773320000,-122.467740000,\\n\\t37.773350000,-122.467270000,\\n\\t37.773360000,-122.466980000,\\n\\t37.773360000,-122.466870000,\\n\\t37.773370000,-122.466610000,\\n\\t37.773390000,-122.466300000,\\n\\t37.773400000,-122.466000000,\\n\\t37.773400000,-122.465910000,\\n\\t37.773410000,-122.465790000,\\n\\t37.773430000,-122.465520000,\\n\\t37.773460000,-122.465210000,\\n\\t37.773490000,-122.464980000,\\n\\t37.773500000,-122.464910000,\\n\\t37.773460000,-122.464830000,\\n\\t37.773560000,-122.464070000,\\n\\t37.773580000,-122.463900000,\\n\\t37.773590000,-122.463810000,\\n\\t37.773600000,-122.463780000,\\n\\t37.773610000,-122.463670000,\\n\\t37.773660000,-122.463320000,\\n\\t37.773740000,-122.462700000,\\n\\t37.773770000,-122.462440000,\\n\\t37.773860000,-122.461730000,\\n\\t37.773870000,-122.461640000,\\n\\t37.773920000,-122.461260000,\\n\\t37.773970000,-122.460890000,\\n\\t37.774010000,-122.460570000,\\n\\t37.774110000,-122.459760000,\\n\\t37.774140000,-122.459490000,\\n\\t37.774270000,-122.458520000,\\n\\t37.774270000,-122.458440000,\\n\\t37.774270000,-122.458380000,\\n\\t37.774320000,-122.458270000,\\n\\t37.774340000,-122.458050000,\\n\\t37.774510000,-122.456680000,\\n\\t37.774560000,-122.456310000,\\n\\t37.774700000,-122.455280000,\\n\\t37.774760000,-122.454780000,\\n\\t37.774770000,-122.454670000,\\n\\t37.774770000,-122.454670000,\\n\\t37.774670000,-122.454650000,\\n\\t37.774670000,-122.454650000,\\n\\t37.774580000,-122.454640000,\\n\\t37.774300000,-122.454580000,\\n\\t37.774190000,-122.454560000,\\n\\t37.773700000,-122.454460000,\\n\\t37.772910000,-122.454310000,\\n\\t37.772620000,-122.454260000,\\n\\t37.772430000,-122.454220000,\\n\\t37.771980000,-122.454110000,\\n\\t37.771910000,-122.454100000,\\n\\t37.771760000,-122.454060000,\\n\\t37.771690000,-122.454050000,\\n\\t37.771620000,-122.454030000,\\n\\t37.771530000,-122.454010000,\\n\\t37.771380000,-122.453970000,\\n\\t37.771250000,-122.453950000,\\n\\t37.771100000,-122.453930000,\\n\\t37.771020000,-122.453920000,\\n\\t37.770920000,-122.453900000,\\n\\t37.770810000,-122.453890000,\\n\\t37.770660000,-122.453860000,\\n\\t37.770110000,-122.453750000,\\n\\t37.769560000,-122.453640000,\\n\\t37.769360000,-122.453600000,\\n\\t37.769250000,-122.453580000,\\n\\t37.769180000,-122.453560000,\\n\\t37.769090000,-122.453540000,\\n\\t37.768780000,-122.453480000,\\n\\t37.768250000,-122.453380000,\\n\\t37.768160000,-122.453360000,\\n\\t37.767820000,-122.453290000,\\n\\t37.767310000,-122.453190000,\\n\\t37.767160000,-122.453160000,\\n\\t37.767010000,-122.453130000,\\n\\t37.766760000,-122.453070000,\\n\\t37.766550000,-122.453030000,\\n\\t37.766550000,-122.453030000,\\n\\t37.766390000,-122.452990000,\\n\\t37.766390000,-122.452990000,\\n\\t37.766290000,-122.453720000,\\n\\t37.766180000,-122.454610000,\\n\\t37.766130000,-122.454980000,\\n\\t37.765960000,-122.456290000,\\n\\t37.765960000,-122.456340000,\\n\\t37.765960000,-122.456360000,\\n\\t37.765960000,-122.456380000,\\n\\t37.765960000,-122.456410000,\\n\\t37.765960000,-122.456460000,\\n\\t37.765940000,-122.456630000,\\n\\t37.765930000,-122.456700000,\\n\\t37.765920000,-122.456810000,\\n\\t37.765910000,-122.456930000,\\n\\t37.765910000,-122.457020000,\\n\\t37.765920000,-122.457160000,\\n\\t37.765930000,-122.457270000,\\n\\t37.765940000,-122.457360000,\\n\\t37.765950000,-122.457410000,\\n\\t37.765960000,-122.457470000,\\n\\t37.765980000,-122.457560000,\\n\\t37.766010000,-122.457660000,\\n\\t37.766070000,-122.457830000,\\n\\t37.766070000,-122.457830000,\\n\\t37.766120000,-122.457980000,\\n\\t37.766180000,-122.458180000,\\n\\t37.766190000,-122.458200000,\\n\\t37.766240000,-122.458400000,\\n\\t37.766270000,-122.458530000,\\n\\t37.766290000,-122.458600000,\\n\\t37.766300000,-122.458690000,\\n\\t37.766300000,-122.458880000,\\n\\t37.766300000,-122.458970000,\\n\\t37.766280000,-122.459470000,\\n\\t37.766270000,-122.459520000,\\n\\t37.766270000,-122.459560000,\\n\\t37.766280000,-122.459600000,\\n\\t37.766280000,-122.459630000,\\n\\t37.766290000,-122.459670000,\\n\\t37.766300000,-122.459700000,\\n\\t37.766310000,-122.459730000,\\n\\t37.766320000,-122.459750000,\\n\\t37.766330000,-122.459770000,\\n\\t37.766350000,-122.459800000,\\n\\t37.766390000,-122.459860000,\\n\\t37.766340000,-122.459970000,\\n\\t37.766290000,-122.460150000,\\n\\t37.766290000,-122.460230000,\\n\\t37.766280000,-122.460280000,\\n\\t37.766260000,-122.460330000,\\n\\t37.766250000,-122.460420000,\\n\\t37.766240000,-122.460520000,\\n\\t37.766230000,-122.460670000,\\n\\t37.766230000,-122.460800000,\\n\\t37.766230000,-122.460900000,\\n\\t37.766210000,-122.461110000,\\n\\t37.766170000,-122.462030000,\\n\\t37.766160000,-122.462170000,\\n\\t37.766150000,-122.462520000,\\n\\t37.766120000,-122.463260000,\\n\\t37.766090000,-122.464130000,\\n\\t37.766070000,-122.464350000,\\n\\t37.766070000,-122.464440000,\\n\\t37.766060000,-122.464620000,\\n\\t37.766030000,-122.465400000,\\n\\t37.765980000,-122.466470000,\\n\\t37.765940000,-122.467530000,\\n\\t37.765930000,-122.467680000,\\n\\t37.765890000,-122.468600000,\\n\\t37.765860000,-122.468980000,\\n\\t37.765830000,-122.469660000,\\n\\t37.765780000,-122.470740000,\\n\\t37.765770000,-122.471030000,\\n\\t37.765770000,-122.471140000,\\n\\t37.765760000,-122.471380000,\\n\\t37.765740000,-122.471820000,\\n\\t37.765690000,-122.472950000,\\n\\t37.765680000,-122.473220000,\\n\\t37.765670000,-122.473320000,\\n\\t37.765640000,-122.474070000,\\n\\t37.765590000,-122.475140000,\\n\\t37.765590000,-122.475400000,\\n\\t37.765580000,-122.475520000,\\n\\t37.765550000,-122.476200000,\\n\\t37.765500000,-122.477180000,\\n\\t37.765500000,-122.477280000,\\n\\t37.765490000,-122.477400000,\\n\\t37.765490000,-122.477440000,\\n\\t37.765490000,-122.477440000,\\n\\t37.765490000,-122.477490000,\\n\\t37.765470000,-122.477770000,\\n\\t37.765450000,-122.478340000,\\n\\t37.765450000,-122.478420000,\\n\\t37.765430000,-122.478870000,\\n\\t37.765400000,-122.479430000,\\n\\t37.765380000,-122.479810000,\\n\\t37.765350000,-122.480480000,\\n\\t37.765300000,-122.481570000,\\n\\t37.765300000,-122.481660000,\\n\\t37.765290000,-122.481950000,\\n\\t37.765260000,-122.482640000,\\n\\t37.765220000,-122.483570000,\\n\\t37.765210000,-122.483710000,\\n\\t37.765210000,-122.483810000,\\n\\t37.765190000,-122.484130000,\\n\\t37.765160000,-122.484780000,\\n\\t37.765120000,-122.485860000,\\n\\t37.765110000,-122.485960000,\\n\\t37.765100000,-122.486170000,\\n\\t37.765070000,-122.486930000,\\n\\t37.765020000,-122.488000000,\\n\\t37.765020000,-122.488100000,\\n\\t37.765000000,-122.488360000,\\n\\t37.764980000,-122.488970000,\\n\\t37.764970000,-122.489070000,\\n\\t37.764930000,-122.490150000,\\n\\t37.764920000,-122.490240000,\\n\\t37.764910000,-122.490490000,\\n\\t37.764880000,-122.491210000,\\n\\t37.764830000,-122.492290000,\\n\\t37.764790000,-122.493260000,\\n\\t37.764780000,-122.493350000,\\n\\t37.764740000,-122.494420000,\\n\\t37.764720000,-122.494730000,\\n\\t37.764710000,-122.495500000,\\n\\t37.764700000,-122.495630000,\\n\\t37.764690000,-122.495940000,\\n\\t37.764680000,-122.496260000,\\n\\t37.764670000,-122.496480000,\\n\\t37.764600000,-122.497490000,\\n\\t37.764590000,-122.497650000,\\n\\t37.764550000,-122.498720000,\\n\\t37.764500000,-122.499780000,\\n\\t37.764450000,-122.500870000,\\n\\t37.764440000,-122.501060000,\\n\\t37.764400000,-122.501930000,\\n\\t37.764360000,-122.502990000,\\n\\t37.764310000,-122.504080000,\\n\\t37.764260000,-122.505140000,\\n\\t37.764260000,-122.505250000,\\n\\t37.764220000,-122.506220000,\\n\\t37.764170000,-122.507280000,\\n\\t37.764120000,-122.508360000,\\n\\t37.764100000,-122.508850000,\\n\\t37.764100000,-122.509150000,\\n\\t37.764100000,-122.509440000,\\n\\t37.764090000,-122.509760000,\\n\\t37.764080000,-122.510200000,\\n\\t37.764070000,-122.510320000,\\n\\t37.764060000,-122.510430000,\\n\\t37.764030000,-122.510430000,\\n\\t37.764030000,-122.510430000,\\n\\t37.763960000,-122.510430000,\\n\\t37.763960000,-122.510290000,\\n\\t37.764070000,-122.510320000,\\n\\t37.764170000,-122.510320000,\\n\\t37.764410000,-122.510340000,\\n\\t37.764610000,-122.510350000,\\n\\t37.764780000,-122.510330000,\\n\\t37.764960000,-122.510310000,\\n\\t37.765340000,-122.510280000,\\n\\t37.765570000,-122.510260000,\\n\\t37.765840000,-122.510250000,\\n\\t37.765900000,-122.510250000,\\n\\t37.766140000,-122.510260000,\\n\\t37.766410000,-122.510260000,\\n\\t37.766620000,-122.510270000,\\n\\t37.767040000,-122.510310000,\\n\\t37.767270000,-122.510330000,\\n\\t37.767620000,-122.510390000,\\n\\t37.767670000,-122.510390000,\\n\\t37.767740000,-122.510410000,\\n\\t37.767840000,-122.510430000,\\n\\t37.768280000,-122.510530000,\\n\\t37.768620000,-122.510600000,\\n\\t37.768690000,-122.510620000,\\n\\t37.769020000,-122.510690000,\\n\\t37.769260000,-122.510730000,\\n\\t37.769420000,-122.510750000,\\n\\t37.770010000,-122.510830000,\\n\\t37.770340000,-122.510860000,\\n\\t37.770460000,-122.510870000,\\n\\t37.770930000,-122.510930000,\\n\\t37.770980000,-122.510930000,\\n];\\n let value = gpsData.indexOf(prevValue); \\nreturn gpsData[(value == -1 ? 1 : value + 2)];\"}]}],\"timewindow\":{\"history\":{\"interval\":1000,\"timewindowMs\":60000},\"aggregation\":{\"type\":\"NONE\",\"limit\":500}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"mapProvider\":\"OpenStreetMap.Mapnik\",\"latKeyName\":\"latitude\",\"lngKeyName\":\"longitude\",\"showLabel\":true,\"label\":\"${entityName}\",\"showTooltip\":true,\"tooltipColor\":\"#fff\",\"tooltipFontColor\":\"#000\",\"tooltipOpacity\":1,\"tooltipPattern\":\"<b>${entityName}</b><br/><br/><b>Latitude:</b> ${latitude:7}<br/><b>Longitude:</b> ${longitude:7}<br/><b>End Time:</b> ${maxTime}<br/><b>Start Time:</b> ${minTime}\",\"strokeWeight\":2,\"strokeOpacity\":1,\"pointSize\":10,\"markerImageSize\":34,\"rotationAngle\":180},\"title\":\"Trip Animation\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"mobileHeight\":null,\"widgetStyle\":{},\"useDashboardTimewindow\":false,\"showLegend\":false,\"actions\":{},\"legendConfig\":{\"position\":\"bottom\",\"showMin\":false,\"showMax\":false,\"showAvg\":false,\"showTotal\":false}}" | 133 | "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"latitude\",\"color\":\"#2196f3\",\"settings\":{\"showLines\":true,\"fillLines\":true,\"showPoints\":false},\"_hash\":0.8587686344902596,\"funcBody\":\"var gpsData = [\\n\\t37.771210000,-122.510960000,\\n\\t37.771340000,-122.510980000,\\n\\t37.771340000,-122.510980000,\\n\\t37.771360000,-122.510850000,\\n\\t37.771380000,-122.510550000,\\n\\t37.771400000,-122.509900000,\\n\\t37.771410000,-122.509660000,\\n\\t37.771430000,-122.509360000,\\n\\t37.771430000,-122.509270000,\\n\\t37.771450000,-122.508840000,\\n\\t37.771490000,-122.507880000,\\n\\t37.771490000,-122.507780000,\\n\\t37.771530000,-122.507140000,\\n\\t37.771550000,-122.506690000,\\n\\t37.771560000,-122.506310000,\\n\\t37.771600000,-122.505640000,\\n\\t37.771650000,-122.504540000,\\n\\t37.771670000,-122.503990000,\\n\\t37.771700000,-122.503490000,\\n\\t37.771740000,-122.502430000,\\n\\t37.771790000,-122.501360000,\\n\\t37.771840000,-122.500290000,\\n\\t37.771870000,-122.499730000,\\n\\t37.771890000,-122.499210000,\\n\\t37.771940000,-122.498140000,\\n\\t37.771990000,-122.497070000,\\n\\t37.772000000,-122.496690000,\\n\\t37.772020000,-122.496350000,\\n\\t37.772030000,-122.496110000,\\n\\t37.772040000,-122.496000000,\\n\\t37.772040000,-122.495890000,\\n\\t37.772060000,-122.495440000,\\n\\t37.772090000,-122.494930000,\\n\\t37.772120000,-122.494160000,\\n\\t37.772130000,-122.493860000,\\n\\t37.772180000,-122.492790000,\\n\\t37.772200000,-122.492300000,\\n\\t37.772220000,-122.491840000,\\n\\t37.772230000,-122.491710000,\\n\\t37.772280000,-122.490630000,\\n\\t37.772330000,-122.489560000,\\n\\t37.772330000,-122.489470000,\\n\\t37.772360000,-122.489030000,\\n\\t37.772380000,-122.488490000,\\n\\t37.772430000,-122.487420000,\\n\\t37.772450000,-122.486980000,\\n\\t37.772480000,-122.486360000,\\n\\t37.772520000,-122.485280000,\\n\\t37.772560000,-122.484400000,\\n\\t37.772570000,-122.484300000,\\n\\t37.772570000,-122.484150000,\\n\\t37.772620000,-122.483140000,\\n\\t37.772680000,-122.482050000,\\n\\t37.772700000,-122.481370000,\\n\\t37.772710000,-122.481000000,\\n\\t37.772730000,-122.480740000,\\n\\t37.772770000,-122.479930000,\\n\\t37.772820000,-122.478860000,\\n\\t37.772870000,-122.477790000,\\n\\t37.772900000,-122.477110000,\\n\\t37.772920000,-122.476710000,\\n\\t37.772960000,-122.475650000,\\n\\t37.772990000,-122.474950000,\\n\\t37.773010000,-122.474580000,\\n\\t37.773060000,-122.473450000,\\n\\t37.773120000,-122.472330000,\\n\\t37.773140000,-122.471850000,\\n\\t37.773140000,-122.471730000,\\n\\t37.773150000,-122.471640000,\\n\\t37.773170000,-122.471260000,\\n\\t37.773190000,-122.470570000,\\n\\t37.773210000,-122.470190000,\\n\\t37.773230000,-122.469770000,\\n\\t37.773250000,-122.469370000,\\n\\t37.773260000,-122.469120000,\\n\\t37.773290000,-122.468490000,\\n\\t37.773300000,-122.468150000,\\n\\t37.773310000,-122.468050000,\\n\\t37.773310000,-122.467940000,\\n\\t37.773320000,-122.467740000,\\n\\t37.773350000,-122.467270000,\\n\\t37.773360000,-122.466980000,\\n\\t37.773360000,-122.466870000,\\n\\t37.773370000,-122.466610000,\\n\\t37.773390000,-122.466300000,\\n\\t37.773400000,-122.466000000,\\n\\t37.773400000,-122.465910000,\\n\\t37.773410000,-122.465790000,\\n\\t37.773430000,-122.465520000,\\n\\t37.773460000,-122.465210000,\\n\\t37.773490000,-122.464980000,\\n\\t37.773500000,-122.464910000,\\n\\t37.773460000,-122.464830000,\\n\\t37.773560000,-122.464070000,\\n\\t37.773580000,-122.463900000,\\n\\t37.773590000,-122.463810000,\\n\\t37.773600000,-122.463780000,\\n\\t37.773610000,-122.463670000,\\n\\t37.773660000,-122.463320000,\\n\\t37.773740000,-122.462700000,\\n\\t37.773770000,-122.462440000,\\n\\t37.773860000,-122.461730000,\\n\\t37.773870000,-122.461640000,\\n\\t37.773920000,-122.461260000,\\n\\t37.773970000,-122.460890000,\\n\\t37.774010000,-122.460570000,\\n\\t37.774110000,-122.459760000,\\n\\t37.774140000,-122.459490000,\\n\\t37.774270000,-122.458520000,\\n\\t37.774270000,-122.458440000,\\n\\t37.774270000,-122.458380000,\\n\\t37.774320000,-122.458270000,\\n\\t37.774340000,-122.458050000,\\n\\t37.774510000,-122.456680000,\\n\\t37.774560000,-122.456310000,\\n\\t37.774700000,-122.455280000,\\n\\t37.774760000,-122.454780000,\\n\\t37.774770000,-122.454670000,\\n\\t37.774770000,-122.454670000,\\n\\t37.774670000,-122.454650000,\\n\\t37.774670000,-122.454650000,\\n\\t37.774580000,-122.454640000,\\n\\t37.774300000,-122.454580000,\\n\\t37.774190000,-122.454560000,\\n\\t37.773700000,-122.454460000,\\n\\t37.772910000,-122.454310000,\\n\\t37.772620000,-122.454260000,\\n\\t37.772430000,-122.454220000,\\n\\t37.771980000,-122.454110000,\\n\\t37.771910000,-122.454100000,\\n\\t37.771760000,-122.454060000,\\n\\t37.771690000,-122.454050000,\\n\\t37.771620000,-122.454030000,\\n\\t37.771530000,-122.454010000,\\n\\t37.771380000,-122.453970000,\\n\\t37.771250000,-122.453950000,\\n\\t37.771100000,-122.453930000,\\n\\t37.771020000,-122.453920000,\\n\\t37.770920000,-122.453900000,\\n\\t37.770810000,-122.453890000,\\n\\t37.770660000,-122.453860000,\\n\\t37.770110000,-122.453750000,\\n\\t37.769560000,-122.453640000,\\n\\t37.769360000,-122.453600000,\\n\\t37.769250000,-122.453580000,\\n\\t37.769180000,-122.453560000,\\n\\t37.769090000,-122.453540000,\\n\\t37.768780000,-122.453480000,\\n\\t37.768250000,-122.453380000,\\n\\t37.768160000,-122.453360000,\\n\\t37.767820000,-122.453290000,\\n\\t37.767310000,-122.453190000,\\n\\t37.767160000,-122.453160000,\\n\\t37.767010000,-122.453130000,\\n\\t37.766760000,-122.453070000,\\n\\t37.766550000,-122.453030000,\\n\\t37.766550000,-122.453030000,\\n\\t37.766390000,-122.452990000,\\n\\t37.766390000,-122.452990000,\\n\\t37.766290000,-122.453720000,\\n\\t37.766180000,-122.454610000,\\n\\t37.766130000,-122.454980000,\\n\\t37.765960000,-122.456290000,\\n\\t37.765960000,-122.456340000,\\n\\t37.765960000,-122.456360000,\\n\\t37.765960000,-122.456380000,\\n\\t37.765960000,-122.456410000,\\n\\t37.765960000,-122.456460000,\\n\\t37.765940000,-122.456630000,\\n\\t37.765930000,-122.456700000,\\n\\t37.765920000,-122.456810000,\\n\\t37.765910000,-122.456930000,\\n\\t37.765910000,-122.457020000,\\n\\t37.765920000,-122.457160000,\\n\\t37.765930000,-122.457270000,\\n\\t37.765940000,-122.457360000,\\n\\t37.765950000,-122.457410000,\\n\\t37.765960000,-122.457470000,\\n\\t37.765980000,-122.457560000,\\n\\t37.766010000,-122.457660000,\\n\\t37.766070000,-122.457830000,\\n\\t37.766070000,-122.457830000,\\n\\t37.766120000,-122.457980000,\\n\\t37.766180000,-122.458180000,\\n\\t37.766190000,-122.458200000,\\n\\t37.766240000,-122.458400000,\\n\\t37.766270000,-122.458530000,\\n\\t37.766290000,-122.458600000,\\n\\t37.766300000,-122.458690000,\\n\\t37.766300000,-122.458880000,\\n\\t37.766300000,-122.458970000,\\n\\t37.766280000,-122.459470000,\\n\\t37.766270000,-122.459520000,\\n\\t37.766270000,-122.459560000,\\n\\t37.766280000,-122.459600000,\\n\\t37.766280000,-122.459630000,\\n\\t37.766290000,-122.459670000,\\n\\t37.766300000,-122.459700000,\\n\\t37.766310000,-122.459730000,\\n\\t37.766320000,-122.459750000,\\n\\t37.766330000,-122.459770000,\\n\\t37.766350000,-122.459800000,\\n\\t37.766390000,-122.459860000,\\n\\t37.766340000,-122.459970000,\\n\\t37.766290000,-122.460150000,\\n\\t37.766290000,-122.460230000,\\n\\t37.766280000,-122.460280000,\\n\\t37.766260000,-122.460330000,\\n\\t37.766250000,-122.460420000,\\n\\t37.766240000,-122.460520000,\\n\\t37.766230000,-122.460670000,\\n\\t37.766230000,-122.460800000,\\n\\t37.766230000,-122.460900000,\\n\\t37.766210000,-122.461110000,\\n\\t37.766170000,-122.462030000,\\n\\t37.766160000,-122.462170000,\\n\\t37.766150000,-122.462520000,\\n\\t37.766120000,-122.463260000,\\n\\t37.766090000,-122.464130000,\\n\\t37.766070000,-122.464350000,\\n\\t37.766070000,-122.464440000,\\n\\t37.766060000,-122.464620000,\\n\\t37.766030000,-122.465400000,\\n\\t37.765980000,-122.466470000,\\n\\t37.765940000,-122.467530000,\\n\\t37.765930000,-122.467680000,\\n\\t37.765890000,-122.468600000,\\n\\t37.765860000,-122.468980000,\\n\\t37.765830000,-122.469660000,\\n\\t37.765780000,-122.470740000,\\n\\t37.765770000,-122.471030000,\\n\\t37.765770000,-122.471140000,\\n\\t37.765760000,-122.471380000,\\n\\t37.765740000,-122.471820000,\\n\\t37.765690000,-122.472950000,\\n\\t37.765680000,-122.473220000,\\n\\t37.765670000,-122.473320000,\\n\\t37.765640000,-122.474070000,\\n\\t37.765590000,-122.475140000,\\n\\t37.765590000,-122.475400000,\\n\\t37.765580000,-122.475520000,\\n\\t37.765550000,-122.476200000,\\n\\t37.765500000,-122.477180000,\\n\\t37.765500000,-122.477280000,\\n\\t37.765490000,-122.477400000,\\n\\t37.765490000,-122.477440000,\\n\\t37.765490000,-122.477440000,\\n\\t37.765490000,-122.477490000,\\n\\t37.765470000,-122.477770000,\\n\\t37.765450000,-122.478340000,\\n\\t37.765450000,-122.478420000,\\n\\t37.765430000,-122.478870000,\\n\\t37.765400000,-122.479430000,\\n\\t37.765380000,-122.479810000,\\n\\t37.765350000,-122.480480000,\\n\\t37.765300000,-122.481570000,\\n\\t37.765300000,-122.481660000,\\n\\t37.765290000,-122.481950000,\\n\\t37.765260000,-122.482640000,\\n\\t37.765220000,-122.483570000,\\n\\t37.765210000,-122.483710000,\\n\\t37.765210000,-122.483810000,\\n\\t37.765190000,-122.484130000,\\n\\t37.765160000,-122.484780000,\\n\\t37.765120000,-122.485860000,\\n\\t37.765110000,-122.485960000,\\n\\t37.765100000,-122.486170000,\\n\\t37.765070000,-122.486930000,\\n\\t37.765020000,-122.488000000,\\n\\t37.765020000,-122.488100000,\\n\\t37.765000000,-122.488360000,\\n\\t37.764980000,-122.488970000,\\n\\t37.764970000,-122.489070000,\\n\\t37.764930000,-122.490150000,\\n\\t37.764920000,-122.490240000,\\n\\t37.764910000,-122.490490000,\\n\\t37.764880000,-122.491210000,\\n\\t37.764830000,-122.492290000,\\n\\t37.764790000,-122.493260000,\\n\\t37.764780000,-122.493350000,\\n\\t37.764740000,-122.494420000,\\n\\t37.764720000,-122.494730000,\\n\\t37.764710000,-122.495500000,\\n\\t37.764700000,-122.495630000,\\n\\t37.764690000,-122.495940000,\\n\\t37.764680000,-122.496260000,\\n\\t37.764670000,-122.496480000,\\n\\t37.764600000,-122.497490000,\\n\\t37.764590000,-122.497650000,\\n\\t37.764550000,-122.498720000,\\n\\t37.764500000,-122.499780000,\\n\\t37.764450000,-122.500870000,\\n\\t37.764440000,-122.501060000,\\n\\t37.764400000,-122.501930000,\\n\\t37.764360000,-122.502990000,\\n\\t37.764310000,-122.504080000,\\n\\t37.764260000,-122.505140000,\\n\\t37.764260000,-122.505250000,\\n\\t37.764220000,-122.506220000,\\n\\t37.764170000,-122.507280000,\\n\\t37.764120000,-122.508360000,\\n\\t37.764100000,-122.508850000,\\n\\t37.764100000,-122.509150000,\\n\\t37.764100000,-122.509440000,\\n\\t37.764090000,-122.509760000,\\n\\t37.764080000,-122.510200000,\\n\\t37.764070000,-122.510320000,\\n\\t37.764060000,-122.510430000,\\n\\t37.764030000,-122.510430000,\\n\\t37.764030000,-122.510430000,\\n\\t37.763960000,-122.510430000,\\n\\t37.763960000,-122.510290000,\\n\\t37.764070000,-122.510320000,\\n\\t37.764170000,-122.510320000,\\n\\t37.764410000,-122.510340000,\\n\\t37.764610000,-122.510350000,\\n\\t37.764780000,-122.510330000,\\n\\t37.764960000,-122.510310000,\\n\\t37.765340000,-122.510280000,\\n\\t37.765570000,-122.510260000,\\n\\t37.765840000,-122.510250000,\\n\\t37.765900000,-122.510250000,\\n\\t37.766140000,-122.510260000,\\n\\t37.766410000,-122.510260000,\\n\\t37.766620000,-122.510270000,\\n\\t37.767040000,-122.510310000,\\n\\t37.767270000,-122.510330000,\\n\\t37.767620000,-122.510390000,\\n\\t37.767670000,-122.510390000,\\n\\t37.767740000,-122.510410000,\\n\\t37.767840000,-122.510430000,\\n\\t37.768280000,-122.510530000,\\n\\t37.768620000,-122.510600000,\\n\\t37.768690000,-122.510620000,\\n\\t37.769020000,-122.510690000,\\n\\t37.769260000,-122.510730000,\\n\\t37.769420000,-122.510750000,\\n\\t37.770010000,-122.510830000,\\n\\t37.770340000,-122.510860000,\\n\\t37.770460000,-122.510870000,\\n\\t37.770930000,-122.510930000,\\n\\t37.770980000,-122.510930000,\\n];\\n let value = gpsData.indexOf(prevValue); \\nreturn gpsData[(value == -1 ? 0 : value + 2)];\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"longitude\",\"color\":\"#ffc107\",\"settings\":{\"showLines\":true,\"fillLines\":false,\"showPoints\":false},\"_hash\":0.12775350966079668,\"funcBody\":\"var gpsData = [\\n\\t37.771210000,-122.510960000,\\n\\t37.771340000,-122.510980000,\\n\\t37.771340000,-122.510980000,\\n\\t37.771360000,-122.510850000,\\n\\t37.771380000,-122.510550000,\\n\\t37.771400000,-122.509900000,\\n\\t37.771410000,-122.509660000,\\n\\t37.771430000,-122.509360000,\\n\\t37.771430000,-122.509270000,\\n\\t37.771450000,-122.508840000,\\n\\t37.771490000,-122.507880000,\\n\\t37.771490000,-122.507780000,\\n\\t37.771530000,-122.507140000,\\n\\t37.771550000,-122.506690000,\\n\\t37.771560000,-122.506310000,\\n\\t37.771600000,-122.505640000,\\n\\t37.771650000,-122.504540000,\\n\\t37.771670000,-122.503990000,\\n\\t37.771700000,-122.503490000,\\n\\t37.771740000,-122.502430000,\\n\\t37.771790000,-122.501360000,\\n\\t37.771840000,-122.500290000,\\n\\t37.771870000,-122.499730000,\\n\\t37.771890000,-122.499210000,\\n\\t37.771940000,-122.498140000,\\n\\t37.771990000,-122.497070000,\\n\\t37.772000000,-122.496690000,\\n\\t37.772020000,-122.496350000,\\n\\t37.772030000,-122.496110000,\\n\\t37.772040000,-122.496000000,\\n\\t37.772040000,-122.495890000,\\n\\t37.772060000,-122.495440000,\\n\\t37.772090000,-122.494930000,\\n\\t37.772120000,-122.494160000,\\n\\t37.772130000,-122.493860000,\\n\\t37.772180000,-122.492790000,\\n\\t37.772200000,-122.492300000,\\n\\t37.772220000,-122.491840000,\\n\\t37.772230000,-122.491710000,\\n\\t37.772280000,-122.490630000,\\n\\t37.772330000,-122.489560000,\\n\\t37.772330000,-122.489470000,\\n\\t37.772360000,-122.489030000,\\n\\t37.772380000,-122.488490000,\\n\\t37.772430000,-122.487420000,\\n\\t37.772450000,-122.486980000,\\n\\t37.772480000,-122.486360000,\\n\\t37.772520000,-122.485280000,\\n\\t37.772560000,-122.484400000,\\n\\t37.772570000,-122.484300000,\\n\\t37.772570000,-122.484150000,\\n\\t37.772620000,-122.483140000,\\n\\t37.772680000,-122.482050000,\\n\\t37.772700000,-122.481370000,\\n\\t37.772710000,-122.481000000,\\n\\t37.772730000,-122.480740000,\\n\\t37.772770000,-122.479930000,\\n\\t37.772820000,-122.478860000,\\n\\t37.772870000,-122.477790000,\\n\\t37.772900000,-122.477110000,\\n\\t37.772920000,-122.476710000,\\n\\t37.772960000,-122.475650000,\\n\\t37.772990000,-122.474950000,\\n\\t37.773010000,-122.474580000,\\n\\t37.773060000,-122.473450000,\\n\\t37.773120000,-122.472330000,\\n\\t37.773140000,-122.471850000,\\n\\t37.773140000,-122.471730000,\\n\\t37.773150000,-122.471640000,\\n\\t37.773170000,-122.471260000,\\n\\t37.773190000,-122.470570000,\\n\\t37.773210000,-122.470190000,\\n\\t37.773230000,-122.469770000,\\n\\t37.773250000,-122.469370000,\\n\\t37.773260000,-122.469120000,\\n\\t37.773290000,-122.468490000,\\n\\t37.773300000,-122.468150000,\\n\\t37.773310000,-122.468050000,\\n\\t37.773310000,-122.467940000,\\n\\t37.773320000,-122.467740000,\\n\\t37.773350000,-122.467270000,\\n\\t37.773360000,-122.466980000,\\n\\t37.773360000,-122.466870000,\\n\\t37.773370000,-122.466610000,\\n\\t37.773390000,-122.466300000,\\n\\t37.773400000,-122.466000000,\\n\\t37.773400000,-122.465910000,\\n\\t37.773410000,-122.465790000,\\n\\t37.773430000,-122.465520000,\\n\\t37.773460000,-122.465210000,\\n\\t37.773490000,-122.464980000,\\n\\t37.773500000,-122.464910000,\\n\\t37.773460000,-122.464830000,\\n\\t37.773560000,-122.464070000,\\n\\t37.773580000,-122.463900000,\\n\\t37.773590000,-122.463810000,\\n\\t37.773600000,-122.463780000,\\n\\t37.773610000,-122.463670000,\\n\\t37.773660000,-122.463320000,\\n\\t37.773740000,-122.462700000,\\n\\t37.773770000,-122.462440000,\\n\\t37.773860000,-122.461730000,\\n\\t37.773870000,-122.461640000,\\n\\t37.773920000,-122.461260000,\\n\\t37.773970000,-122.460890000,\\n\\t37.774010000,-122.460570000,\\n\\t37.774110000,-122.459760000,\\n\\t37.774140000,-122.459490000,\\n\\t37.774270000,-122.458520000,\\n\\t37.774270000,-122.458440000,\\n\\t37.774270000,-122.458380000,\\n\\t37.774320000,-122.458270000,\\n\\t37.774340000,-122.458050000,\\n\\t37.774510000,-122.456680000,\\n\\t37.774560000,-122.456310000,\\n\\t37.774700000,-122.455280000,\\n\\t37.774760000,-122.454780000,\\n\\t37.774770000,-122.454670000,\\n\\t37.774770000,-122.454670000,\\n\\t37.774670000,-122.454650000,\\n\\t37.774670000,-122.454650000,\\n\\t37.774580000,-122.454640000,\\n\\t37.774300000,-122.454580000,\\n\\t37.774190000,-122.454560000,\\n\\t37.773700000,-122.454460000,\\n\\t37.772910000,-122.454310000,\\n\\t37.772620000,-122.454260000,\\n\\t37.772430000,-122.454220000,\\n\\t37.771980000,-122.454110000,\\n\\t37.771910000,-122.454100000,\\n\\t37.771760000,-122.454060000,\\n\\t37.771690000,-122.454050000,\\n\\t37.771620000,-122.454030000,\\n\\t37.771530000,-122.454010000,\\n\\t37.771380000,-122.453970000,\\n\\t37.771250000,-122.453950000,\\n\\t37.771100000,-122.453930000,\\n\\t37.771020000,-122.453920000,\\n\\t37.770920000,-122.453900000,\\n\\t37.770810000,-122.453890000,\\n\\t37.770660000,-122.453860000,\\n\\t37.770110000,-122.453750000,\\n\\t37.769560000,-122.453640000,\\n\\t37.769360000,-122.453600000,\\n\\t37.769250000,-122.453580000,\\n\\t37.769180000,-122.453560000,\\n\\t37.769090000,-122.453540000,\\n\\t37.768780000,-122.453480000,\\n\\t37.768250000,-122.453380000,\\n\\t37.768160000,-122.453360000,\\n\\t37.767820000,-122.453290000,\\n\\t37.767310000,-122.453190000,\\n\\t37.767160000,-122.453160000,\\n\\t37.767010000,-122.453130000,\\n\\t37.766760000,-122.453070000,\\n\\t37.766550000,-122.453030000,\\n\\t37.766550000,-122.453030000,\\n\\t37.766390000,-122.452990000,\\n\\t37.766390000,-122.452990000,\\n\\t37.766290000,-122.453720000,\\n\\t37.766180000,-122.454610000,\\n\\t37.766130000,-122.454980000,\\n\\t37.765960000,-122.456290000,\\n\\t37.765960000,-122.456340000,\\n\\t37.765960000,-122.456360000,\\n\\t37.765960000,-122.456380000,\\n\\t37.765960000,-122.456410000,\\n\\t37.765960000,-122.456460000,\\n\\t37.765940000,-122.456630000,\\n\\t37.765930000,-122.456700000,\\n\\t37.765920000,-122.456810000,\\n\\t37.765910000,-122.456930000,\\n\\t37.765910000,-122.457020000,\\n\\t37.765920000,-122.457160000,\\n\\t37.765930000,-122.457270000,\\n\\t37.765940000,-122.457360000,\\n\\t37.765950000,-122.457410000,\\n\\t37.765960000,-122.457470000,\\n\\t37.765980000,-122.457560000,\\n\\t37.766010000,-122.457660000,\\n\\t37.766070000,-122.457830000,\\n\\t37.766070000,-122.457830000,\\n\\t37.766120000,-122.457980000,\\n\\t37.766180000,-122.458180000,\\n\\t37.766190000,-122.458200000,\\n\\t37.766240000,-122.458400000,\\n\\t37.766270000,-122.458530000,\\n\\t37.766290000,-122.458600000,\\n\\t37.766300000,-122.458690000,\\n\\t37.766300000,-122.458880000,\\n\\t37.766300000,-122.458970000,\\n\\t37.766280000,-122.459470000,\\n\\t37.766270000,-122.459520000,\\n\\t37.766270000,-122.459560000,\\n\\t37.766280000,-122.459600000,\\n\\t37.766280000,-122.459630000,\\n\\t37.766290000,-122.459670000,\\n\\t37.766300000,-122.459700000,\\n\\t37.766310000,-122.459730000,\\n\\t37.766320000,-122.459750000,\\n\\t37.766330000,-122.459770000,\\n\\t37.766350000,-122.459800000,\\n\\t37.766390000,-122.459860000,\\n\\t37.766340000,-122.459970000,\\n\\t37.766290000,-122.460150000,\\n\\t37.766290000,-122.460230000,\\n\\t37.766280000,-122.460280000,\\n\\t37.766260000,-122.460330000,\\n\\t37.766250000,-122.460420000,\\n\\t37.766240000,-122.460520000,\\n\\t37.766230000,-122.460670000,\\n\\t37.766230000,-122.460800000,\\n\\t37.766230000,-122.460900000,\\n\\t37.766210000,-122.461110000,\\n\\t37.766170000,-122.462030000,\\n\\t37.766160000,-122.462170000,\\n\\t37.766150000,-122.462520000,\\n\\t37.766120000,-122.463260000,\\n\\t37.766090000,-122.464130000,\\n\\t37.766070000,-122.464350000,\\n\\t37.766070000,-122.464440000,\\n\\t37.766060000,-122.464620000,\\n\\t37.766030000,-122.465400000,\\n\\t37.765980000,-122.466470000,\\n\\t37.765940000,-122.467530000,\\n\\t37.765930000,-122.467680000,\\n\\t37.765890000,-122.468600000,\\n\\t37.765860000,-122.468980000,\\n\\t37.765830000,-122.469660000,\\n\\t37.765780000,-122.470740000,\\n\\t37.765770000,-122.471030000,\\n\\t37.765770000,-122.471140000,\\n\\t37.765760000,-122.471380000,\\n\\t37.765740000,-122.471820000,\\n\\t37.765690000,-122.472950000,\\n\\t37.765680000,-122.473220000,\\n\\t37.765670000,-122.473320000,\\n\\t37.765640000,-122.474070000,\\n\\t37.765590000,-122.475140000,\\n\\t37.765590000,-122.475400000,\\n\\t37.765580000,-122.475520000,\\n\\t37.765550000,-122.476200000,\\n\\t37.765500000,-122.477180000,\\n\\t37.765500000,-122.477280000,\\n\\t37.765490000,-122.477400000,\\n\\t37.765490000,-122.477440000,\\n\\t37.765490000,-122.477440000,\\n\\t37.765490000,-122.477490000,\\n\\t37.765470000,-122.477770000,\\n\\t37.765450000,-122.478340000,\\n\\t37.765450000,-122.478420000,\\n\\t37.765430000,-122.478870000,\\n\\t37.765400000,-122.479430000,\\n\\t37.765380000,-122.479810000,\\n\\t37.765350000,-122.480480000,\\n\\t37.765300000,-122.481570000,\\n\\t37.765300000,-122.481660000,\\n\\t37.765290000,-122.481950000,\\n\\t37.765260000,-122.482640000,\\n\\t37.765220000,-122.483570000,\\n\\t37.765210000,-122.483710000,\\n\\t37.765210000,-122.483810000,\\n\\t37.765190000,-122.484130000,\\n\\t37.765160000,-122.484780000,\\n\\t37.765120000,-122.485860000,\\n\\t37.765110000,-122.485960000,\\n\\t37.765100000,-122.486170000,\\n\\t37.765070000,-122.486930000,\\n\\t37.765020000,-122.488000000,\\n\\t37.765020000,-122.488100000,\\n\\t37.765000000,-122.488360000,\\n\\t37.764980000,-122.488970000,\\n\\t37.764970000,-122.489070000,\\n\\t37.764930000,-122.490150000,\\n\\t37.764920000,-122.490240000,\\n\\t37.764910000,-122.490490000,\\n\\t37.764880000,-122.491210000,\\n\\t37.764830000,-122.492290000,\\n\\t37.764790000,-122.493260000,\\n\\t37.764780000,-122.493350000,\\n\\t37.764740000,-122.494420000,\\n\\t37.764720000,-122.494730000,\\n\\t37.764710000,-122.495500000,\\n\\t37.764700000,-122.495630000,\\n\\t37.764690000,-122.495940000,\\n\\t37.764680000,-122.496260000,\\n\\t37.764670000,-122.496480000,\\n\\t37.764600000,-122.497490000,\\n\\t37.764590000,-122.497650000,\\n\\t37.764550000,-122.498720000,\\n\\t37.764500000,-122.499780000,\\n\\t37.764450000,-122.500870000,\\n\\t37.764440000,-122.501060000,\\n\\t37.764400000,-122.501930000,\\n\\t37.764360000,-122.502990000,\\n\\t37.764310000,-122.504080000,\\n\\t37.764260000,-122.505140000,\\n\\t37.764260000,-122.505250000,\\n\\t37.764220000,-122.506220000,\\n\\t37.764170000,-122.507280000,\\n\\t37.764120000,-122.508360000,\\n\\t37.764100000,-122.508850000,\\n\\t37.764100000,-122.509150000,\\n\\t37.764100000,-122.509440000,\\n\\t37.764090000,-122.509760000,\\n\\t37.764080000,-122.510200000,\\n\\t37.764070000,-122.510320000,\\n\\t37.764060000,-122.510430000,\\n\\t37.764030000,-122.510430000,\\n\\t37.764030000,-122.510430000,\\n\\t37.763960000,-122.510430000,\\n\\t37.763960000,-122.510290000,\\n\\t37.764070000,-122.510320000,\\n\\t37.764170000,-122.510320000,\\n\\t37.764410000,-122.510340000,\\n\\t37.764610000,-122.510350000,\\n\\t37.764780000,-122.510330000,\\n\\t37.764960000,-122.510310000,\\n\\t37.765340000,-122.510280000,\\n\\t37.765570000,-122.510260000,\\n\\t37.765840000,-122.510250000,\\n\\t37.765900000,-122.510250000,\\n\\t37.766140000,-122.510260000,\\n\\t37.766410000,-122.510260000,\\n\\t37.766620000,-122.510270000,\\n\\t37.767040000,-122.510310000,\\n\\t37.767270000,-122.510330000,\\n\\t37.767620000,-122.510390000,\\n\\t37.767670000,-122.510390000,\\n\\t37.767740000,-122.510410000,\\n\\t37.767840000,-122.510430000,\\n\\t37.768280000,-122.510530000,\\n\\t37.768620000,-122.510600000,\\n\\t37.768690000,-122.510620000,\\n\\t37.769020000,-122.510690000,\\n\\t37.769260000,-122.510730000,\\n\\t37.769420000,-122.510750000,\\n\\t37.770010000,-122.510830000,\\n\\t37.770340000,-122.510860000,\\n\\t37.770460000,-122.510870000,\\n\\t37.770930000,-122.510930000,\\n\\t37.770980000,-122.510930000,\\n];\\n let value = gpsData.indexOf(prevValue); \\nreturn gpsData[(value == -1 ? 1 : value + 2)];\"}]}],\"timewindow\":{\"history\":{\"interval\":1000,\"timewindowMs\":60000},\"aggregation\":{\"type\":\"NONE\",\"limit\":500}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"mapProvider\":\"OpenStreetMap.Mapnik\",\"latKeyName\":\"latitude\",\"lngKeyName\":\"longitude\",\"showLabel\":true,\"label\":\"${entityName}\",\"showTooltip\":true,\"tooltipColor\":\"#fff\",\"tooltipFontColor\":\"#000\",\"tooltipOpacity\":1,\"tooltipPattern\":\"<b>${entityName}</b><br/><br/><b>Latitude:</b> ${latitude:7}<br/><b>Longitude:</b> ${longitude:7}<br/><b>End Time:</b> ${maxTime}<br/><b>Start Time:</b> ${minTime}\",\"strokeWeight\":2,\"strokeOpacity\":1,\"pointSize\":10,\"markerImageSize\":34,\"rotationAngle\":180},\"title\":\"Trip Animation\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"mobileHeight\":null,\"widgetStyle\":{},\"useDashboardTimewindow\":false,\"showLegend\":false,\"actions\":{},\"legendConfig\":{\"position\":\"bottom\",\"showMin\":false,\"showMax\":false,\"showAvg\":false,\"showTotal\":false}}" |
134 | } | 134 | } |
135 | } | 135 | } |
136 | ] | 136 | ] |
137 | -} | ||
137 | +} |
1 | +-- | ||
2 | +-- Copyright © 2016-2020 The Thingsboard Authors | ||
3 | +-- | ||
4 | +-- Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +-- you may not use this file except in compliance with the License. | ||
6 | +-- You may obtain a copy of the License at | ||
7 | +-- | ||
8 | +-- http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +-- | ||
10 | +-- Unless required by applicable law or agreed to in writing, software | ||
11 | +-- distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +-- See the License for the specific language governing permissions and | ||
14 | +-- limitations under the License. | ||
15 | +-- | ||
16 | + | ||
17 | +CREATE OR REPLACE PROCEDURE drop_partitions_by_max_ttl(IN partition_type varchar, IN system_ttl bigint, INOUT deleted bigint) | ||
18 | + LANGUAGE plpgsql AS | ||
19 | +$$ | ||
20 | +DECLARE | ||
21 | + max_tenant_ttl bigint; | ||
22 | + max_customer_ttl bigint; | ||
23 | + max_ttl bigint; | ||
24 | + date timestamp; | ||
25 | + partition_by_max_ttl_date varchar; | ||
26 | + partition_month varchar; | ||
27 | + partition_day varchar; | ||
28 | + partition_year varchar; | ||
29 | + partition varchar; | ||
30 | + partition_to_delete varchar; | ||
31 | + | ||
32 | + | ||
33 | +BEGIN | ||
34 | + SELECT max(attribute_kv.long_v) | ||
35 | + FROM tenant | ||
36 | + INNER JOIN attribute_kv ON tenant.id = attribute_kv.entity_id | ||
37 | + WHERE attribute_kv.attribute_key = 'TTL' | ||
38 | + into max_tenant_ttl; | ||
39 | + SELECT max(attribute_kv.long_v) | ||
40 | + FROM customer | ||
41 | + INNER JOIN attribute_kv ON customer.id = attribute_kv.entity_id | ||
42 | + WHERE attribute_kv.attribute_key = 'TTL' | ||
43 | + into max_customer_ttl; | ||
44 | + max_ttl := GREATEST(system_ttl, max_customer_ttl, max_tenant_ttl); | ||
45 | + if max_ttl IS NOT NULL AND max_ttl > 0 THEN | ||
46 | + date := to_timestamp(EXTRACT(EPOCH FROM current_timestamp) - (max_ttl / 1000)); | ||
47 | + partition_by_max_ttl_date := get_partition_by_max_ttl_date(partition_type, date); | ||
48 | + RAISE NOTICE 'Partition by max ttl: %', partition_by_max_ttl_date; | ||
49 | + IF partition_by_max_ttl_date IS NOT NULL THEN | ||
50 | + CASE | ||
51 | + WHEN partition_type = 'DAYS' THEN | ||
52 | + partition_year := SPLIT_PART(partition_by_max_ttl_date, '_', 3); | ||
53 | + partition_month := SPLIT_PART(partition_by_max_ttl_date, '_', 4); | ||
54 | + partition_day := SPLIT_PART(partition_by_max_ttl_date, '_', 5); | ||
55 | + WHEN partition_type = 'MONTHS' THEN | ||
56 | + partition_year := SPLIT_PART(partition_by_max_ttl_date, '_', 3); | ||
57 | + partition_month := SPLIT_PART(partition_by_max_ttl_date, '_', 4); | ||
58 | + ELSE | ||
59 | + partition_year := SPLIT_PART(partition_by_max_ttl_date, '_', 3); | ||
60 | + END CASE; | ||
61 | + FOR partition IN SELECT tablename | ||
62 | + FROM pg_tables | ||
63 | + WHERE schemaname = 'public' | ||
64 | + AND tablename like 'ts_kv_' || '%' | ||
65 | + AND tablename != 'ts_kv_latest' | ||
66 | + AND tablename != 'ts_kv_dictionary' | ||
67 | + LOOP | ||
68 | + IF partition != partition_by_max_ttl_date THEN | ||
69 | + IF partition_year IS NOT NULL THEN | ||
70 | + IF SPLIT_PART(partition, '_', 3)::integer < partition_year::integer THEN | ||
71 | + partition_to_delete := partition; | ||
72 | + ELSE | ||
73 | + IF partition_month IS NOT NULL THEN | ||
74 | + IF SPLIT_PART(partition, '_', 4)::integer < partition_month::integer THEN | ||
75 | + partition_to_delete := partition; | ||
76 | + ELSE | ||
77 | + IF partition_day IS NOT NULL THEN | ||
78 | + IF SPLIT_PART(partition, '_', 5)::integer < partition_day::integer THEN | ||
79 | + partition_to_delete := partition; | ||
80 | + END IF; | ||
81 | + END IF; | ||
82 | + END IF; | ||
83 | + END IF; | ||
84 | + END IF; | ||
85 | + END IF; | ||
86 | + END IF; | ||
87 | + IF partition_to_delete IS NOT NULL THEN | ||
88 | + RAISE NOTICE 'Partition to delete by max ttl: %', partition_to_delete; | ||
89 | + EXECUTE format('DROP TABLE %I', partition_to_delete); | ||
90 | + deleted := deleted + 1; | ||
91 | + END IF; | ||
92 | + END LOOP; | ||
93 | + END IF; | ||
94 | + END IF; | ||
95 | +END | ||
96 | +$$; | ||
97 | + | ||
98 | +CREATE OR REPLACE FUNCTION get_partition_by_max_ttl_date(IN partition_type varchar, IN date timestamp, OUT partition varchar) AS | ||
99 | +$$ | ||
100 | +BEGIN | ||
101 | + CASE | ||
102 | + WHEN partition_type = 'DAYS' THEN | ||
103 | + partition := 'ts_kv_' || to_char(date, 'yyyy') || '_' || to_char(date, 'MM') || '_' || to_char(date, 'dd'); | ||
104 | + WHEN partition_type = 'MONTHS' THEN | ||
105 | + partition := 'ts_kv_' || to_char(date, 'yyyy') || '_' || to_char(date, 'MM'); | ||
106 | + WHEN partition_type = 'YEARS' THEN | ||
107 | + partition := 'ts_kv_' || to_char(date, 'yyyy'); | ||
108 | + WHEN partition_type = 'INDEFINITE' THEN | ||
109 | + partition := NULL; | ||
110 | + ELSE | ||
111 | + partition := NULL; | ||
112 | + END CASE; | ||
113 | + IF partition IS NOT NULL THEN | ||
114 | + IF NOT EXISTS(SELECT | ||
115 | + FROM pg_tables | ||
116 | + WHERE schemaname = 'public' | ||
117 | + AND tablename = partition) THEN | ||
118 | + partition := NULL; | ||
119 | + RAISE NOTICE 'Failed to found partition by ttl'; | ||
120 | + END IF; | ||
121 | + END IF; | ||
122 | +END; | ||
123 | +$$ LANGUAGE plpgsql; |
1 | +-- | ||
2 | +-- Copyright © 2016-2020 The Thingsboard Authors | ||
3 | +-- | ||
4 | +-- Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +-- you may not use this file except in compliance with the License. | ||
6 | +-- You may obtain a copy of the License at | ||
7 | +-- | ||
8 | +-- http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +-- | ||
10 | +-- Unless required by applicable law or agreed to in writing, software | ||
11 | +-- distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +-- See the License for the specific language governing permissions and | ||
14 | +-- limitations under the License. | ||
15 | +-- | ||
16 | + | ||
17 | +-- call create_partition_ts_kv_table(); | ||
18 | + | ||
19 | +CREATE OR REPLACE PROCEDURE create_partition_ts_kv_table() LANGUAGE plpgsql AS $$ | ||
20 | + | ||
21 | +BEGIN | ||
22 | + ALTER TABLE ts_kv | ||
23 | + RENAME TO ts_kv_old; | ||
24 | + ALTER TABLE ts_kv_old | ||
25 | + RENAME CONSTRAINT ts_kv_pkey TO ts_kv_pkey_old; | ||
26 | + CREATE TABLE IF NOT EXISTS ts_kv | ||
27 | + ( | ||
28 | + LIKE ts_kv_old | ||
29 | + ) | ||
30 | + PARTITION BY RANGE (ts); | ||
31 | + ALTER TABLE ts_kv | ||
32 | + DROP COLUMN entity_type; | ||
33 | + ALTER TABLE ts_kv | ||
34 | + ALTER COLUMN entity_id TYPE uuid USING entity_id::uuid; | ||
35 | + ALTER TABLE ts_kv | ||
36 | + ALTER COLUMN key TYPE integer USING key::integer; | ||
37 | + ALTER TABLE ts_kv | ||
38 | + ADD CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_id, key, ts); | ||
39 | +END; | ||
40 | +$$; | ||
41 | + | ||
42 | +-- call create_new_ts_kv_latest_table(); | ||
43 | + | ||
44 | +CREATE OR REPLACE PROCEDURE create_new_ts_kv_latest_table() LANGUAGE plpgsql AS $$ | ||
45 | + | ||
46 | +BEGIN | ||
47 | + ALTER TABLE ts_kv_latest | ||
48 | + RENAME TO ts_kv_latest_old; | ||
49 | + ALTER TABLE ts_kv_latest_old | ||
50 | + RENAME CONSTRAINT ts_kv_latest_pkey TO ts_kv_latest_pkey_old; | ||
51 | + CREATE TABLE IF NOT EXISTS ts_kv_latest | ||
52 | + ( | ||
53 | + LIKE ts_kv_latest_old | ||
54 | + ); | ||
55 | + ALTER TABLE ts_kv_latest | ||
56 | + DROP COLUMN entity_type; | ||
57 | + ALTER TABLE ts_kv_latest | ||
58 | + ALTER COLUMN entity_id TYPE uuid USING entity_id::uuid; | ||
59 | + ALTER TABLE ts_kv_latest | ||
60 | + ALTER COLUMN key TYPE integer USING key::integer; | ||
61 | + ALTER TABLE ts_kv_latest | ||
62 | + ADD CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key); | ||
63 | +END; | ||
64 | +$$; | ||
65 | + | ||
66 | +CREATE OR REPLACE FUNCTION get_partitions_data(IN partition_type varchar) | ||
67 | + RETURNS | ||
68 | + TABLE | ||
69 | + ( | ||
70 | + partition_date text, | ||
71 | + from_ts bigint, | ||
72 | + to_ts bigint | ||
73 | + ) | ||
74 | +AS | ||
75 | +$$ | ||
76 | +BEGIN | ||
77 | + CASE | ||
78 | + WHEN partition_type = 'DAYS' THEN | ||
79 | + RETURN QUERY SELECT day_date.day AS partition_date, | ||
80 | + (extract(epoch from (day_date.day)::timestamp) * 1000)::bigint AS from_ts, | ||
81 | + (extract(epoch from (day_date.day::date + INTERVAL '1 DAY')::timestamp) * | ||
82 | + 1000)::bigint AS to_ts | ||
83 | + FROM (SELECT DISTINCT TO_CHAR(TO_TIMESTAMP(ts / 1000), 'YYYY_MM_DD') AS day | ||
84 | + FROM ts_kv_old) AS day_date; | ||
85 | + WHEN partition_type = 'MONTHS' THEN | ||
86 | + RETURN QUERY SELECT SUBSTRING(month_date.first_date, 1, 7) AS partition_date, | ||
87 | + (extract(epoch from (month_date.first_date)::timestamp) * 1000)::bigint AS from_ts, | ||
88 | + (extract(epoch from (month_date.first_date::date + INTERVAL '1 MONTH')::timestamp) * | ||
89 | + 1000)::bigint AS to_ts | ||
90 | + FROM (SELECT DISTINCT TO_CHAR(TO_TIMESTAMP(ts / 1000), 'YYYY_MM_01') AS first_date | ||
91 | + FROM ts_kv_old) AS month_date; | ||
92 | + WHEN partition_type = 'YEARS' THEN | ||
93 | + RETURN QUERY SELECT SUBSTRING(year_date.year, 1, 4) AS partition_date, | ||
94 | + (extract(epoch from (year_date.year)::timestamp) * 1000)::bigint AS from_ts, | ||
95 | + (extract(epoch from (year_date.year::date + INTERVAL '1 YEAR')::timestamp) * | ||
96 | + 1000)::bigint AS to_ts | ||
97 | + FROM (SELECT DISTINCT TO_CHAR(TO_TIMESTAMP(ts / 1000), 'YYYY_01_01') AS year FROM ts_kv_old) AS year_date; | ||
98 | + ELSE | ||
99 | + RAISE EXCEPTION 'Failed to parse partitioning property: % !', partition_type; | ||
100 | + END CASE; | ||
101 | +END; | ||
102 | +$$ LANGUAGE plpgsql; | ||
103 | + | ||
104 | +-- call create_partitions(); | ||
105 | + | ||
106 | +CREATE OR REPLACE PROCEDURE create_partitions(IN partition_type varchar) LANGUAGE plpgsql AS $$ | ||
107 | + | ||
108 | +DECLARE | ||
109 | + partition_date varchar; | ||
110 | + from_ts bigint; | ||
111 | + to_ts bigint; | ||
112 | + partitions_cursor CURSOR FOR SELECT * FROM get_partitions_data(partition_type); | ||
113 | +BEGIN | ||
114 | + OPEN partitions_cursor; | ||
115 | + LOOP | ||
116 | + FETCH partitions_cursor INTO partition_date, from_ts, to_ts; | ||
117 | + EXIT WHEN NOT FOUND; | ||
118 | + EXECUTE 'CREATE TABLE IF NOT EXISTS ts_kv_' || partition_date || | ||
119 | + ' PARTITION OF ts_kv FOR VALUES FROM (' || from_ts || | ||
120 | + ') TO (' || to_ts || ');'; | ||
121 | + RAISE NOTICE 'A partition % has been created!',CONCAT('ts_kv_', partition_date); | ||
122 | + END LOOP; | ||
123 | + | ||
124 | + CLOSE partitions_cursor; | ||
125 | +END; | ||
126 | +$$; | ||
127 | + | ||
128 | +-- call create_ts_kv_dictionary_table(); | ||
129 | + | ||
130 | +CREATE OR REPLACE PROCEDURE create_ts_kv_dictionary_table() LANGUAGE plpgsql AS $$ | ||
131 | + | ||
132 | +BEGIN | ||
133 | + CREATE TABLE IF NOT EXISTS ts_kv_dictionary | ||
134 | + ( | ||
135 | + key varchar(255) NOT NULL, | ||
136 | + key_id serial UNIQUE, | ||
137 | + CONSTRAINT ts_key_id_pkey PRIMARY KEY (key) | ||
138 | + ); | ||
139 | +END; | ||
140 | +$$; | ||
141 | + | ||
142 | +-- call insert_into_dictionary(); | ||
143 | + | ||
144 | +CREATE OR REPLACE PROCEDURE insert_into_dictionary() LANGUAGE plpgsql AS $$ | ||
145 | + | ||
146 | +DECLARE | ||
147 | + insert_record RECORD; | ||
148 | + key_cursor CURSOR FOR SELECT DISTINCT key | ||
149 | + FROM ts_kv_old | ||
150 | + ORDER BY key; | ||
151 | +BEGIN | ||
152 | + OPEN key_cursor; | ||
153 | + LOOP | ||
154 | + FETCH key_cursor INTO insert_record; | ||
155 | + EXIT WHEN NOT FOUND; | ||
156 | + IF NOT EXISTS(SELECT key FROM ts_kv_dictionary WHERE key = insert_record.key) THEN | ||
157 | + INSERT INTO ts_kv_dictionary(key) VALUES (insert_record.key); | ||
158 | + RAISE NOTICE 'Key: % has been inserted into the dictionary!',insert_record.key; | ||
159 | + ELSE | ||
160 | + RAISE NOTICE 'Key: % already exists in the dictionary!',insert_record.key; | ||
161 | + END IF; | ||
162 | + END LOOP; | ||
163 | + CLOSE key_cursor; | ||
164 | +END; | ||
165 | +$$; | ||
166 | + | ||
167 | +-- call insert_into_ts_kv(); | ||
168 | + | ||
169 | +CREATE OR REPLACE PROCEDURE insert_into_ts_kv() LANGUAGE plpgsql AS $$ | ||
170 | +DECLARE | ||
171 | + insert_size CONSTANT integer := 10000; | ||
172 | + insert_counter integer DEFAULT 0; | ||
173 | + insert_record RECORD; | ||
174 | + insert_cursor CURSOR FOR SELECT CONCAT(entity_id_uuid_first_part, '-', entity_id_uuid_second_part, '-1', entity_id_uuid_third_part, '-', entity_id_uuid_fourth_part, '-', entity_id_uuid_fifth_part)::uuid AS entity_id, | ||
175 | + ts_kv_records.key AS key, | ||
176 | + ts_kv_records.ts AS ts, | ||
177 | + ts_kv_records.bool_v AS bool_v, | ||
178 | + ts_kv_records.str_v AS str_v, | ||
179 | + ts_kv_records.long_v AS long_v, | ||
180 | + ts_kv_records.dbl_v AS dbl_v | ||
181 | + FROM (SELECT SUBSTRING(entity_id, 8, 8) AS entity_id_uuid_first_part, | ||
182 | + SUBSTRING(entity_id, 4, 4) AS entity_id_uuid_second_part, | ||
183 | + SUBSTRING(entity_id, 1, 3) AS entity_id_uuid_third_part, | ||
184 | + SUBSTRING(entity_id, 16, 4) AS entity_id_uuid_fourth_part, | ||
185 | + SUBSTRING(entity_id, 20) AS entity_id_uuid_fifth_part, | ||
186 | + key_id AS key, | ||
187 | + ts, | ||
188 | + bool_v, | ||
189 | + str_v, | ||
190 | + long_v, | ||
191 | + dbl_v | ||
192 | + FROM ts_kv_old | ||
193 | + INNER JOIN ts_kv_dictionary ON (ts_kv_old.key = ts_kv_dictionary.key)) AS ts_kv_records; | ||
194 | +BEGIN | ||
195 | + OPEN insert_cursor; | ||
196 | + LOOP | ||
197 | + insert_counter := insert_counter + 1; | ||
198 | + FETCH insert_cursor INTO insert_record; | ||
199 | + IF NOT FOUND THEN | ||
200 | + RAISE NOTICE '% records have been inserted into the partitioned ts_kv!',insert_counter - 1; | ||
201 | + EXIT; | ||
202 | + END IF; | ||
203 | + INSERT INTO ts_kv(entity_id, key, ts, bool_v, str_v, long_v, dbl_v) | ||
204 | + VALUES (insert_record.entity_id, insert_record.key, insert_record.ts, insert_record.bool_v, insert_record.str_v, | ||
205 | + insert_record.long_v, insert_record.dbl_v); | ||
206 | + IF MOD(insert_counter, insert_size) = 0 THEN | ||
207 | + RAISE NOTICE '% records have been inserted into the partitioned ts_kv!',insert_counter; | ||
208 | + END IF; | ||
209 | + END LOOP; | ||
210 | + CLOSE insert_cursor; | ||
211 | +END; | ||
212 | +$$; | ||
213 | + | ||
214 | +-- call insert_into_ts_kv_latest(); | ||
215 | + | ||
216 | +CREATE OR REPLACE PROCEDURE insert_into_ts_kv_latest() LANGUAGE plpgsql AS $$ | ||
217 | +DECLARE | ||
218 | + insert_size CONSTANT integer := 10000; | ||
219 | + insert_counter integer DEFAULT 0; | ||
220 | + insert_record RECORD; | ||
221 | + insert_cursor CURSOR FOR SELECT CONCAT(entity_id_uuid_first_part, '-', entity_id_uuid_second_part, '-1', entity_id_uuid_third_part, '-', entity_id_uuid_fourth_part, '-', entity_id_uuid_fifth_part)::uuid AS entity_id, | ||
222 | + ts_kv_latest_records.key AS key, | ||
223 | + ts_kv_latest_records.ts AS ts, | ||
224 | + ts_kv_latest_records.bool_v AS bool_v, | ||
225 | + ts_kv_latest_records.str_v AS str_v, | ||
226 | + ts_kv_latest_records.long_v AS long_v, | ||
227 | + ts_kv_latest_records.dbl_v AS dbl_v | ||
228 | + FROM (SELECT SUBSTRING(entity_id, 8, 8) AS entity_id_uuid_first_part, | ||
229 | + SUBSTRING(entity_id, 4, 4) AS entity_id_uuid_second_part, | ||
230 | + SUBSTRING(entity_id, 1, 3) AS entity_id_uuid_third_part, | ||
231 | + SUBSTRING(entity_id, 16, 4) AS entity_id_uuid_fourth_part, | ||
232 | + SUBSTRING(entity_id, 20) AS entity_id_uuid_fifth_part, | ||
233 | + key_id AS key, | ||
234 | + ts, | ||
235 | + bool_v, | ||
236 | + str_v, | ||
237 | + long_v, | ||
238 | + dbl_v | ||
239 | + FROM ts_kv_latest_old | ||
240 | + INNER JOIN ts_kv_dictionary ON (ts_kv_latest_old.key = ts_kv_dictionary.key)) AS ts_kv_latest_records; | ||
241 | +BEGIN | ||
242 | + OPEN insert_cursor; | ||
243 | + LOOP | ||
244 | + insert_counter := insert_counter + 1; | ||
245 | + FETCH insert_cursor INTO insert_record; | ||
246 | + IF NOT FOUND THEN | ||
247 | + RAISE NOTICE '% records have been inserted into the ts_kv_latest!',insert_counter - 1; | ||
248 | + EXIT; | ||
249 | + END IF; | ||
250 | + INSERT INTO ts_kv_latest(entity_id, key, ts, bool_v, str_v, long_v, dbl_v) | ||
251 | + VALUES (insert_record.entity_id, insert_record.key, insert_record.ts, insert_record.bool_v, insert_record.str_v, | ||
252 | + insert_record.long_v, insert_record.dbl_v); | ||
253 | + IF MOD(insert_counter, insert_size) = 0 THEN | ||
254 | + RAISE NOTICE '% records have been inserted into the ts_kv_latest!',insert_counter; | ||
255 | + END IF; | ||
256 | + END LOOP; | ||
257 | + CLOSE insert_cursor; | ||
258 | +END; | ||
259 | +$$; | ||
260 | + | ||
261 | + |
1 | +-- | ||
2 | +-- Copyright © 2016-2020 The Thingsboard Authors | ||
3 | +-- | ||
4 | +-- Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +-- you may not use this file except in compliance with the License. | ||
6 | +-- You may obtain a copy of the License at | ||
7 | +-- | ||
8 | +-- http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +-- | ||
10 | +-- Unless required by applicable law or agreed to in writing, software | ||
11 | +-- distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +-- See the License for the specific language governing permissions and | ||
14 | +-- limitations under the License. | ||
15 | +-- | ||
16 | + | ||
17 | +-- call create_new_ts_kv_table(); | ||
18 | + | ||
19 | +CREATE OR REPLACE PROCEDURE create_new_ts_kv_table() LANGUAGE plpgsql AS $$ | ||
20 | + | ||
21 | +BEGIN | ||
22 | + ALTER TABLE tenant_ts_kv | ||
23 | + RENAME TO tenant_ts_kv_old; | ||
24 | + CREATE TABLE IF NOT EXISTS ts_kv | ||
25 | + ( | ||
26 | + LIKE tenant_ts_kv_old | ||
27 | + ); | ||
28 | + ALTER TABLE ts_kv ALTER COLUMN entity_id TYPE uuid USING entity_id::uuid; | ||
29 | + ALTER TABLE ts_kv ALTER COLUMN key TYPE integer USING key::integer; | ||
30 | + ALTER INDEX ts_kv_pkey RENAME TO tenant_ts_kv_pkey_old; | ||
31 | + ALTER INDEX idx_tenant_ts_kv RENAME TO idx_tenant_ts_kv_old; | ||
32 | + ALTER INDEX tenant_ts_kv_ts_idx RENAME TO tenant_ts_kv_ts_idx_old; | ||
33 | + ALTER TABLE ts_kv ADD CONSTRAINT ts_kv_pkey PRIMARY KEY(entity_id, key, ts); | ||
34 | +-- CREATE INDEX IF NOT EXISTS ts_kv_ts_idx ON ts_kv(ts DESC); | ||
35 | + ALTER TABLE ts_kv DROP COLUMN IF EXISTS tenant_id; | ||
36 | +END; | ||
37 | +$$; | ||
38 | + | ||
39 | + | ||
40 | +-- call create_ts_kv_latest_table(); | ||
41 | + | ||
42 | +CREATE OR REPLACE PROCEDURE create_ts_kv_latest_table() LANGUAGE plpgsql AS $$ | ||
43 | + | ||
44 | +BEGIN | ||
45 | + CREATE TABLE IF NOT EXISTS ts_kv_latest | ||
46 | + ( | ||
47 | + entity_id uuid NOT NULL, | ||
48 | + key int NOT NULL, | ||
49 | + ts bigint NOT NULL, | ||
50 | + bool_v boolean, | ||
51 | + str_v varchar(10000000), | ||
52 | + long_v bigint, | ||
53 | + dbl_v double precision, | ||
54 | + CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key) | ||
55 | + ); | ||
56 | +END; | ||
57 | +$$; | ||
58 | + | ||
59 | + | ||
60 | +-- call create_ts_kv_dictionary_table(); | ||
61 | + | ||
62 | +CREATE OR REPLACE PROCEDURE create_ts_kv_dictionary_table() LANGUAGE plpgsql AS $$ | ||
63 | + | ||
64 | +BEGIN | ||
65 | + CREATE TABLE IF NOT EXISTS ts_kv_dictionary | ||
66 | + ( | ||
67 | + key varchar(255) NOT NULL, | ||
68 | + key_id serial UNIQUE, | ||
69 | + CONSTRAINT ts_key_id_pkey PRIMARY KEY (key) | ||
70 | + ); | ||
71 | +END; | ||
72 | +$$; | ||
73 | + | ||
74 | +-- call insert_into_dictionary(); | ||
75 | + | ||
76 | +CREATE OR REPLACE PROCEDURE insert_into_dictionary() LANGUAGE plpgsql AS $$ | ||
77 | + | ||
78 | +DECLARE | ||
79 | + insert_record RECORD; | ||
80 | + key_cursor CURSOR FOR SELECT DISTINCT key | ||
81 | + FROM tenant_ts_kv_old | ||
82 | + ORDER BY key; | ||
83 | +BEGIN | ||
84 | + OPEN key_cursor; | ||
85 | + LOOP | ||
86 | + FETCH key_cursor INTO insert_record; | ||
87 | + EXIT WHEN NOT FOUND; | ||
88 | + IF NOT EXISTS(SELECT key FROM ts_kv_dictionary WHERE key = insert_record.key) THEN | ||
89 | + INSERT INTO ts_kv_dictionary(key) VALUES (insert_record.key); | ||
90 | + RAISE NOTICE 'Key: % has been inserted into the dictionary!',insert_record.key; | ||
91 | + ELSE | ||
92 | + RAISE NOTICE 'Key: % already exists in the dictionary!',insert_record.key; | ||
93 | + END IF; | ||
94 | + END LOOP; | ||
95 | + CLOSE key_cursor; | ||
96 | +END; | ||
97 | +$$; | ||
98 | + | ||
99 | +-- call insert_into_ts_kv(); | ||
100 | + | ||
101 | +CREATE OR REPLACE PROCEDURE insert_into_ts_kv() LANGUAGE plpgsql AS $$ | ||
102 | + | ||
103 | +DECLARE | ||
104 | + insert_size CONSTANT integer := 10000; | ||
105 | + insert_counter integer DEFAULT 0; | ||
106 | + insert_record RECORD; | ||
107 | + insert_cursor CURSOR FOR SELECT CONCAT(entity_id_uuid_first_part, '-', entity_id_uuid_second_part, '-1', entity_id_uuid_third_part, '-', entity_id_uuid_fourth_part, '-', entity_id_uuid_fifth_part)::uuid AS entity_id, | ||
108 | + new_ts_kv_records.key AS key, | ||
109 | + new_ts_kv_records.ts AS ts, | ||
110 | + new_ts_kv_records.bool_v AS bool_v, | ||
111 | + new_ts_kv_records.str_v AS str_v, | ||
112 | + new_ts_kv_records.long_v AS long_v, | ||
113 | + new_ts_kv_records.dbl_v AS dbl_v | ||
114 | + FROM (SELECT SUBSTRING(entity_id, 8, 8) AS entity_id_uuid_first_part, | ||
115 | + SUBSTRING(entity_id, 4, 4) AS entity_id_uuid_second_part, | ||
116 | + SUBSTRING(entity_id, 1, 3) AS entity_id_uuid_third_part, | ||
117 | + SUBSTRING(entity_id, 16, 4) AS entity_id_uuid_fourth_part, | ||
118 | + SUBSTRING(entity_id, 20) AS entity_id_uuid_fifth_part, | ||
119 | + key_id AS key, | ||
120 | + ts, | ||
121 | + bool_v, | ||
122 | + str_v, | ||
123 | + long_v, | ||
124 | + dbl_v | ||
125 | + FROM tenant_ts_kv_old | ||
126 | + INNER JOIN ts_kv_dictionary ON (tenant_ts_kv_old.key = ts_kv_dictionary.key)) AS new_ts_kv_records; | ||
127 | +BEGIN | ||
128 | + OPEN insert_cursor; | ||
129 | + LOOP | ||
130 | + insert_counter := insert_counter + 1; | ||
131 | + FETCH insert_cursor INTO insert_record; | ||
132 | + IF NOT FOUND THEN | ||
133 | + RAISE NOTICE '% records have been inserted into the new ts_kv table!',insert_counter - 1; | ||
134 | + EXIT; | ||
135 | + END IF; | ||
136 | + INSERT INTO ts_kv(entity_id, key, ts, bool_v, str_v, long_v, dbl_v) | ||
137 | + VALUES (insert_record.entity_id, insert_record.key, insert_record.ts, insert_record.bool_v, insert_record.str_v, | ||
138 | + insert_record.long_v, insert_record.dbl_v); | ||
139 | + IF MOD(insert_counter, insert_size) = 0 THEN | ||
140 | + RAISE NOTICE '% records have been inserted into the new ts_kv table!',insert_counter; | ||
141 | + END IF; | ||
142 | + END LOOP; | ||
143 | + CLOSE insert_cursor; | ||
144 | +END; | ||
145 | +$$; | ||
146 | + | ||
147 | +-- call insert_into_ts_kv_latest(); | ||
148 | + | ||
149 | +CREATE OR REPLACE PROCEDURE insert_into_ts_kv_latest() LANGUAGE plpgsql AS $$ | ||
150 | + | ||
151 | +DECLARE | ||
152 | + insert_size CONSTANT integer := 10000; | ||
153 | + insert_counter integer DEFAULT 0; | ||
154 | + latest_record RECORD; | ||
155 | + insert_record RECORD; | ||
156 | + insert_cursor CURSOR FOR SELECT | ||
157 | + latest_records.key AS key, | ||
158 | + latest_records.entity_id AS entity_id, | ||
159 | + latest_records.ts AS ts | ||
160 | + FROM (SELECT DISTINCT key AS key, entity_id AS entity_id, MAX(ts) AS ts FROM ts_kv GROUP BY key, entity_id) AS latest_records; | ||
161 | +BEGIN | ||
162 | + OPEN insert_cursor; | ||
163 | + LOOP | ||
164 | + insert_counter := insert_counter + 1; | ||
165 | + FETCH insert_cursor INTO latest_record; | ||
166 | + IF NOT FOUND THEN | ||
167 | + RAISE NOTICE '% records have been inserted into the ts_kv_latest table!',insert_counter - 1; | ||
168 | + EXIT; | ||
169 | + END IF; | ||
170 | + SELECT entity_id AS entity_id, key AS key, ts AS ts, bool_v AS bool_v, str_v AS str_v, long_v AS long_v, dbl_v AS dbl_v INTO insert_record FROM ts_kv WHERE entity_id = latest_record.entity_id AND key = latest_record.key AND ts = latest_record.ts; | ||
171 | + INSERT INTO ts_kv_latest(entity_id, key, ts, bool_v, str_v, long_v, dbl_v) | ||
172 | + VALUES (insert_record.entity_id, insert_record.key, insert_record.ts, insert_record.bool_v, insert_record.str_v, insert_record.long_v, insert_record.dbl_v); | ||
173 | + IF MOD(insert_counter, insert_size) = 0 THEN | ||
174 | + RAISE NOTICE '% records have been inserted into the ts_kv_latest table!',insert_counter; | ||
175 | + END IF; | ||
176 | + END LOOP; | ||
177 | + CLOSE insert_cursor; | ||
178 | +END; | ||
179 | +$$; |
1 | +-- | ||
2 | +-- Copyright © 2016-2020 The Thingsboard Authors | ||
3 | +-- | ||
4 | +-- Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +-- you may not use this file except in compliance with the License. | ||
6 | +-- You may obtain a copy of the License at | ||
7 | +-- | ||
8 | +-- http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +-- | ||
10 | +-- Unless required by applicable law or agreed to in writing, software | ||
11 | +-- distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +-- See the License for the specific language governing permissions and | ||
14 | +-- limitations under the License. | ||
15 | +-- | ||
16 | + | ||
17 | +CREATE OR REPLACE FUNCTION to_uuid(IN entity_id varchar, OUT uuid_id uuid) AS | ||
18 | +$$ | ||
19 | +BEGIN | ||
20 | + uuid_id := substring(entity_id, 8, 8) || '-' || substring(entity_id, 4, 4) || '-1' || substring(entity_id, 1, 3) || | ||
21 | + '-' || substring(entity_id, 16, 4) || '-' || substring(entity_id, 20, 12); | ||
22 | +END; | ||
23 | +$$ LANGUAGE plpgsql; | ||
24 | + | ||
25 | +CREATE OR REPLACE FUNCTION delete_device_records_from_ts_kv(tenant_id varchar, customer_id varchar, ttl bigint, | ||
26 | + OUT deleted bigint) AS | ||
27 | +$$ | ||
28 | +BEGIN | ||
29 | + EXECUTE format( | ||
30 | + 'WITH deleted AS (DELETE FROM ts_kv WHERE entity_id IN (SELECT to_uuid(device.id) as entity_id FROM device WHERE tenant_id = %L and customer_id = %L) AND ts < %L::bigint RETURNING *) SELECT count(*) FROM deleted', | ||
31 | + tenant_id, customer_id, ttl) into deleted; | ||
32 | +END; | ||
33 | +$$ LANGUAGE plpgsql; | ||
34 | + | ||
35 | +CREATE OR REPLACE FUNCTION delete_asset_records_from_ts_kv(tenant_id varchar, customer_id varchar, ttl bigint, | ||
36 | + OUT deleted bigint) AS | ||
37 | +$$ | ||
38 | +BEGIN | ||
39 | + EXECUTE format( | ||
40 | + 'WITH deleted AS (DELETE FROM ts_kv WHERE entity_id IN (SELECT to_uuid(asset.id) as entity_id FROM asset WHERE tenant_id = %L and customer_id = %L) AND ts < %L::bigint RETURNING *) SELECT count(*) FROM deleted', | ||
41 | + tenant_id, customer_id, ttl) into deleted; | ||
42 | +END; | ||
43 | +$$ LANGUAGE plpgsql; | ||
44 | + | ||
45 | +CREATE OR REPLACE FUNCTION delete_customer_records_from_ts_kv(tenant_id varchar, customer_id varchar, ttl bigint, | ||
46 | + OUT deleted bigint) AS | ||
47 | +$$ | ||
48 | +BEGIN | ||
49 | + EXECUTE format( | ||
50 | + 'WITH deleted AS (DELETE FROM ts_kv WHERE entity_id IN (SELECT to_uuid(customer.id) as entity_id FROM customer WHERE tenant_id = %L and id = %L) AND ts < %L::bigint RETURNING *) SELECT count(*) FROM deleted', | ||
51 | + tenant_id, customer_id, ttl) into deleted; | ||
52 | +END; | ||
53 | +$$ LANGUAGE plpgsql; | ||
54 | + | ||
55 | +CREATE OR REPLACE PROCEDURE cleanup_timeseries_by_ttl(IN null_uuid varchar(31), | ||
56 | + IN system_ttl bigint, INOUT deleted bigint) | ||
57 | + LANGUAGE plpgsql AS | ||
58 | +$$ | ||
59 | +DECLARE | ||
60 | + tenant_cursor CURSOR FOR select tenant.id as tenant_id | ||
61 | + from tenant; | ||
62 | + tenant_id_record varchar; | ||
63 | + customer_id_record varchar; | ||
64 | + tenant_ttl bigint; | ||
65 | + customer_ttl bigint; | ||
66 | + deleted_for_entities bigint; | ||
67 | + tenant_ttl_ts bigint; | ||
68 | + customer_ttl_ts bigint; | ||
69 | +BEGIN | ||
70 | + OPEN tenant_cursor; | ||
71 | + FETCH tenant_cursor INTO tenant_id_record; | ||
72 | + WHILE FOUND | ||
73 | + LOOP | ||
74 | + EXECUTE format( | ||
75 | + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = %L', | ||
76 | + tenant_id_record, 'TTL') INTO tenant_ttl; | ||
77 | + if tenant_ttl IS NULL THEN | ||
78 | + tenant_ttl := system_ttl; | ||
79 | + END IF; | ||
80 | + IF tenant_ttl > 0 THEN | ||
81 | + tenant_ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - tenant_ttl::bigint * 1000)::bigint; | ||
82 | + deleted_for_entities := delete_device_records_from_ts_kv(tenant_id_record, null_uuid, tenant_ttl_ts); | ||
83 | + deleted := deleted + deleted_for_entities; | ||
84 | + RAISE NOTICE '% telemetry removed for devices where tenant_id = %', deleted_for_entities, tenant_id_record; | ||
85 | + deleted_for_entities := delete_asset_records_from_ts_kv(tenant_id_record, null_uuid, tenant_ttl_ts); | ||
86 | + deleted := deleted + deleted_for_entities; | ||
87 | + RAISE NOTICE '% telemetry removed for assets where tenant_id = %', deleted_for_entities, tenant_id_record; | ||
88 | + END IF; | ||
89 | + FOR customer_id_record IN | ||
90 | + SELECT customer.id AS customer_id FROM customer WHERE customer.tenant_id = tenant_id_record | ||
91 | + LOOP | ||
92 | + EXECUTE format( | ||
93 | + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = %L', | ||
94 | + customer_id_record, 'TTL') INTO customer_ttl; | ||
95 | + IF customer_ttl IS NULL THEN | ||
96 | + customer_ttl_ts := tenant_ttl_ts; | ||
97 | + ELSE | ||
98 | + IF customer_ttl > 0 THEN | ||
99 | + customer_ttl_ts := | ||
100 | + (EXTRACT(EPOCH FROM current_timestamp) * 1000 - | ||
101 | + customer_ttl::bigint * 1000)::bigint; | ||
102 | + END IF; | ||
103 | + END IF; | ||
104 | + IF customer_ttl_ts IS NOT NULL AND customer_ttl_ts > 0 THEN | ||
105 | + deleted_for_entities := | ||
106 | + delete_customer_records_from_ts_kv(tenant_id_record, customer_id_record, | ||
107 | + customer_ttl_ts); | ||
108 | + deleted := deleted + deleted_for_entities; | ||
109 | + RAISE NOTICE '% telemetry removed for customer with id = % where tenant_id = %', deleted_for_entities, customer_id_record, tenant_id_record; | ||
110 | + deleted_for_entities := | ||
111 | + delete_device_records_from_ts_kv(tenant_id_record, customer_id_record, | ||
112 | + customer_ttl_ts); | ||
113 | + deleted := deleted + deleted_for_entities; | ||
114 | + RAISE NOTICE '% telemetry removed for devices where tenant_id = % and customer_id = %', deleted_for_entities, tenant_id_record, customer_id_record; | ||
115 | + deleted_for_entities := delete_asset_records_from_ts_kv(tenant_id_record, | ||
116 | + customer_id_record, | ||
117 | + customer_ttl_ts); | ||
118 | + deleted := deleted + deleted_for_entities; | ||
119 | + RAISE NOTICE '% telemetry removed for assets where tenant_id = % and customer_id = %', deleted_for_entities, tenant_id_record, customer_id_record; | ||
120 | + END IF; | ||
121 | + END LOOP; | ||
122 | + FETCH tenant_cursor INTO tenant_id_record; | ||
123 | + END LOOP; | ||
124 | +END | ||
125 | +$$; | ||
126 | + | ||
127 | +CREATE OR REPLACE PROCEDURE cleanup_events_by_ttl(IN ttl bigint, IN debug_ttl bigint, INOUT deleted bigint) | ||
128 | + LANGUAGE plpgsql AS | ||
129 | +$$ | ||
130 | +DECLARE | ||
131 | + ttl_ts bigint; | ||
132 | + debug_ttl_ts bigint; | ||
133 | + ttl_deleted_count bigint DEFAULT 0; | ||
134 | + debug_ttl_deleted_count bigint DEFAULT 0; | ||
135 | +BEGIN | ||
136 | + IF ttl > 0 THEN | ||
137 | + ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - ttl::bigint * 1000)::bigint; | ||
138 | + EXECUTE format( | ||
139 | + 'WITH deleted AS (DELETE FROM event WHERE ts < %L::bigint AND (event_type != %L::varchar AND event_type != %L::varchar) RETURNING *) SELECT count(*) FROM deleted', ttl_ts, 'DEBUG_RULE_NODE', 'DEBUG_RULE_CHAIN') into ttl_deleted_count; | ||
140 | + END IF; | ||
141 | + IF debug_ttl > 0 THEN | ||
142 | + debug_ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - debug_ttl::bigint * 1000)::bigint; | ||
143 | + EXECUTE format( | ||
144 | + 'WITH deleted AS (DELETE FROM event WHERE ts < %L::bigint AND (event_type = %L::varchar OR event_type = %L::varchar) RETURNING *) SELECT count(*) FROM deleted', debug_ttl_ts, 'DEBUG_RULE_NODE', 'DEBUG_RULE_CHAIN') into debug_ttl_deleted_count; | ||
145 | + END IF; | ||
146 | + RAISE NOTICE 'Events removed by ttl: %', ttl_deleted_count; | ||
147 | + RAISE NOTICE 'Debug Events removed by ttl: %', debug_ttl_deleted_count; | ||
148 | + deleted := ttl_deleted_count + debug_ttl_deleted_count; | ||
149 | +END | ||
150 | +$$; |
@@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; | @@ -24,6 +24,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; | ||
24 | import com.google.common.util.concurrent.FutureCallback; | 24 | import com.google.common.util.concurrent.FutureCallback; |
25 | import com.google.common.util.concurrent.Futures; | 25 | import com.google.common.util.concurrent.Futures; |
26 | import com.google.common.util.concurrent.ListenableFuture; | 26 | import com.google.common.util.concurrent.ListenableFuture; |
27 | +import com.google.common.util.concurrent.MoreExecutors; | ||
27 | import com.typesafe.config.Config; | 28 | import com.typesafe.config.Config; |
28 | import com.typesafe.config.ConfigFactory; | 29 | import com.typesafe.config.ConfigFactory; |
29 | import lombok.Getter; | 30 | import lombok.Getter; |
@@ -36,7 +37,6 @@ import org.springframework.data.redis.core.RedisTemplate; | @@ -36,7 +37,6 @@ import org.springframework.data.redis.core.RedisTemplate; | ||
36 | import org.springframework.scheduling.annotation.Scheduled; | 37 | import org.springframework.scheduling.annotation.Scheduled; |
37 | import org.springframework.stereotype.Component; | 38 | import org.springframework.stereotype.Component; |
38 | import org.thingsboard.rule.engine.api.MailService; | 39 | import org.thingsboard.rule.engine.api.MailService; |
39 | -import org.thingsboard.rule.engine.api.RuleChainTransactionService; | ||
40 | import org.thingsboard.server.actors.service.ActorService; | 40 | import org.thingsboard.server.actors.service.ActorService; |
41 | import org.thingsboard.server.actors.tenant.DebugTbRateLimits; | 41 | import org.thingsboard.server.actors.tenant.DebugTbRateLimits; |
42 | import org.thingsboard.server.common.data.DataConstants; | 42 | import org.thingsboard.server.common.data.DataConstants; |
@@ -44,10 +44,11 @@ import org.thingsboard.server.common.data.Event; | @@ -44,10 +44,11 @@ import org.thingsboard.server.common.data.Event; | ||
44 | import org.thingsboard.server.common.data.id.EntityId; | 44 | import org.thingsboard.server.common.data.id.EntityId; |
45 | import org.thingsboard.server.common.data.id.TenantId; | 45 | import org.thingsboard.server.common.data.id.TenantId; |
46 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | 46 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; |
47 | +import org.thingsboard.server.common.msg.TbActorMsg; | ||
47 | import org.thingsboard.server.common.msg.TbMsg; | 48 | import org.thingsboard.server.common.msg.TbMsg; |
48 | -import org.thingsboard.server.common.msg.cluster.ServerAddress; | 49 | +import org.thingsboard.server.common.msg.queue.ServiceType; |
50 | +import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; | ||
49 | import org.thingsboard.server.common.msg.tools.TbRateLimits; | 51 | import org.thingsboard.server.common.msg.tools.TbRateLimits; |
50 | -import org.thingsboard.server.common.transport.auth.DeviceAuthService; | ||
51 | import org.thingsboard.server.dao.alarm.AlarmService; | 52 | import org.thingsboard.server.dao.alarm.AlarmService; |
52 | import org.thingsboard.server.dao.asset.AssetService; | 53 | import org.thingsboard.server.dao.asset.AssetService; |
53 | import org.thingsboard.server.dao.attributes.AttributesService; | 54 | import org.thingsboard.server.dao.attributes.AttributesService; |
@@ -64,24 +65,23 @@ import org.thingsboard.server.dao.rule.RuleChainService; | @@ -64,24 +65,23 @@ import org.thingsboard.server.dao.rule.RuleChainService; | ||
64 | import org.thingsboard.server.dao.tenant.TenantService; | 65 | import org.thingsboard.server.dao.tenant.TenantService; |
65 | import org.thingsboard.server.dao.timeseries.TimeseriesService; | 66 | import org.thingsboard.server.dao.timeseries.TimeseriesService; |
66 | import org.thingsboard.server.dao.user.UserService; | 67 | import org.thingsboard.server.dao.user.UserService; |
67 | -import org.thingsboard.server.kafka.TbNodeIdProvider; | ||
68 | -import org.thingsboard.server.service.cluster.discovery.DiscoveryService; | ||
69 | -import org.thingsboard.server.service.cluster.routing.ClusterRoutingService; | ||
70 | -import org.thingsboard.server.service.cluster.rpc.ClusterRpcService; | 68 | +import org.thingsboard.server.queue.discovery.PartitionService; |
69 | +import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; | ||
71 | import org.thingsboard.server.service.component.ComponentDiscoveryService; | 70 | import org.thingsboard.server.service.component.ComponentDiscoveryService; |
72 | import org.thingsboard.server.service.encoding.DataDecodingEncodingService; | 71 | import org.thingsboard.server.service.encoding.DataDecodingEncodingService; |
73 | -import org.thingsboard.server.service.executors.ClusterRpcCallbackExecutorService; | ||
74 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; | 72 | import org.thingsboard.server.service.executors.DbCallbackExecutorService; |
75 | import org.thingsboard.server.service.executors.ExternalCallExecutorService; | 73 | import org.thingsboard.server.service.executors.ExternalCallExecutorService; |
76 | import org.thingsboard.server.service.executors.SharedEventLoopGroupService; | 74 | import org.thingsboard.server.service.executors.SharedEventLoopGroupService; |
77 | import org.thingsboard.server.service.mail.MailExecutorService; | 75 | import org.thingsboard.server.service.mail.MailExecutorService; |
78 | -import org.thingsboard.server.service.rpc.DeviceRpcService; | 76 | +import org.thingsboard.server.service.queue.TbClusterService; |
77 | +import org.thingsboard.server.service.rpc.TbCoreDeviceRpcService; | ||
78 | +import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; | ||
79 | import org.thingsboard.server.service.script.JsExecutorService; | 79 | import org.thingsboard.server.service.script.JsExecutorService; |
80 | import org.thingsboard.server.service.script.JsInvokeService; | 80 | import org.thingsboard.server.service.script.JsInvokeService; |
81 | import org.thingsboard.server.service.session.DeviceSessionCacheService; | 81 | import org.thingsboard.server.service.session.DeviceSessionCacheService; |
82 | import org.thingsboard.server.service.state.DeviceStateService; | 82 | import org.thingsboard.server.service.state.DeviceStateService; |
83 | import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; | 83 | import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; |
84 | -import org.thingsboard.server.service.transport.RuleEngineTransportService; | 84 | +import org.thingsboard.server.service.transport.TbCoreToTransportService; |
85 | 85 | ||
86 | import javax.annotation.Nullable; | 86 | import javax.annotation.Nullable; |
87 | import java.io.IOException; | 87 | import java.io.IOException; |
@@ -105,13 +105,14 @@ public class ActorSystemContext { | @@ -105,13 +105,14 @@ public class ActorSystemContext { | ||
105 | return debugPerTenantLimits; | 105 | return debugPerTenantLimits; |
106 | } | 106 | } |
107 | 107 | ||
108 | + @Autowired | ||
108 | @Getter | 109 | @Getter |
109 | @Setter | 110 | @Setter |
110 | - private ActorService actorService; | 111 | + private TbServiceInfoProvider serviceInfoProvider; |
111 | 112 | ||
112 | - @Autowired | ||
113 | @Getter | 113 | @Getter |
114 | - private DiscoveryService discoveryService; | 114 | + @Setter |
115 | + private ActorService actorService; | ||
115 | 116 | ||
116 | @Autowired | 117 | @Autowired |
117 | @Getter | 118 | @Getter |
@@ -120,22 +121,10 @@ public class ActorSystemContext { | @@ -120,22 +121,10 @@ public class ActorSystemContext { | ||
120 | 121 | ||
121 | @Autowired | 122 | @Autowired |
122 | @Getter | 123 | @Getter |
123 | - private ClusterRoutingService routingService; | ||
124 | - | ||
125 | - @Autowired | ||
126 | - @Getter | ||
127 | - private ClusterRpcService rpcService; | ||
128 | - | ||
129 | - @Autowired | ||
130 | - @Getter | ||
131 | private DataDecodingEncodingService encodingService; | 124 | private DataDecodingEncodingService encodingService; |
132 | 125 | ||
133 | @Autowired | 126 | @Autowired |
134 | @Getter | 127 | @Getter |
135 | - private DeviceAuthService deviceAuthService; | ||
136 | - | ||
137 | - @Autowired | ||
138 | - @Getter | ||
139 | private DeviceService deviceService; | 128 | private DeviceService deviceService; |
140 | 129 | ||
141 | @Autowired | 130 | @Autowired |
@@ -163,6 +152,13 @@ public class ActorSystemContext { | @@ -163,6 +152,13 @@ public class ActorSystemContext { | ||
163 | private RuleChainService ruleChainService; | 152 | private RuleChainService ruleChainService; |
164 | 153 | ||
165 | @Autowired | 154 | @Autowired |
155 | + private PartitionService partitionService; | ||
156 | + | ||
157 | + @Autowired | ||
158 | + @Getter | ||
159 | + private TbClusterService clusterService; | ||
160 | + | ||
161 | + @Autowired | ||
166 | @Getter | 162 | @Getter |
167 | private TimeseriesService tsService; | 163 | private TimeseriesService tsService; |
168 | 164 | ||
@@ -196,10 +192,6 @@ public class ActorSystemContext { | @@ -196,10 +192,6 @@ public class ActorSystemContext { | ||
196 | 192 | ||
197 | @Autowired | 193 | @Autowired |
198 | @Getter | 194 | @Getter |
199 | - private DeviceRpcService deviceRpcService; | ||
200 | - | ||
201 | - @Autowired | ||
202 | - @Getter | ||
203 | private JsInvokeService jsSandbox; | 195 | private JsInvokeService jsSandbox; |
204 | 196 | ||
205 | @Autowired | 197 | @Autowired |
@@ -212,10 +204,6 @@ public class ActorSystemContext { | @@ -212,10 +204,6 @@ public class ActorSystemContext { | ||
212 | 204 | ||
213 | @Autowired | 205 | @Autowired |
214 | @Getter | 206 | @Getter |
215 | - private ClusterRpcCallbackExecutorService clusterRpcCallbackExecutor; | ||
216 | - | ||
217 | - @Autowired | ||
218 | - @Getter | ||
219 | private DbCallbackExecutorService dbCallbackExecutor; | 207 | private DbCallbackExecutorService dbCallbackExecutor; |
220 | 208 | ||
221 | @Autowired | 209 | @Autowired |
@@ -230,27 +218,34 @@ public class ActorSystemContext { | @@ -230,27 +218,34 @@ public class ActorSystemContext { | ||
230 | @Getter | 218 | @Getter |
231 | private MailService mailService; | 219 | private MailService mailService; |
232 | 220 | ||
233 | - @Autowired | 221 | + //TODO: separate context for TbCore and TbRuleEngine |
222 | + @Autowired(required = false) | ||
234 | @Getter | 223 | @Getter |
235 | private DeviceStateService deviceStateService; | 224 | private DeviceStateService deviceStateService; |
236 | 225 | ||
237 | - @Autowired | 226 | + @Autowired(required = false) |
238 | @Getter | 227 | @Getter |
239 | private DeviceSessionCacheService deviceSessionCacheService; | 228 | private DeviceSessionCacheService deviceSessionCacheService; |
240 | 229 | ||
241 | - @Lazy | ||
242 | - @Autowired | 230 | + @Autowired(required = false) |
243 | @Getter | 231 | @Getter |
244 | - private RuleEngineTransportService ruleEngineTransportService; | 232 | + private TbCoreToTransportService tbCoreToTransportService; |
245 | 233 | ||
234 | + /** | ||
235 | + * The following Service will be null if we operate in tb-core mode | ||
236 | + */ | ||
246 | @Lazy | 237 | @Lazy |
247 | - @Autowired | 238 | + @Autowired(required = false) |
248 | @Getter | 239 | @Getter |
249 | - private RuleChainTransactionService ruleChainTransactionService; | 240 | + private TbRuleEngineDeviceRpcService tbRuleEngineDeviceRpcService; |
250 | 241 | ||
251 | - @Value("${cluster.partition_id}") | 242 | + /** |
243 | + * The following Service will be null if we operate in tb-rule-engine mode | ||
244 | + */ | ||
245 | + @Lazy | ||
246 | + @Autowired(required = false) | ||
252 | @Getter | 247 | @Getter |
253 | - private long queuePartitionId; | 248 | + private TbCoreDeviceRpcService tbCoreDeviceRpcService; |
254 | 249 | ||
255 | @Value("${actors.session.max_concurrent_sessions_per_device:1}") | 250 | @Value("${actors.session.max_concurrent_sessions_per_device:1}") |
256 | @Getter | 251 | @Getter |
@@ -268,10 +263,6 @@ public class ActorSystemContext { | @@ -268,10 +263,6 @@ public class ActorSystemContext { | ||
268 | @Getter | 263 | @Getter |
269 | private long queuePersistenceTimeout; | 264 | private long queuePersistenceTimeout; |
270 | 265 | ||
271 | - @Value("${actors.client_side_rpc.timeout}") | ||
272 | - @Getter | ||
273 | - private long clientSideRpcTimeout; | ||
274 | - | ||
275 | @Value("${actors.rule.chain.error_persist_frequency}") | 266 | @Value("${actors.rule.chain.error_persist_frequency}") |
276 | @Getter | 267 | @Getter |
277 | private long ruleChainErrorPersistFrequency; | 268 | private long ruleChainErrorPersistFrequency; |
@@ -295,7 +286,7 @@ public class ActorSystemContext { | @@ -295,7 +286,7 @@ public class ActorSystemContext { | ||
295 | @Getter | 286 | @Getter |
296 | private final AtomicInteger jsInvokeFailuresCount = new AtomicInteger(0); | 287 | private final AtomicInteger jsInvokeFailuresCount = new AtomicInteger(0); |
297 | 288 | ||
298 | - @Scheduled(fixedDelayString = "${js.remote.stats.print_interval_ms}") | 289 | + @Scheduled(fixedDelayString = "${actors.statistics.js_print_interval_ms}") |
299 | public void printStats() { | 290 | public void printStats() { |
300 | if (statisticsEnabled) { | 291 | if (statisticsEnabled) { |
301 | if (jsInvokeRequestsCount.get() > 0 || jsInvokeResponsesCount.get() > 0 || jsInvokeFailuresCount.get() > 0) { | 292 | if (jsInvokeRequestsCount.get() > 0 || jsInvokeResponsesCount.get() > 0 || jsInvokeFailuresCount.get() > 0) { |
@@ -333,11 +324,6 @@ public class ActorSystemContext { | @@ -333,11 +324,6 @@ public class ActorSystemContext { | ||
333 | @Setter | 324 | @Setter |
334 | private ActorSystem actorSystem; | 325 | private ActorSystem actorSystem; |
335 | 326 | ||
336 | - @Autowired | ||
337 | - @Getter | ||
338 | - private TbNodeIdProvider nodeIdProvider; | ||
339 | - | ||
340 | - @Getter | ||
341 | @Setter | 327 | @Setter |
342 | private ActorRef appActor; | 328 | private ActorRef appActor; |
343 | 329 | ||
@@ -364,6 +350,8 @@ public class ActorSystemContext { | @@ -364,6 +350,8 @@ public class ActorSystemContext { | ||
364 | config = ConfigFactory.parseResources(AKKA_CONF_FILE_NAME).withFallback(ConfigFactory.load()); | 350 | config = ConfigFactory.parseResources(AKKA_CONF_FILE_NAME).withFallback(ConfigFactory.load()); |
365 | } | 351 | } |
366 | 352 | ||
353 | + | ||
354 | + | ||
367 | public Scheduler getScheduler() { | 355 | public Scheduler getScheduler() { |
368 | return actorSystem.scheduler(); | 356 | return actorSystem.scheduler(); |
369 | } | 357 | } |
@@ -373,7 +361,7 @@ public class ActorSystemContext { | @@ -373,7 +361,7 @@ public class ActorSystemContext { | ||
373 | event.setTenantId(tenantId); | 361 | event.setTenantId(tenantId); |
374 | event.setEntityId(entityId); | 362 | event.setEntityId(entityId); |
375 | event.setType(DataConstants.ERROR); | 363 | event.setType(DataConstants.ERROR); |
376 | - event.setBody(toBodyJson(discoveryService.getCurrentServer().getServerAddress(), method, toString(e))); | 364 | + event.setBody(toBodyJson(serviceInfoProvider.getServiceInfo().getServiceId(), method, toString(e))); |
377 | persistEvent(event); | 365 | persistEvent(event); |
378 | } | 366 | } |
379 | 367 | ||
@@ -382,7 +370,7 @@ public class ActorSystemContext { | @@ -382,7 +370,7 @@ public class ActorSystemContext { | ||
382 | event.setTenantId(tenantId); | 370 | event.setTenantId(tenantId); |
383 | event.setEntityId(entityId); | 371 | event.setEntityId(entityId); |
384 | event.setType(DataConstants.LC_EVENT); | 372 | event.setType(DataConstants.LC_EVENT); |
385 | - event.setBody(toBodyJson(discoveryService.getCurrentServer().getServerAddress(), lcEvent, Optional.ofNullable(e))); | 373 | + event.setBody(toBodyJson(serviceInfoProvider.getServiceInfo().getServiceId(), lcEvent, Optional.ofNullable(e))); |
386 | persistEvent(event); | 374 | persistEvent(event); |
387 | } | 375 | } |
388 | 376 | ||
@@ -396,8 +384,8 @@ public class ActorSystemContext { | @@ -396,8 +384,8 @@ public class ActorSystemContext { | ||
396 | return sw.toString(); | 384 | return sw.toString(); |
397 | } | 385 | } |
398 | 386 | ||
399 | - private JsonNode toBodyJson(ServerAddress server, ComponentLifecycleEvent event, Optional<Exception> e) { | ||
400 | - ObjectNode node = mapper.createObjectNode().put("server", server.toString()).put("event", event.name()); | 387 | + private JsonNode toBodyJson(String serviceId, ComponentLifecycleEvent event, Optional<Exception> e) { |
388 | + ObjectNode node = mapper.createObjectNode().put("server", serviceId).put("event", event.name()); | ||
401 | if (e.isPresent()) { | 389 | if (e.isPresent()) { |
402 | node = node.put("success", false); | 390 | node = node.put("success", false); |
403 | node = node.put("error", toString(e.get())); | 391 | node = node.put("error", toString(e.get())); |
@@ -407,12 +395,21 @@ public class ActorSystemContext { | @@ -407,12 +395,21 @@ public class ActorSystemContext { | ||
407 | return node; | 395 | return node; |
408 | } | 396 | } |
409 | 397 | ||
410 | - private JsonNode toBodyJson(ServerAddress server, String method, String body) { | ||
411 | - return mapper.createObjectNode().put("server", server.toString()).put("method", method).put("error", body); | 398 | + private JsonNode toBodyJson(String serviceId, String method, String body) { |
399 | + return mapper.createObjectNode().put("server", serviceId).put("method", method).put("error", body); | ||
412 | } | 400 | } |
413 | 401 | ||
414 | - public String getServerAddress() { | ||
415 | - return discoveryService.getCurrentServer().getServerAddress().toString(); | 402 | + public TopicPartitionInfo resolve(ServiceType serviceType, TenantId tenantId, EntityId entityId) { |
403 | + return partitionService.resolve(serviceType, tenantId, entityId); | ||
404 | + } | ||
405 | + | ||
406 | + public TopicPartitionInfo resolve(ServiceType serviceType, String queueName, TenantId tenantId, EntityId entityId) { | ||
407 | + return partitionService.resolve(serviceType, queueName, tenantId, entityId); | ||
408 | + } | ||
409 | + | ||
410 | + | ||
411 | + public String getServiceId() { | ||
412 | + return serviceInfoProvider.getServiceId(); | ||
416 | } | 413 | } |
417 | 414 | ||
418 | public void persistDebugInput(TenantId tenantId, EntityId entityId, TbMsg tbMsg, String relationType) { | 415 | public void persistDebugInput(TenantId tenantId, EntityId entityId, TbMsg tbMsg, String relationType) { |
@@ -443,7 +440,7 @@ public class ActorSystemContext { | @@ -443,7 +440,7 @@ public class ActorSystemContext { | ||
443 | 440 | ||
444 | ObjectNode node = mapper.createObjectNode() | 441 | ObjectNode node = mapper.createObjectNode() |
445 | .put("type", type) | 442 | .put("type", type) |
446 | - .put("server", getServerAddress()) | 443 | + .put("server", getServiceId()) |
447 | .put("entityId", tbMsg.getOriginator().getId().toString()) | 444 | .put("entityId", tbMsg.getOriginator().getId().toString()) |
448 | .put("entityName", tbMsg.getOriginator().getEntityType().name()) | 445 | .put("entityName", tbMsg.getOriginator().getEntityType().name()) |
449 | .put("msgId", tbMsg.getId().toString()) | 446 | .put("msgId", tbMsg.getId().toString()) |
@@ -469,7 +466,7 @@ public class ActorSystemContext { | @@ -469,7 +466,7 @@ public class ActorSystemContext { | ||
469 | public void onFailure(Throwable th) { | 466 | public void onFailure(Throwable th) { |
470 | log.error("Could not save debug Event for Node", th); | 467 | log.error("Could not save debug Event for Node", th); |
471 | } | 468 | } |
472 | - }); | 469 | + }, MoreExecutors.directExecutor()); |
473 | } catch (IOException ex) { | 470 | } catch (IOException ex) { |
474 | log.warn("Failed to persist rule node debug message", ex); | 471 | log.warn("Failed to persist rule node debug message", ex); |
475 | } | 472 | } |
@@ -503,7 +500,7 @@ public class ActorSystemContext { | @@ -503,7 +500,7 @@ public class ActorSystemContext { | ||
503 | 500 | ||
504 | ObjectNode node = mapper.createObjectNode() | 501 | ObjectNode node = mapper.createObjectNode() |
505 | //todo: what fields are needed here? | 502 | //todo: what fields are needed here? |
506 | - .put("server", getServerAddress()) | 503 | + .put("server", getServiceId()) |
507 | .put("message", "Reached debug mode rate limit!"); | 504 | .put("message", "Reached debug mode rate limit!"); |
508 | 505 | ||
509 | if (error != null) { | 506 | if (error != null) { |
@@ -522,11 +519,14 @@ public class ActorSystemContext { | @@ -522,11 +519,14 @@ public class ActorSystemContext { | ||
522 | public void onFailure(Throwable th) { | 519 | public void onFailure(Throwable th) { |
523 | log.error("Could not save debug Event for Rule Chain", th); | 520 | log.error("Could not save debug Event for Rule Chain", th); |
524 | } | 521 | } |
525 | - }); | 522 | + }, MoreExecutors.directExecutor()); |
526 | } | 523 | } |
527 | 524 | ||
528 | public static Exception toException(Throwable error) { | 525 | public static Exception toException(Throwable error) { |
529 | return Exception.class.isInstance(error) ? (Exception) error : new Exception(error); | 526 | return Exception.class.isInstance(error) ? (Exception) error : new Exception(error); |
530 | } | 527 | } |
531 | 528 | ||
529 | + public void tell(TbActorMsg tbActorMsg, ActorRef sender) { | ||
530 | + appActor.tell(tbActorMsg, sender); | ||
531 | + } | ||
532 | } | 532 | } |
@@ -20,19 +20,13 @@ import akka.actor.LocalActorRef; | @@ -20,19 +20,13 @@ import akka.actor.LocalActorRef; | ||
20 | import akka.actor.OneForOneStrategy; | 20 | import akka.actor.OneForOneStrategy; |
21 | import akka.actor.Props; | 21 | import akka.actor.Props; |
22 | import akka.actor.SupervisorStrategy; | 22 | import akka.actor.SupervisorStrategy; |
23 | -import akka.actor.SupervisorStrategy.Directive; | ||
24 | import akka.actor.Terminated; | 23 | import akka.actor.Terminated; |
25 | -import akka.event.Logging; | ||
26 | -import akka.event.LoggingAdapter; | ||
27 | -import akka.japi.Function; | ||
28 | import com.google.common.collect.BiMap; | 24 | import com.google.common.collect.BiMap; |
29 | import com.google.common.collect.HashBiMap; | 25 | import com.google.common.collect.HashBiMap; |
30 | -import lombok.extern.slf4j.Slf4j; | ||
31 | import org.thingsboard.server.actors.ActorSystemContext; | 26 | import org.thingsboard.server.actors.ActorSystemContext; |
32 | -import org.thingsboard.server.actors.ruleChain.RuleChainManagerActor; | 27 | +import org.thingsboard.server.actors.service.ContextAwareActor; |
33 | import org.thingsboard.server.actors.service.ContextBasedCreator; | 28 | import org.thingsboard.server.actors.service.ContextBasedCreator; |
34 | import org.thingsboard.server.actors.service.DefaultActorService; | 29 | import org.thingsboard.server.actors.service.DefaultActorService; |
35 | -import org.thingsboard.server.actors.shared.rulechain.SystemRuleChainManager; | ||
36 | import org.thingsboard.server.actors.tenant.TenantActor; | 30 | import org.thingsboard.server.actors.tenant.TenantActor; |
37 | import org.thingsboard.server.common.data.EntityType; | 31 | import org.thingsboard.server.common.data.EntityType; |
38 | import org.thingsboard.server.common.data.Tenant; | 32 | import org.thingsboard.server.common.data.Tenant; |
@@ -42,29 +36,32 @@ import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | @@ -42,29 +36,32 @@ import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; | ||
42 | import org.thingsboard.server.common.msg.MsgType; | 36 | import org.thingsboard.server.common.msg.MsgType; |
43 | import org.thingsboard.server.common.msg.TbActorMsg; | 37 | import org.thingsboard.server.common.msg.TbActorMsg; |
44 | import org.thingsboard.server.common.msg.aware.TenantAwareMsg; | 38 | import org.thingsboard.server.common.msg.aware.TenantAwareMsg; |
45 | -import org.thingsboard.server.common.msg.cluster.SendToClusterMsg; | ||
46 | -import org.thingsboard.server.common.msg.cluster.ServerAddress; | ||
47 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; | 39 | import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; |
48 | -import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg; | 40 | +import org.thingsboard.server.common.msg.queue.QueueToRuleEngineMsg; |
41 | +import org.thingsboard.server.common.msg.queue.RuleEngineException; | ||
42 | +import org.thingsboard.server.common.msg.queue.ServiceType; | ||
49 | import org.thingsboard.server.dao.model.ModelConstants; | 43 | import org.thingsboard.server.dao.model.ModelConstants; |
50 | import org.thingsboard.server.dao.tenant.TenantService; | 44 | import org.thingsboard.server.dao.tenant.TenantService; |
45 | +import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; | ||
51 | import scala.concurrent.duration.Duration; | 46 | import scala.concurrent.duration.Duration; |
52 | 47 | ||
53 | -import java.util.HashMap; | ||
54 | -import java.util.Map; | 48 | +import java.util.HashSet; |
55 | import java.util.Optional; | 49 | import java.util.Optional; |
50 | +import java.util.Set; | ||
56 | 51 | ||
57 | -public class AppActor extends RuleChainManagerActor { | 52 | +public class AppActor extends ContextAwareActor { |
58 | 53 | ||
59 | private static final TenantId SYSTEM_TENANT = new TenantId(ModelConstants.NULL_UUID); | 54 | private static final TenantId SYSTEM_TENANT = new TenantId(ModelConstants.NULL_UUID); |
60 | private final TenantService tenantService; | 55 | private final TenantService tenantService; |
61 | private final BiMap<TenantId, ActorRef> tenantActors; | 56 | private final BiMap<TenantId, ActorRef> tenantActors; |
57 | + private final Set<TenantId> deletedTenants; | ||
62 | private boolean ruleChainsInitialized; | 58 | private boolean ruleChainsInitialized; |
63 | 59 | ||
64 | private AppActor(ActorSystemContext systemContext) { | 60 | private AppActor(ActorSystemContext systemContext) { |
65 | - super(systemContext, new SystemRuleChainManager(systemContext)); | 61 | + super(systemContext); |
66 | this.tenantService = systemContext.getTenantService(); | 62 | this.tenantService = systemContext.getTenantService(); |
67 | this.tenantActors = HashBiMap.create(); | 63 | this.tenantActors = HashBiMap.create(); |
64 | + this.deletedTenants = new HashSet<>(); | ||
68 | } | 65 | } |
69 | 66 | ||
70 | @Override | 67 | @Override |
@@ -79,7 +76,7 @@ public class AppActor extends RuleChainManagerActor { | @@ -79,7 +76,7 @@ public class AppActor extends RuleChainManagerActor { | ||
79 | @Override | 76 | @Override |
80 | protected boolean process(TbActorMsg msg) { | 77 | protected boolean process(TbActorMsg msg) { |
81 | if (!ruleChainsInitialized) { | 78 | if (!ruleChainsInitialized) { |
82 | - initRuleChainsAndTenantActors(); | 79 | + initTenantActors(); |
83 | ruleChainsInitialized = true; | 80 | ruleChainsInitialized = true; |
84 | if (msg.getMsgType() != MsgType.APP_INIT_MSG) { | 81 | if (msg.getMsgType() != MsgType.APP_INIT_MSG) { |
85 | log.warn("Rule Chains initialized by unexpected message: {}", msg); | 82 | log.warn("Rule Chains initialized by unexpected message: {}", msg); |
@@ -88,17 +85,14 @@ public class AppActor extends RuleChainManagerActor { | @@ -88,17 +85,14 @@ public class AppActor extends RuleChainManagerActor { | ||
88 | switch (msg.getMsgType()) { | 85 | switch (msg.getMsgType()) { |
89 | case APP_INIT_MSG: | 86 | case APP_INIT_MSG: |
90 | break; | 87 | break; |
91 | - case SEND_TO_CLUSTER_MSG: | ||
92 | - onPossibleClusterMsg((SendToClusterMsg) msg); | ||
93 | - break; | ||
94 | - case CLUSTER_EVENT_MSG: | 88 | + case PARTITION_CHANGE_MSG: |
95 | broadcast(msg); | 89 | broadcast(msg); |
96 | break; | 90 | break; |
97 | case COMPONENT_LIFE_CYCLE_MSG: | 91 | case COMPONENT_LIFE_CYCLE_MSG: |
98 | onComponentLifecycleMsg((ComponentLifecycleMsg) msg); | 92 | onComponentLifecycleMsg((ComponentLifecycleMsg) msg); |
99 | break; | 93 | break; |
100 | - case SERVICE_TO_RULE_ENGINE_MSG: | ||
101 | - onServiceToRuleEngineMsg((ServiceToRuleEngineMsg) msg); | 94 | + case QUEUE_TO_RULE_ENGINE_MSG: |
95 | + onQueueToRuleEngineMsg((QueueToRuleEngineMsg) msg); | ||
102 | break; | 96 | break; |
103 | case TRANSPORT_TO_DEVICE_ACTOR_MSG: | 97 | case TRANSPORT_TO_DEVICE_ACTOR_MSG: |
104 | case DEVICE_ATTRIBUTES_UPDATE_TO_DEVICE_ACTOR_MSG: | 98 | case DEVICE_ATTRIBUTES_UPDATE_TO_DEVICE_ACTOR_MSG: |
@@ -106,7 +100,6 @@ public class AppActor extends RuleChainManagerActor { | @@ -106,7 +100,6 @@ public class AppActor extends RuleChainManagerActor { | ||
106 | case DEVICE_NAME_OR_TYPE_UPDATE_TO_DEVICE_ACTOR_MSG: | 100 | case DEVICE_NAME_OR_TYPE_UPDATE_TO_DEVICE_ACTOR_MSG: |
107 | case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: | 101 | case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: |
108 | case SERVER_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: | 102 | case SERVER_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: |
109 | - case REMOTE_TO_RULE_CHAIN_TELL_NEXT_MSG: | ||
110 | onToDeviceActorMsg((TenantAwareMsg) msg); | 103 | onToDeviceActorMsg((TenantAwareMsg) msg); |
111 | break; | 104 | break; |
112 | default: | 105 | default: |
@@ -115,16 +108,30 @@ public class AppActor extends RuleChainManagerActor { | @@ -115,16 +108,30 @@ public class AppActor extends RuleChainManagerActor { | ||
115 | return true; | 108 | return true; |
116 | } | 109 | } |
117 | 110 | ||
118 | - private void initRuleChainsAndTenantActors() { | 111 | + private void initTenantActors() { |
119 | log.info("Starting main system actor."); | 112 | log.info("Starting main system actor."); |
120 | try { | 113 | try { |
121 | - initRuleChains(); | ||
122 | - if (systemContext.isTenantComponentsInitEnabled()) { | ||
123 | - PageDataIterable<Tenant> tenantIterator = new PageDataIterable<>(tenantService::findTenants, ENTITY_PACK_LIMIT); | ||
124 | - for (Tenant tenant : tenantIterator) { | 114 | + // This Service may be started for specific tenant only. |
115 | + Optional<TenantId> isolatedTenantId = systemContext.getServiceInfoProvider().getIsolatedTenant(); | ||
116 | + if (isolatedTenantId.isPresent()) { | ||
117 | + Tenant tenant = systemContext.getTenantService().findTenantById(isolatedTenantId.get()); | ||
118 | + if (tenant != null) { | ||
125 | log.debug("[{}] Creating tenant actor", tenant.getId()); | 119 | log.debug("[{}] Creating tenant actor", tenant.getId()); |
126 | getOrCreateTenantActor(tenant.getId()); | 120 | getOrCreateTenantActor(tenant.getId()); |
127 | log.debug("Tenant actor created."); | 121 | log.debug("Tenant actor created."); |
122 | + } else { | ||
123 | + log.error("[{}] Tenant with such ID does not exist", isolatedTenantId.get()); | ||
124 | + } | ||
125 | + } else if (systemContext.isTenantComponentsInitEnabled()) { | ||
126 | + PageDataIterable<Tenant> tenantIterator = new PageDataIterable<>(tenantService::findTenants, ENTITY_PACK_LIMIT); | ||
127 | + boolean isRuleEngine = systemContext.getServiceInfoProvider().isService(ServiceType.TB_RULE_ENGINE); | ||
128 | + boolean isCore = systemContext.getServiceInfoProvider().isService(ServiceType.TB_CORE); | ||
129 | + for (Tenant tenant : tenantIterator) { | ||
130 | + if (isCore || (isRuleEngine && !tenant.isIsolatedTbRuleEngine())) { | ||
131 | + log.debug("[{}] Creating tenant actor", tenant.getId()); | ||
132 | + getOrCreateTenantActor(tenant.getId()); | ||
133 | + log.debug("[{}] Tenant actor created.", tenant.getId()); | ||
134 | + } | ||
128 | } | 135 | } |
129 | } | 136 | } |
130 | log.info("Main system actor started."); | 137 | log.info("Main system actor started."); |
@@ -133,40 +140,33 @@ public class AppActor extends RuleChainManagerActor { | @@ -133,40 +140,33 @@ public class AppActor extends RuleChainManagerActor { | ||
133 | } | 140 | } |
134 | } | 141 | } |
135 | 142 | ||
136 | - private void onPossibleClusterMsg(SendToClusterMsg msg) { | ||
137 | - Optional<ServerAddress> address = systemContext.getRoutingService().resolveById(msg.getEntityId()); | ||
138 | - if (address.isPresent()) { | ||
139 | - systemContext.getRpcService().tell( | ||
140 | - systemContext.getEncodingService().convertToProtoDataMessage(address.get(), msg.getMsg())); | ||
141 | - } else { | ||
142 | - self().tell(msg.getMsg(), ActorRef.noSender()); | ||
143 | - } | ||
144 | - } | ||
145 | - | ||
146 | - private void onServiceToRuleEngineMsg(ServiceToRuleEngineMsg msg) { | 143 | + private void onQueueToRuleEngineMsg(QueueToRuleEngineMsg msg) { |
147 | if (SYSTEM_TENANT.equals(msg.getTenantId())) { | 144 | if (SYSTEM_TENANT.equals(msg.getTenantId())) { |
148 | -// this may be a notification about system entities created. | ||
149 | -// log.warn("[{}] Invalid service to rule engine msg called. System messages are not supported yet: {}", SYSTEM_TENANT, msg); | 145 | + msg.getTbMsg().getCallback().onFailure(new RuleEngineException("Message has system tenant id!")); |
150 | } else { | 146 | } else { |
151 | - getOrCreateTenantActor(msg.getTenantId()).tell(msg, self()); | 147 | + if (!deletedTenants.contains(msg.getTenantId())) { |
148 | + getOrCreateTenantActor(msg.getTenantId()).tell(msg, self()); | ||
149 | + } else { | ||
150 | + msg.getTbMsg().getCallback().onSuccess(); | ||
151 | + } | ||
152 | } | 152 | } |
153 | } | 153 | } |
154 | 154 | ||
155 | - @Override | ||
156 | protected void broadcast(Object msg) { | 155 | protected void broadcast(Object msg) { |
157 | - super.broadcast(msg); | ||
158 | tenantActors.values().forEach(actorRef -> actorRef.tell(msg, ActorRef.noSender())); | 156 | tenantActors.values().forEach(actorRef -> actorRef.tell(msg, ActorRef.noSender())); |
159 | } | 157 | } |
160 | 158 | ||
161 | private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { | 159 | private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { |
162 | ActorRef target = null; | 160 | ActorRef target = null; |
163 | if (SYSTEM_TENANT.equals(msg.getTenantId())) { | 161 | if (SYSTEM_TENANT.equals(msg.getTenantId())) { |
164 | - target = getEntityActorRef(msg.getEntityId()); | 162 | + log.warn("Message has system tenant id: {}", msg); |
165 | } else { | 163 | } else { |
166 | if (msg.getEntityId().getEntityType() == EntityType.TENANT | 164 | if (msg.getEntityId().getEntityType() == EntityType.TENANT |
167 | && msg.getEvent() == ComponentLifecycleEvent.DELETED) { | 165 | && msg.getEvent() == ComponentLifecycleEvent.DELETED) { |
168 | - log.debug("[{}] Handling tenant deleted notification: {}", msg.getTenantId(), msg); | ||
169 | - ActorRef tenantActor = tenantActors.remove(new TenantId(msg.getEntityId().getId())); | 166 | + log.info("[{}] Handling tenant deleted notification: {}", msg.getTenantId(), msg); |
167 | + TenantId tenantId = new TenantId(msg.getEntityId().getId()); | ||
168 | + deletedTenants.add(tenantId); | ||
169 | + ActorRef tenantActor = tenantActors.get(tenantId); | ||
170 | if (tenantActor != null) { | 170 | if (tenantActor != null) { |
171 | log.debug("[{}] Deleting tenant actor: {}", msg.getTenantId(), tenantActor); | 171 | log.debug("[{}] Deleting tenant actor: {}", msg.getTenantId(), tenantActor); |
172 | context().stop(tenantActor); | 172 | context().stop(tenantActor); |
@@ -183,16 +183,22 @@ public class AppActor extends RuleChainManagerActor { | @@ -183,16 +183,22 @@ public class AppActor extends RuleChainManagerActor { | ||
183 | } | 183 | } |
184 | 184 | ||
185 | private void onToDeviceActorMsg(TenantAwareMsg msg) { | 185 | private void onToDeviceActorMsg(TenantAwareMsg msg) { |
186 | - getOrCreateTenantActor(msg.getTenantId()).tell(msg, ActorRef.noSender()); | 186 | + if (!deletedTenants.contains(msg.getTenantId())) { |
187 | + getOrCreateTenantActor(msg.getTenantId()).tell(msg, ActorRef.noSender()); | ||
188 | + } else { | ||
189 | + if (msg instanceof TransportToDeviceActorMsgWrapper) { | ||
190 | + ((TransportToDeviceActorMsgWrapper) msg).getCallback().onSuccess(); | ||
191 | + } | ||
192 | + } | ||
187 | } | 193 | } |
188 | 194 | ||
189 | private ActorRef getOrCreateTenantActor(TenantId tenantId) { | 195 | private ActorRef getOrCreateTenantActor(TenantId tenantId) { |
190 | return tenantActors.computeIfAbsent(tenantId, k -> { | 196 | return tenantActors.computeIfAbsent(tenantId, k -> { |
191 | - log.debug("[{}] Creating tenant actor.", tenantId); | 197 | + log.info("[{}] Creating tenant actor.", tenantId); |
192 | ActorRef tenantActor = context().actorOf(Props.create(new TenantActor.ActorCreator(systemContext, tenantId)) | 198 | ActorRef tenantActor = context().actorOf(Props.create(new TenantActor.ActorCreator(systemContext, tenantId)) |
193 | .withDispatcher(DefaultActorService.CORE_DISPATCHER_NAME), tenantId.toString()); | 199 | .withDispatcher(DefaultActorService.CORE_DISPATCHER_NAME), tenantId.toString()); |
194 | context().watch(tenantActor); | 200 | context().watch(tenantActor); |
195 | - log.debug("[{}] Created tenant actor: {}.", tenantId, tenantActor); | 201 | + log.info("[{}] Created tenant actor: {}.", tenantId, tenantActor); |
196 | return tenantActor; | 202 | return tenantActor; |
197 | }); | 203 | }); |
198 | } | 204 | } |
@@ -22,10 +22,8 @@ import org.thingsboard.server.actors.service.ContextAwareActor; | @@ -22,10 +22,8 @@ import org.thingsboard.server.actors.service.ContextAwareActor; | ||
22 | import org.thingsboard.server.common.data.id.DeviceId; | 22 | import org.thingsboard.server.common.data.id.DeviceId; |
23 | import org.thingsboard.server.common.data.id.TenantId; | 23 | import org.thingsboard.server.common.data.id.TenantId; |
24 | import org.thingsboard.server.common.msg.TbActorMsg; | 24 | import org.thingsboard.server.common.msg.TbActorMsg; |
25 | -import org.thingsboard.server.common.msg.timeout.DeviceActorClientSideRpcTimeoutMsg; | ||
26 | import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg; | 25 | import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg; |
27 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; | 26 | import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; |
28 | -import org.thingsboard.server.service.rpc.ToServerRpcResponseActorMsg; | ||
29 | import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; | 27 | import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; |
30 | 28 | ||
31 | public class DeviceActor extends ContextAwareActor { | 29 | public class DeviceActor extends ContextAwareActor { |
@@ -49,6 +47,11 @@ public class DeviceActor extends ContextAwareActor { | @@ -49,6 +47,11 @@ public class DeviceActor extends ContextAwareActor { | ||
49 | } | 47 | } |
50 | 48 | ||
51 | @Override | 49 | @Override |
50 | + public void postStop() { | ||
51 | + | ||
52 | + } | ||
53 | + | ||
54 | + @Override | ||
52 | protected boolean process(TbActorMsg msg) { | 55 | protected boolean process(TbActorMsg msg) { |
53 | switch (msg.getMsgType()) { | 56 | switch (msg.getMsgType()) { |
54 | case TRANSPORT_TO_DEVICE_ACTOR_MSG: | 57 | case TRANSPORT_TO_DEVICE_ACTOR_MSG: |
@@ -66,15 +69,9 @@ public class DeviceActor extends ContextAwareActor { | @@ -66,15 +69,9 @@ public class DeviceActor extends ContextAwareActor { | ||
66 | case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: | 69 | case DEVICE_RPC_REQUEST_TO_DEVICE_ACTOR_MSG: |
67 | processor.processRpcRequest(context(), (ToDeviceRpcRequestActorMsg) msg); | 70 | processor.processRpcRequest(context(), (ToDeviceRpcRequestActorMsg) msg); |
68 | break; | 71 | break; |
69 | - case SERVER_RPC_RESPONSE_TO_DEVICE_ACTOR_MSG: | ||
70 | - processor.processToServerRPCResponse(context(), (ToServerRpcResponseActorMsg) msg); | ||
71 | - break; | ||
72 | case DEVICE_ACTOR_SERVER_SIDE_RPC_TIMEOUT_MSG: | 72 | case DEVICE_ACTOR_SERVER_SIDE_RPC_TIMEOUT_MSG: |
73 | processor.processServerSideRpcTimeout(context(), (DeviceActorServerSideRpcTimeoutMsg) msg); | 73 | processor.processServerSideRpcTimeout(context(), (DeviceActorServerSideRpcTimeoutMsg) msg); |
74 | break; | 74 | break; |
75 | - case DEVICE_ACTOR_CLIENT_SIDE_RPC_TIMEOUT_MSG: | ||
76 | - processor.processClientSideRpcTimeout(context(), (DeviceActorClientSideRpcTimeoutMsg) msg); | ||
77 | - break; | ||
78 | case SESSION_TIMEOUT_MSG: | 75 | case SESSION_TIMEOUT_MSG: |
79 | processor.checkSessionsTimeout(); | 76 | processor.checkSessionsTimeout(); |
80 | break; | 77 | break; |