{"id":1190,"date":"2019-09-29T15:45:28","date_gmt":"2019-09-29T13:45:28","guid":{"rendered":"https:\/\/azure.teamprojects.de\/?page_id=1190"},"modified":"2019-09-30T11:41:12","modified_gmt":"2019-09-30T09:41:12","slug":"azure-web-app","status":"publish","type":"page","link":"https:\/\/azure.teamprojects.de\/?page_id=1190","title":{"rendered":"Azure Web-App"},"content":{"rendered":"\n<h2><strong>Allgemein<\/strong><\/h2>\n\n\n\n<p>Mit Hilfe des Azure App Service bietet sich die M\u00f6glichkeit ein auf die eigenen Bed\u00fcrfnisse abgestimmtes Frontend (Website oder Webanwendung) mit verschiedensten Funktionen zu implementieren. Ein weiterer Vorteil dieses Services besteht darin, dass er sich beliebig skalieren l\u00e4sst und die komplette Infrastruktur von Azure bereitgestellt wird.<\/p>\n\n\n\n<p>Dieser Service wurde bei diesem Projekt genutzt, um eine eigene Website (Web-App) zu erstellen. Diese dient dazu, verschiedenste Informationen \u00fcber die gewonnen Daten der Smart Home Komponenten zu liefern ohne einen direkten Zugriff auf den Microsoft Azure Account zu haben. Hierzu geh\u00f6ren unter anderem Live- und Historische-Daten. F\u00fcr die Programmierung dieser Web-App wurde Hypertext Markup Language (HTML), Cascading Style Sheets (CSS) und Javascript verwendet. Hierbei wurde HTML als Grundlage f\u00fcr die Seitengestaltung genutzt. Mithilfe von CSS wurde das Aussehen der Seiten verbessert und optimiert. Der komplette Quellcode f\u00fcr die Funktionalit\u00e4t der Web-App wurde in Javascript geschrieben.   <\/p>\n\n\n\n<p>Link zur Website: <a href=\"https:\/\/h-dasmarthomeprojekt.azurewebsites.net\/HistoryDataHtml\/temperaturHumidityHistory.html\">https:\/\/h-dasmarthomeprojekt.azurewebsites.net\/HistoryDataHtml\/temperaturHumidityHistory.html<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/azure.teamprojects.de\/wp-content\/uploads\/2019\/09\/Web-App_History_Daten-1024x560.png\" alt=\"\" class=\"wp-image-1202\" width=\"817\" height=\"447\" srcset=\"https:\/\/azure.teamprojects.de\/wp-content\/uploads\/2019\/09\/Web-App_History_Daten-1024x560.png 1024w, https:\/\/azure.teamprojects.de\/wp-content\/uploads\/2019\/09\/Web-App_History_Daten-300x164.png 300w, https:\/\/azure.teamprojects.de\/wp-content\/uploads\/2019\/09\/Web-App_History_Daten-768x420.png 768w, https:\/\/azure.teamprojects.de\/wp-content\/uploads\/2019\/09\/Web-App_History_Daten.png 1905w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption>Screenshot der erstellten Web-App<\/figcaption><\/figure>\n\n\n\n<h2><strong>Funktion der Web-App<\/strong>  <\/h2>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/azure.teamprojects.de\/wp-content\/uploads\/2019\/09\/Funktionsweise_Web-App.png\" alt=\"\" class=\"wp-image-1205\" width=\"343\" height=\"337\" srcset=\"https:\/\/azure.teamprojects.de\/wp-content\/uploads\/2019\/09\/Funktionsweise_Web-App.png 637w, https:\/\/azure.teamprojects.de\/wp-content\/uploads\/2019\/09\/Funktionsweise_Web-App-300x295.png 300w\" sizes=\"(max-width: 343px) 100vw, 343px\" \/><figcaption>Struktur der Datenverbindungen der Web-App<\/figcaption><\/figure>\n\n\n\n<p>Aus der Abbildung ist zu entnehmen, wie der Informationsfluss innerhalb der Web-App grob funktioniert. Zu beachten ist hierbei, dass nur der Browser(Client) au\u00dferhalb der Azure Cloud liegt. Alle anderen Komponenten laufen in der Azure Cloud-Umgebung. Die Verbindung von der Cloud nach au\u00dfen wird \u00fcber einen WebSocket realisiert, welcher vom Web-App-Server ge\u00f6ffnet wird. Jeder neue Client verbindet sich automatisch mit dem WebSocket des Servers und kann somit \u00fcber diesen bidirektional kommunizieren.  <\/p>\n\n\n\n<p>Damit Daten im Browser angezeigt werden, gibt es zwei Arten der Datengewinnung. Dem Nutzer k\u00f6nnen durch die beiden Arten sowohl Live- als auch Historische-Daten der Hardwarekomponenten angezeigt werden.  <\/p>\n\n\n\n<p>Das Anzeigen der Live-Daten funktionieren so, dass sobald Daten von einer Hardwarekomponente an die Cloud, genauer an den Azure-Event-Hub verschickt werden, diese aus dem Event-Hub abgegriffen und an die Web-App weitergeleitet werden. Dies passiert indem eine Instanz eines iotHubReader, welcher auf dem Server der Web-App l\u00e4uft, den IoT Event-Hub \u00fcberwacht und auf eingehende Nachrichten der Hardwarekomponenten wartet. Wird eine Nachricht empfangen, wird diese als JSON-Objekt codiert und \u00fcber die broadcast Funktion an alle verbundenen Clients geschickt.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var iotHubReader = new iotHubClient(process.env['Azure.IoT.IoTHub.ConnectionString'], process.env['Azure.IoT.IoTHub.ConsumerGroup']);\niotHubReader.startReadMessage(function (obj, date) {\n  try {\n    console.log(date);\n    date = date || Date.now()\n    wss.broadcast(JSON.stringify(Object.assign(obj, { time: moment.utc(date).format('YYYY:MM:DD[T]hh:mm:ss') })));\n  } catch (err) {\n    console.log(obj);\n    console.error(err);\n  }\n});\n\n\/\/ Broadcast to all.\nwss.broadcast = function broadcast(data) {\n  wss.clients.forEach(function each(client) {\n    if (client.readyState === WebSocket.OPEN) {\n      try {\n        console.log('sending data ' + data);\n        client.send(data);\n      } catch (e) {\n        console.error(e);\n      }\n    }\n  });\n};<\/code><\/pre>\n\n\n\n<p>Die vom Server verschickte Nachricht wird vom Client \u00fcber die Funktion onmessage empfangen. Dort wird der Inhalt der Nachricht ausgewertet und in das entsprechenden Diagramme geladen. Die in diesem Projekt zum Anzeigen der Daten verwendeten Diagramme stammen von einem Open Source Projekt namens <a href=\"https:\/\/www.chartjs.org\/\">Chart.js<\/a>. Im folgenden ist ein Codebeispiel f\u00fcr den Temperatursensor und den Bewegungsmelder gegeben. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ws.onmessage = function (message) {\n    var messageObj = parseMesseage(message);\n\n    if(!messageObj.time &amp;&amp; !messageObj.temperature &amp;&amp; !messageObj.telegram) {\n      return;\n    }\n\n  if(messageObj.telegram){\n    switch (messageObj.telegram.friendlyId){ \n      \/*This is the temperature Sensor*\/ \n      case \"SmartMotionDetector_2\":\n        updateTempSensorChart(messageObj, TempSensor1Chart);\n        break;\n\n      case \"SmartMotionDetector_1\":\n        updateMotionDetectorChart(messageObj, MotionDetectorChart);\n        break;\n\n      default:\n        break;\n      }\n    } \n  }\n<\/code><\/pre>\n\n\n\n<p style=\"text-align:left\">Sind f\u00fcr den Nutzer die Live-Daten zurzeit nicht interessant, kann auf historische Daten zur\u00fcckgriffen werden. Hierf\u00fcr sendet der Client eine Anfrage \u00fcber den WebSocket, als JSON-Objekt verpackt, an den Server welcher in der Azure Umgebung l\u00e4uft. In dieser Anfrage stehen der Tabellenname, der Sensorname und die Anzahl der Datenpunkte welche angefordert werden sollen. Im folgenden ist der Code f\u00fcr die Anfrage an den Server f\u00fcr die Historischen-Daten des Temperatursensors zu sehen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function getTemperatureData(webSocket)\n  {\n    var request = \n    {\n      tableName : \"tabTemperatureSensor\",\n      friendlyId: \"SmartMotionDetector_2\",\n      amountOfDataPoints : 100\n    }\n    webSocket.send(JSON.stringify(request));\n  }<\/code><\/pre>\n\n\n\n<p>Sobald der Server die Anfrage erhalten hat, wird die Nachricht geparsed und der Server greift auf die Datenbank zu, um die geforderten Information abzurufen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>wss.on('connection', function connection(ws){\n  ws.on('message', function incoming(message){\n    message = JSON.parse(message);\n    const myQuery = new SQLQuery();\n    myQuery.on('done', async () => {\n      let myVar =  await myQuery.readTable(message.tableName,message.friendlyId,message.amountOfDataPoints);\n      console.log(\"Das sind die Daten aus der Tabelle\",myVar);\n      wss.broadcast(JSON.stringify(myVar));\n    });\n  });\n});<\/code><\/pre>\n\n\n\n<p>Nachdem die Informationen aus der Datenbank vorhanden sind, werden diese vom Server als JSON-Objekt verpackt und \u00fcber die broadcast Funktion an alle Clients verschickt. Der Client der die Anfrage gestellt hat parsed die Nachricht und f\u00fcgt die Informationen dem passenden Diagramm hinzu.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>webSocket.onmessage = function(message){\n    parsedMessage = JSON.parse(message.data);\n    if(!(parsedMessage === undefined)){\n      if(!parsedMessage.telegram){\n        if(parsedMessage[0].value == \"SmartMotionDetector_2\"){\n          if(!tempSensorHisotoryFinsihed){\n            updateTemperatureSensoreChart(parsedMessage,TempSensor1Chart);\n            tempSensorHisotoryFinsihed = true;\n          }\n        }else if(parsedMessage[0].value == \"SmartMotionDetector_1\"){\n          if(!motionSensorHisotoryFinsihed){\n            updateMotionDetectorChart(parsedMessage, MotionDetectorChart);\n            motionSensorHisotoryFinsihed = true;\n          }\n        }\n      }\n    }\n  };<\/code><\/pre>\n\n\n\n<p>Eine direkte Anfrage vom Browser an die Datenbank ist nicht m\u00f6glich und auch nicht vorgesehen. Der Browser w\u00fcrde hierf\u00fcr die Einlogdaten der Datenbank ben\u00f6tigt und diese somit f\u00fcr jeden, der die Website aufruft, einsehbar machen. Dies muss vermieden werden. Der Weg \u00fcber den Server ist somit n\u00f6tig, um die Sicherheit der Datenbank zu gew\u00e4hrleisten. Unautorisierte Anfragen von Dritten k\u00f6nnen durch diesen Weg ausgeschlossen werden. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Allgemein Mit Hilfe des Azure App Service bietet sich die M\u00f6glichkeit ein auf die eigenen Bed\u00fcrfnisse abgestimmtes Frontend (Website oder Webanwendung) mit verschiedensten Funktionen zu implementieren. Ein weiterer Vorteil dieses Services besteht darin, dass er sich beliebig skalieren l\u00e4sst und die komplette Infrastruktur von Azure bereitgestellt wird. Dieser Service wurde bei diesem Projekt genutzt, um &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/azure.teamprojects.de\/?page_id=1190\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eAzure Web-App\u201c<\/span> weiterlesen<\/a><\/p>\n","protected":false},"author":100,"featured_media":0,"parent":671,"menu_order":30,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"_links":{"self":[{"href":"https:\/\/azure.teamprojects.de\/index.php?rest_route=\/wp\/v2\/pages\/1190"}],"collection":[{"href":"https:\/\/azure.teamprojects.de\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/azure.teamprojects.de\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/azure.teamprojects.de\/index.php?rest_route=\/wp\/v2\/users\/100"}],"replies":[{"embeddable":true,"href":"https:\/\/azure.teamprojects.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1190"}],"version-history":[{"count":123,"href":"https:\/\/azure.teamprojects.de\/index.php?rest_route=\/wp\/v2\/pages\/1190\/revisions"}],"predecessor-version":[{"id":1496,"href":"https:\/\/azure.teamprojects.de\/index.php?rest_route=\/wp\/v2\/pages\/1190\/revisions\/1496"}],"up":[{"embeddable":true,"href":"https:\/\/azure.teamprojects.de\/index.php?rest_route=\/wp\/v2\/pages\/671"}],"wp:attachment":[{"href":"https:\/\/azure.teamprojects.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1190"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}