Sensor Aggregation in Netzwerken und Applikation (1) (PD Stefan Bosse) [12.2023]

HTTP WEB Sensor Monitor

HTTP WEB Sensor Monitor
Das Konzept
Die Plattformen
Eine LuaOS Thread Prozess erzeugen
Die Sensoren
GEO Location
Der Server
HTTP
HTML
HTTP Sensor Server
Der Klient
Sensoren
HTTP

In dieser Übung soll ein erster Prototyp eines Sensor Monitors programmiert werden der über einen Web Service verfügt (Aggregation und Applikation).

Das Konzept

Die Plattformen

  1. Natives LuaOS ausgeführt von lvm (LuaJit+Luv+AsyncIO) mit dem LuaOS und einem Web API Service (wird hier verwendet)
  2. Eingebettetes LuaOS ausgeführt im Web Browser, basierend auf der Fengari JavaScript Implementierung von Lua (wird hier auch verwendet).
terminal> lvm luaos

Linux: Optional ./lvm in dem Verzeichnis ausführen wo lvm gespeichert wurde da es schon ein Systemprogramm lvm gibt!

LuaOS im Web Browser und in der nativen Plattform sind nahezu identisch in der API.

Wichtig. Das Notebook muss entweder via http (nicht https) oder lokal vom Dateisystem in der Web Browser geladen werden, sonst funktioniert die verbinung zur lvm Instanz nicht. Immer die aktuelle Version von lvm und LuaOS verwenden.

Eine LuaOS Thread Prozess erzeugen


LuaOS Thread auf externer lvm starten (oder stoppen)

LusOS LVM Thread Controller #0
 ▸ 
 ◼ 

Die Konsolenausgaben der externen Ausführung von Code sind hier zur besseren Unterscheidbarkeit rot umrandet.

Die Sensoren

GEO Location

Der erste wichtige Sensor ist die georäunmliche Position. Diese kann mittels GPS Sensorik (< 10 m Genauigkeit) oder mittels der Internet IP Adresse (> 1 km Genauigkeit) bestimmt werden.

Beispiel GEO Location

 ▸ 
 ✗ 
 ≡ 

Der Server

Es soll ein einfacher HTTP Server gebaut werden der mittels eines HTTP basierten RPC Protokolls Sensordaten von Sensorknoten empfängt und diese in einem weiteren WEB HTTP-HTML Service textuell darstellt. Also zweimal HTTP mit dem gleichen IP Port:

  1. Sensor RPC HTTP Port 22223 unter Verwendung der PUT/POST HTTP Operation (Methode)
  2. WEB Seiten Server mit HTTP Port 22223 unter Verwendung der GET HTTP Operation wie sie von jdem WEB Browser ausgeführt wird

HTTP

LusOS bietet die http Klasse um einen HTTP Server zu erzeugen (nur native Plattform, im WEB Browser nicht möglich/verfügbar):

local hs = http:new()
hs:service(hostip, ipport, function (method,url,peername,params,body)
  ...
  return response -- Text!
end)

Die Parameter des HTTP Request Handlers:

