From d78193f2e51c11428140f56feecc61e68317efec Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Tue, 28 Apr 2020 21:19:53 +0300 Subject: [PATCH 1/2] Test Thermostat devices --- .../data/json/demo/dashboards/theromstats.json | 12 +++++------- .../demo/rule_chains/thermostat_alarms.json | 8 ++++++-- .../DefaultSystemDataLoaderService.java | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/application/src/main/data/json/demo/dashboards/theromstats.json b/application/src/main/data/json/demo/dashboards/theromstats.json index c7ab182171..92d5082031 100644 --- a/application/src/main/data/json/demo/dashboards/theromstats.json +++ b/application/src/main/data/json/demo/dashboards/theromstats.json @@ -1181,12 +1181,10 @@ "id": "ce27a9d0-93bf-b7a4-054d-d0369a8cf813", "alias": "Thermostat-alarm", "filter": { - "type": "singleEntity", - "resolveMultiple": false, - "singleEntity": { - "entityType": "CURRENT_TENANT", - "id": null - } + "type": "entityName", + "resolveMultiple": true, + "entityType": "ASSET", + "entityNameFilter": "Thermostat Alarms" } } }, @@ -1225,4 +1223,4 @@ } }, "name": "Thermostats" -} +} \ No newline at end of file diff --git a/application/src/main/data/json/demo/rule_chains/thermostat_alarms.json b/application/src/main/data/json/demo/rule_chains/thermostat_alarms.json index 9b7e3401d2..8fd10c88f1 100644 --- a/application/src/main/data/json/demo/rule_chains/thermostat_alarms.json +++ b/application/src/main/data/json/demo/rule_chains/thermostat_alarms.json @@ -24,7 +24,9 @@ "severity": "MAJOR", "propagate": true, "useMessageAlarmData": false, - "relationTypes": [] + "relationTypes": [ + "ToAlarmPropagationAsset" + ] } }, { @@ -54,7 +56,9 @@ "severity": "MINOR", "propagate": true, "useMessageAlarmData": false, - "relationTypes": [] + "relationTypes": [ + "ToAlarmPropagationAsset" + ] } }, { diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index b8d5d26d06..3403cf56e2 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; @@ -36,14 +37,17 @@ import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; import org.thingsboard.server.common.data.kv.BooleanDataEntry; import org.thingsboard.server.common.data.kv.DoubleDataEntry; import org.thingsboard.server.common.data.kv.LongDataEntry; +import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.dao.asset.AssetService; import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.customer.CustomerService; import org.thingsboard.server.dao.device.DeviceCredentialsService; import org.thingsboard.server.dao.device.DeviceService; +import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.user.UserService; @@ -81,6 +85,12 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { @Autowired private CustomerService customerService; + @Autowired + private RelationService relationService; + + @Autowired + private AssetService assetService; + @Autowired private DeviceService deviceService; @@ -163,9 +173,17 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { createDevice(demoTenant.getId(), null, DEFAULT_DEVICE_TYPE, "Raspberry Pi Demo Device", "RASPBERRY_PI_DEMO_TOKEN", "Demo device that is used in " + "Raspberry Pi GPIO control sample application"); + Asset thermostatAlarms = new Asset(); + thermostatAlarms.setName("Thermostat Alarms"); + thermostatAlarms.setType("AlarmPropagationAsset"); + thermostatAlarms = assetService.saveAsset(thermostatAlarms); + DeviceId t1Id = createDevice(demoTenant.getId(), null, "thermostat", "Thermostat T1", "T1_TEST_TOKEN", "Demo device for Thermostats dashboard").getId(); DeviceId t2Id = createDevice(demoTenant.getId(), null, "thermostat", "Thermostat T2", "T2_TEST_TOKEN", "Demo device for Thermostats dashboard").getId(); + relationService.saveRelation(thermostatAlarms.getTenantId(), new EntityRelation(thermostatAlarms.getId(), t1Id, "ToAlarmPropagationAsset")); + relationService.saveRelation(thermostatAlarms.getTenantId(), new EntityRelation(thermostatAlarms.getId(), t2Id, "ToAlarmPropagationAsset")); + attributesService.save(demoTenant.getId(), t1Id, DataConstants.SERVER_SCOPE, Arrays.asList(new BaseAttributeKvEntry(System.currentTimeMillis(), new DoubleDataEntry("latitude", 37.3948)), new BaseAttributeKvEntry(System.currentTimeMillis(), new DoubleDataEntry("longitude", -122.1503)), From 8a246cceab0f83a8254ca8a8adcc63703ae60cb6 Mon Sep 17 00:00:00 2001 From: Vladyslav Date: Wed, 29 Apr 2020 09:34:33 +0300 Subject: [PATCH 2/2] Clear code (#2691) --- .../demo/dashboards/{theromstats.json => thermostats.json} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename application/src/main/data/json/demo/dashboards/{theromstats.json => thermostats.json} (94%) diff --git a/application/src/main/data/json/demo/dashboards/theromstats.json b/application/src/main/data/json/demo/dashboards/thermostats.json similarity index 94% rename from application/src/main/data/json/demo/dashboards/theromstats.json rename to application/src/main/data/json/demo/dashboards/thermostats.json index 92d5082031..33bf9d6576 100644 --- a/application/src/main/data/json/demo/dashboards/theromstats.json +++ b/application/src/main/data/json/demo/dashboards/thermostats.json @@ -121,7 +121,7 @@ "type": "customPretty", "customHtml": "\n
\n \n
\n

Add thermostat

\n \n \n \n \n
\n
\n \n
\n \n \n \n
\n
Thermostat name is required.
\n
\n
\n \n High temperature alarm\n \n \n \n \n
\n
High temperature threshold is required.
\n
\n
\n \n Low humidity alarm\n \n \n \n \n
\n
Low humidity threshold is required.
\n
\n
\n
\n
\n \n Create\n Cancel\n \n
\n
", "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", - "customFunction": "var $injector = widgetContext.$scope.$injector;\nvar $mdDialog = $injector.get('$mdDialog'),\n $document = $injector.get('$document'),\n $q = $injector.get('$q'),\n types = $injector.get('types'),\n $rootScope = $injector.get('$rootScope'),\n deviceService = $injector.get('deviceService'),\n attributeService = $injector.get('attributeService'),\n userService = $injector.get('userService'),\n entityRelationService = $injector.get('entityRelationService');\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 vm.relations = [];\n\n vm.addRelation = function() {\n var relation = {\n direction: types.entitySearchDirection.from,\n relationType: 'Contains',\n relatedEntity: {\n id: userService.getCurrentUser().tenantId,\n entityType: types.entityType.tenant\n }\n };\n console.log(userService.getCurrentUser());\n vm.relations.push(relation);\n };\n\n vm.save = function() {\n $scope.addEntityForm.$setPristine();\n vm.addRelation();\n saveEntityPromise().then(\n function (entity) {\n $q.all([saveAttributes(entity.id),\n saveRelations(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 attributeService.saveEntityAttributes(entityId.entityType, entityId.id, \"SERVER_SCOPE\", attributesArray);\n } \n }\n \n function saveRelations(entityId) {\n var tasks = [];\n for (var i=0; i < vm.relations.length; i++) {\n var relation = {\n type: vm.relations[i].relationType\n };\n if (vm.relations[i].direction == types.entitySearchDirection.from) {\n relation.to = vm.relations[i].relatedEntity;\n relation.from = entityId;\n } else {\n relation.to = entityId;\n relation.from = vm.relations[i].relatedEntity;\n }\n tasks.push(entityRelationService.saveRelation(relation));\n }\n return $q.all(tasks);\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}" + "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}" } ], "actionCellButton": [ @@ -1223,4 +1223,4 @@ } }, "name": "Thermostats" -} \ No newline at end of file +}