SAP HANA IoT and The Internet of Things
If you have not seen yet, double check the introduction, first part, second part, third part, fourth part and fifth part of this SAP HANA IoT series.
Configuring SAP UI5
We have covered all the steps related to hardware setup and have also configured the backend SAP HANA.
We’ll configure now the UI which is going to show the sensor information.
The UI is simple and we have kept two tiles
The first tile is showing the value of the sensor ie. the LUX value or light intensity. The small window, below the reading value, tells how the sensor looks like (used custom CSS mapping).
We are going to create a simple view and controller and place the tiles in the view.The tiles will be placed in the tile container and the tile container will be returned inside the content of the page.
There are 3 main component here :
- Index.html
- View
- Controller.
Code for the above components are:
Index.html
HANA IoT <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3E%2F%2F%20%3C!%5BCDATA%5B%20sap.ui.localResources(%22shiot_ui%22)%3B%20app%20%3D%20new%20sap.m.App(%7BinitialPage%3A%22idshiot_ui1%22%7D)%3B%20var%20page%20%3D%20sap.ui.view(%7Bid%3A%22idshiot_ui1%22%2C%20viewName%3A%22shiot_ui_02.shiot_ui_02%22%2C%20type%3Asap.ui.core.mvc.ViewType.JS%7D)%3B%20app.addPage(page)%3B%20app.placeAt(%22content%22)%3B%20%2F%2F%20%5D%5D%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" /> <div id="splash-screen"> <div class="splash-screen-text"> <div class="en">Welcome to HANA IoT Demo</div> </div> <div class="splash-screen-circle-outer"></div> <div class="splash-screen-circle-inner"></div> </div> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20id%3D%22sap-ui-bootstrap%22%20src%3D%22https%3A%2F%2Fsapui5.hana.ondemand.com%2Fresources%2Fsap-ui-core.js%22%20data-sap-ui-libs%3D%22sap.m%2Csap.suite.ui.commons%2Csap.ui.core%2Csap.viz%22%20data-sap-ui-theme%3D%22sap_bluecrystal%22%3E%2F%2F%20%3C!%5BCDATA%5B%20%2F%2F%20%5D%5D%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>" />
View:
sap.ui.jsview("shiot_ui_02.shiot_ui_02", { /** Specifies the Controller belonging to this View. * In the case that it is not implemented, or that "null" is returned, this View does not have a Controller. * @memberOf shiot_ui_02.shiot_ui_02 */ getControllerName : function() { return "shiot_ui_02.shiot_ui_02"; }, /** Is initially called once after the Controller has been instantiated. It is the place where the UI is constructed. * Since the Controller is given to this method, its event handlers can be attached right away. * @memberOf shiot_ui_02.shiot_ui_02 */ createContent : function(oController) { var content = new sap.suite.ui.commons.NumericContent("idInRateValue", { size: "S", scale: "LUX", value: "{/value}", valueColor: "Good", indicator: "{/direction}" }); var tileContent = new sap.suite.ui.commons.TileContent("idInTileCont", { unit: "", size: "L", content: [ content ] }); var tileInInfo = new sap.suite.ui.commons.GenericTile("idTileInInfo", { header: "In", size: "S", frameType: "TwoByOne", tileContent: [ tileContent ] }); var tileCompr = new sap.suite.ui.commons.GenericTile("idAllGTStatus", { header: "Compare Level", size: "L", scale: "L", frameType: "TwoByOne", press: function(){ sap.m.MessageToast.show("Demo"); }, tileContent: [ new sap.suite.ui.commons.TileContent("idDaysComprDash", { size: "S", scale: "S", content: [ new sap.suite.ui.commons.ComparisonChart("idDaysCompr", { size: "XS", width: "18rem", data: [ new sap.suite.ui.commons.ComparisonData({ title: "Maximum Limit", value: "{/comparisonValue1}", color: sap.suite.ui.commons.InfoTileValueColor.Error }), new sap.suite.ui.commons.ComparisonData({ title: "Current", value: "{/comparisonValue2}", color: sap.suite.ui.commons.InfoTileValueColor.Critical }),new sap.suite.ui.commons.ComparisonData({ title: "Mimumim Limit", value: "{/comparisonValue3}", color: sap.suite.ui.commons.InfoTileValueColor.Good }) ] }) ] }) ] }); tileCompr.addStyleClass("sapMTile backGroundWhite"); var custeReading = new sap.m.CustomTile({ content: [ tileContent ] }); var custeCompare = new sap.m.CustomTile({ content: [ tileCompr ] }); var tileContainer = new sap.m.TileContainer("idMainTiles", { tiles: [ custeReading, custeCompare ] }); //Polling implementation setInterval(oController.changeKPITest, 1000 * 3); // create the page holding the List var page1 = new sap.m.Page({ title: "HANA IoT KPI", enableScrolling: false, content : [ tileContainer ] }); return page1; } });
Controller:
sap.ui.controller("shiot_ui_02.shiot_ui_02", { /** * Called when a controller is instantiated and its View controls (if available) are already created. * Can be used to modify the View before it is displayed, to bind event handlers and do other one-time initialization. * @memberOf shiot_ui_02.shiot_ui_02 */ //onInit: function() { // //}, /** * Similar to onAfterRendering, but this hook is invoked before the controller's View is re-rendered * (NOT before the first rendering! onInit() is used for that one!). * @memberOf shiot_ui_02.shiot_ui_02 */ onBeforeRendering: function() { var data = { "value": 0, "direction": "Down", "comparisonValue1": 0, "comparisonValue2": 0, "comparisonValue3": 0 }; var oModel = new sap.ui.model.json.JSONModel(); oModel.setData(data); sap.ui.getCore().setModel(oModel); }, //Triggers automatically for display test changeKPITest: function(){ /*var min = 0; var max = 100; var newRandomreading = Math.floor(Math.random() * (max - min)) + min;*/ var url = "http:///demoApp/demo01/app01/services/getSensorReading.xsjs?id="; var _SENSORID = "A001"; var _MAXLIMIT = 170; var _MINLIMIT = 25; var data = { "value": 0, "direction": "Down", "comparisonValue1": _MAXLIMIT, "comparisonValue2": 0, "comparisonValue3": _MINLIMIT }; var oModel; var newColorCode; //for now hardcoding the sensor ID url = url + _SENSORID; //Doing the asyn call to HANA system jQuery.ajax({ url: url, async: true, dataType: 'json', type: 'GET', success: function(oData) { if (!oData) { sap.m.MessageToast.show("Not able to get Data"); } else { data["value"] = oData["value"]; data["comparisonValue2"] = oData["value"]; oModel = sap.ui.getCore().getModel(); if(oModel.getData()["comparisonValue2"] > data["comparisonValue2"]){ data["direction"] = "Down"; }else{ data["direction"] = "Up"; } oModel.setData(data); oModel.refresh(); //changing the color as well newColorCode = parseInt(data["value"])*2 ; if(newColorCode > 255){ newColorCode = 255; } $('#idInTileCont-footer-text').css("background-color", "rgba("+newColorCode+", "+newColorCode+", "+newColorCode+", 0.99)"); } }, error: function(XMLHttpRequest, textStatus, errorThrown) { sap.m.MessageToast.show("Connection not able to establish"); } }); }, /** * Called when the View has been rendered (so its HTML is part of the document). Post-rendering manipulations of the HTML could be done here. * This hook is the same one that SAPUI5 controls get after being rendered. * @memberOf shiot_ui_02.shiot_ui_02 */ //onAfterRendering: function() { // //}, /** * Called when the Controller is destroyed. Use this one to free resources and finalize activities. * @memberOf shiot_ui_02.shiot_ui_02 */ //onExit: function() { // //} });
Here the controller function changeKPITest is polled every 3 sec and we have the new data bound to model, which is returned from SAP HANA XSJS AJAX call .
It is better to have a push notification feature in here instead of polling which, is called web-sockets, but for simplicity purpose we have kept the configuration minimal.
In part 7, we are tying the loose ends and going live.
UI5CN
UI5CN