Beispiel eines minimalen HTTP Servers (im Browser testen mit z.B. http://127.0.0.1:22223)

 ▸ 
 ✗ 
 ≡ 

Ein HTTP/TCP IP Port kann nur einmal belegt werden. Startet man einen zweiter Server auf dem gleichen Port gibt es einen Fehler. Wird der Server Handler überarbeitet einfach den Thread Prozess stoppen und dann wieder neu starten.

HTML

Einfache HTML Seiten können mit der LuaOS html Klasse erzeugt werden:

local H = html:new()
local htmltext = H:html(
  H:head(),
  H:body({
    H:h1("text"),
    H:h2("text"),
    H:p("text"),
    H:ol({
      H:li("text"),
      H:li("text"),
      ..
    }),
    H:table({
      { "text", "text", .. },
      { "text", "text", .. },
      ...
    })
  })
)
Beispiel der Erzeugung einer HTML Seite

 ▸ 
 ✗ 
 ≡ 

HTTP Sensor Server

Aufgabe. Server Programm
  1. Erstelle zunächst einen einfachen "Hello World" WEB Server der auf eine GET Anfrage eine elementare HTML Seite mit dem Text "Hello World" mit dem aktuellen Datum liefert (date()).

Im nächsten Schritt soll ein Sensor Service programmiert werden der folgende Aufgaben erfüllen soll:

  1. Alle eingehenden Sensordaten (über PUT Request) im Format {sensor:string,time:number, data:string,unit:string} sollen in einer dynamisch wachsenden Tabelle eingbaut werden. Wenn das Sensordatenrekord keinen Zeitstempel enthält muss im Server einer hinzugefügt werden. Die (Lua) Tabelle enthält direkt die emfpangenen Sensordatenrekords.

  2. Es soll eine Coroutine geben die in periodischen Abständen alte Einträge entfernt (Zeitstempel verwenden). Der Timeout soll konfigurierbar sein.

  3. Es sollen Mittelwerte aktueller Sensordaten berechnet werden (nur numerische Sensoren wie Geo/GPS) oder Verteilungen bei kategorischen Werten (siehe 6.). Der Geo Sensor liefert eine Tabelle mit numerischen lon und lat Feldern. Wichtig: Die Sensordaten werden im JSON Textformat übertragen und müssen in ein Lua Datentyp mittels JSON.decode(textdata) konvertiert werden.

  4. Der Server soll eine dynamische HTML Seite erzeugen die alle Sensoreinträge als HTML Tabelle listet und eine weitere Tabelle mit Sensormittelwerten (+ Standardabweichung der Werte) oder bei kategorischen Werten eine Verteilung

  5. Es soll aus dem Agententext das Betriebssystem (Linux, Windows, MacOS) und die Plattform (Browser/lvm) mit String Funktionen LUA Strings und LUA String Operationen sowie LUA Patterns bestimmt und als eigenständige Sensor eingetragen werden.


Die Programmierung erfolgt hier!

Programmcode Server: Initialisierung

 ▸ 
 ✗ 
 ≡ 

Programmcode Server: HTML Formatter

 ▸ 
 ✗ 
 ≡ 

Programmcode Server: Table Management

 ▸ 
 ✗ 
 ≡ 

Programmcode Server: Main Service Loop

 ▸ 
 ✗ 
 ≡ 

Der Klient

Sensoren

Jeder Sensorknoten ist ein Klient der Sensorservices (Server) und kann auf eigene Sensoren über die generische Sensorklasse zugreifen. Dabei stehen je nach Plattform verschiedene Sensorunterklassen zur Verfügung die mittels der sensor:all Methode abgefragt werden können. Im WEB Browser werden es nur wenige sein, u.A. geo der die GPS Koordinaten des Standortes über die IP Adresse liefert (sehr ungenau) sowie agent der Informationen über die Plattform als String ausgibt. Ein Sensor muss von der generischen Klasse durch s=sensor:new("class") erzeugt werden:

Verfügbare Sensoren testen (hier Browser Lua)

 ▸ 
 ✗ 
 ≡ 

Zum Vergleich: Verfügbare Sensoren testen (hier externer lvm Lua Knoten)

 ▸ 
 ✗ 
 ≡ 

Ein Sensor muss i.A. gestartet werden (genauer das periodische Sampling). Mittels der s:read() Methode wird der aktuelle Wert gelesen. Dieser kann aus einem bereits erfolgten Samplingvorgang stammen (z.B. in einer Smartphone App) oder direkt erfasst werden.

local geo1 = sensor:new("geo")
geo1:start()
sleep(1000) -- Die initiale Geo Erfassung dauert eine kurze Zeit
local sample = geo1:read()
print(sample)

Der Klient wird hier direkt im Web Browser laufen!

HTTP

Ein HTTP PUT Request kann über die http Klasse erzeugt werden:

local hc = http:new()
local url = "localhost:22223"
local data = { sensor="test",time=time(), data=0, unit="integer" }
local response,header,error = hc:put(url,JSON.encode(data))
Beispiel HTTP PUT/POST Request zu einem externen Server (Internet)

 ▸ 
 ✗ 
 ≡ 

Beispiel HTTP GET Request zu einem externen Server (Internet)

 ▸ 
 ✗ 
 ≡ 

Der Sensor Server muss natürlich zuerst auf der lvm gestartet werden (siehe oben)!

Der HTTP PUT Request liefert eine (textuelle) Rückantwort des Servers (hier z.B. einfach "OK").

Aufgabe. Klientenprogramm
  1. Zwei Sensoren sollen ausgelesen werden: agent und geo.

  2. Die Sensorwerte sollen (einmalig) zum Sensor Server im JSON Format gesendet werden (JSON.encode(request)). Dabei ist ein Sensordatenwert eine Lua Tabelle {sensor:string, time:number, data:table|string|number, unit:table|string} die im JSON Format übertragen wird. Das Feld sensor enthält den Klassennamen des Sensors.

  3. Teste die Ausgabe der Sensoren im Klientencode und dann nach der Versendung auf dem Server über das WEB Interface

    • Wie unterscheiden sich die Sensorwerte geo und agent in LuaVM.js und lvm?

Programmcode Klient

 ▸ 
 ✗ 
 ≡ 



Hilfe



Einreichung (Assignment #03-42221)



Prüfen



Bewerten (Lehrer)




Created by the NoteBook Compiler Ver. 1.27.0 (c) Dr. Stefan Bosse (Sat Jan 27 2024 13:12:27 GMT+0100 (CET))