Fejlesztői dokumentáció II. Web - adipapp/Raspberry GitHub Wiki

Bevezetés, célok

Egy komplex szenzorikai méréseket megvalósító szoftver megalkotása volt a célunk, amelynek segítségével minimális informatikai háttértudás mellett - elsősorban az általános és középiskolás diákok számára - is lehet érdekes és hasznos fizikai méréseket végezni a Raspberry PI szenzoraival.

Ennek megvalósítására készítettünk egy elsősorban frontend alapokra épülő webes felületet, amely a felhasználói interakcióért, a mérési paraméterek feldolgozásáért illetve Raspberry-nek való küldéséért, és részben az adatmegjelenítésért felelős.

Azért döntöttünk a frontend web technológiák mellett, mert célunk a minél egyszerűbb és kézenfekvőbb használat megvalósítása volt. Így egyszerű böngészőablakból, mindenféle külső program vagy szoftver elindítása nélkül lehet használni, illetve a backend kód minimalizálásával pedig a szükségtelen oldal újratöltések és http kérések elkerülhetővé válnak.

A Raspberry ezen felül mint szerver is funkcionál web, illetve mail szerepkörökkel.

Ezen dokumentációban bemutatásra kerül a kliens oldali web interfész fejlesztői szemszögből, illetve az összes olyan szerver oldali hálózati technológia illetve backend kód, amelyet felhasználtunk munkánk során.


Feladatleírás, követelmények

A kliens oldali web interfésszel szemben támasztott részletes követelmények, ellátandó funkciók listája:

  • felhasználó üdvözlése
  • a mérési paraméterek beállítása, úgy mint:
    • szenzor típusa
    • mérési frekvencia
    • mérési időtartam
  • fenti paraméterek beállítása után a mérés indítása, azaz adott paraméterekkel kérés küldése a szervernek
  • nyers mérési adatok megjelenítése listás formában
  • sokrétű vizuális adatmegjelenítés html-be ágyazott Geogebra programmal
  • a mérési adatok táblázatos formában, email csatolmányként való elküldés lehetőségének biztosítása
  • valamilyen hiba esetén a felhasználó megfelelő tájékoztatása

A Raspberry-vel mint szerverrel szemben támasztott követelmények:

  • web szerverként, az interfész weboldalainak hosztolása
  • backend kód futtatása
  • smtp mail kliensként, a mérési adatfájl küldése emailben

Környezet, szükséges csomagok, programok

Működési/tesztelési környezet:

  • HW: Raspberry PI B3+
  • OS: Raspbian Stretch 4.14
  • Browser: Chromium 1.0.154.65

Fejlesztői környezet:

  • OS: Windows 10 Home
  • IDE: Visual Studio 2017

Az összes kód és egyéb fájl 100%-ban platformfüggetlen.

Szerver részére a szükséges csomagok:

  • apache2
  • libapache2-mod-php7.0
  • php7.0
  • postfix
  • sendemail
  • libsasl2-modules

Architektúra

Architekturális felépítés

A fenti ábrán projektünk architektúrájának szemléltetése látható. A kliens oldalon a HTML, CSS és pure JavaScript alkotta webes interfész fut a böngészőben, amelyet a Raspberry-n egy Apache webszerver hosztol.

Amennyiben a felhasználó interakciót kezdeményez a szerverrel, például mérést indít, a kliens(egész pontosan a JavaScript) egy HTTP kérést küld az Apache szervernek az AJAX technológiának megfelelően.

A HTTP kérés mindig egy PHP szkriptre irányul, amely meghívásakor elindítja a megfelelő szenzorhoz tartozó Python szkriptet, emailt küld, adatot olvas, feladata sokrétű, de a backend kód mennyisége - lehetőségekhez mérten - minimalizálva lett. Azaz a PHP egyfajta hídként vagy összekötőként működik a szerver hardverét közvetlen használó és vezérlő Python szkriptek(valamint az email küldést végző Postfix) és a kliens böngészőjében a felhasználóval kapcsolatot tartó JavaScript között.


A webes interfész felépítése

A webes interfész hierarchikus könyvtárstruktúrába szervezett fájlok gyűjteménye. A fájlok aloldalanként külön könyvtárban kaptak helyet a DocumentRoot-ban:

  • welcome:

    az üdvözlőképernyő fájljai

  • main:

    a fő, mérésvezérlő oldal fájljai

  • geogebra:

    a geogebra beágyazásához szükséges fájlok(a GeoGebra nevű alkönyvtárban a GeoGebra 6, és API-jának fejlesztői oldaláról letöltött fájljai találhatóak)

  • error:

    egy fallback hibajelző oldal arra az esetre, ha valamely kért aloldal nem található vagy valamilyen okból nem tölthető be

  • img:

    itt találhatóak a felhasznált fényképek, ábrák

Minden aloldalhoz tartozik egy, az oldal nevével megegyező fájlnevű .html oldal, egy .css stíluslap, illetve egy vagy több .js JavaScript, valamint .php fájl. A teljesség igénye nélkül, ezek közül néhány fontosabb bemutatása:

  • main/main.js

    Ebben elsősorban a megjelenítést és az oldal vezérlőit működtető kódok kaptak helyet, illetve az email küldésének php szkriptje is innen hívódik meg.

  • main/runScript.js

    A felhasználó által bevitt mérési paraméterek validálása, kiolvasása, illetve a Python mérőszkriptet indító PHP fájl hívása. Ez AJAX technológiával GET módszerrel történik, paraméterlistaként a mérési paraméterek átadásával. Mivel a PHP fájl nem töltődik be az oldalra, hanem a háttérben fut és egy echo 'OK' üzenetet vagy hibát küld csak vissza, amelyet a JS értelmez, így az oldal újratöltése nem szükséges.

  • main/get.php

    Ez végzi a szükséges Python szkriptek indítását. Mindezt az exec('_command_') metódussal teszi, amely a szerver parancssorához hozzáférve, a neki paraméterként átadott parancsot futtatja, annak kimenetét padig visszaadja.

  • main/sendmail.php

    Az email küldését végzi a kapott paraméterek alapján, a fent leírt exec metódus segítségével.

Emellett a DocumentRoot-ban helyet kapott a felhasznált betűkészlet fájlja, amely innen töltődik be, kivédendő azt az esetet ha a kliens nem rendelkezik vele(franklin-gothic.ttf), így az oldal megjelenése minden kliens esetén egységes marad.

Illetve minden könyvtárban található egy .htaccess fájl, amely az Apache szerver részére, könyvtáranként testre szabható konfigurációt biztosít.


Adatok tárolása, szerializáció

A mért adatok tárolása .xlsx formátumban történik a későbbi, minél széles körűbb felhasználói hasznosítás miatt. A GeoGebra ezt nagyon könnyedén tudja feldolgozni, de Excelben is sok műveletet hajthatunk végre az adatokon.

De mivel ez egy bináris formátum, a JS-nek pedig(legjobb tudásunk szerint) nincs API-ja ezt olvasni, ezért ezzel párhuzamosan egy ideiglenes .txt fájlba is kiírásra kerülnek az adatok. A mérés végeztével ezt az ideiglenes fájlt a JS elkéri a szervertől, amelyet parse-ol és listás formában megjeleníti az adatokat a fő oldalon. Új mérés esetén a régi .txt fájl íródik felül, így felesleges adattal nem szemeteljük tele a szervert. A listás formátumú adatok vágólapra másolhatóak, és a GeoGebra beágyazott felületébe illeszthetőek további felhasználásra.

Az .xlsx fájl pedig emailben elküldhető, így a felhasználó a mérési adatait egyszerű és kézenfekvő módon el tudja magának juttatni, és azokat a továbbiakban felhasználni.


Webszerver, és mail kliens beállítása

Apache, mint webszerver

A Raspberry-n egy Apache web szerver felel a webes kezelőfelület oldalának hosztolásáért. Ehhez a fent említett szükséges csomagok feltelepítése után egy VirtualHost került létrehozásra a szerveren. A szerver maga az összes IP címén fogadja a 80-as TCP porton a HTTP kéréseket, elsősorban a raspberry.local URL-en, de a *.raspberry.* Alias is felvételre került, így tetszőleges TLD-vel, illetve aldomain-nel küldött kérést is ki tud szolgálni.

Alapvetően a HTTP kérések a localhost-ról fognak a szoftver használata során beérkezni, ezért is döntöttünk elsődlegesen ennek a lokális URL-nek a használata mellett. Emiatt a /etc/hosts fájlban felvételre került a raspberry.local mint domain-név, így az OS a localhost IP címére fogja a fenti domain-t feloldani.

De természetesen a lehetőség adott a helyi hálózat más gépéről, vagy akár távoli alhálózatból is a szerverhez való csatlakozásra így a mérések vezérlésére. Ehhez természetesen megfelelő DNS rekordok felvétele szükséges egy kliens számára elérhető DNS szerveren, illetve esetlegesen publikus IP cím megléte.

A VirtualHost konfigurációs szintén természetes a DocumentRoot megfelelően beállításra került, továbbá hozzáférést biztosítottunk az Apache számára ehhez a könyvtárhoz a Directory direktíva segítségével, ennek konfigurációs részlete látható az alábbi ábrán, amely a /etc/apache2/sites-available/raspberry.conf fájlban található:

<Directory "/var/www/raspberrypiszenzor/web">

  Allow from all
  Require all granted
  FallbackResource "/error_page.html"
  AllowOverride All

</Directory>

Látható, hogy az alapvető használati jogosultságok megadása mellett engedélyezve lett az AllowOverride direktíva, amely lehetővé teszi hogy .htaccess fájlokkal a globálisabb VirtualHost szintű beállításokat a szűkebb, könyvárszintű beállítások felülírhassák. Így minden .htacces fájlban könyvtáranként beállítható a DirectoryIndex direktívával hogy ha az adott könyvtárra érkezik kérés a szerverhez, akkor a default beállítások szerinti index.html és index.php fájlok helyett mely fájlokat használja mint indexlap. Így a HTTP kérések esetén nem szükséges definiálni fájl szintig az URL-t, elég a tartalmazó könyvtár szintjéig megadni, a megfelelő fájl betöltését pedig .htaccess fájl elvégzi. Így elrejthető az oldalak konkrét fájlneve, de akár jelszavas autentikáció vagy más biztonsági mechanizmusok is alkalmazhatóak a .htaccess fájlokkal.

Emellett a FallbackResource direktívával egy saját default error lap is beállításra kerül, amelyről már esett szó(de akár ez is könyvtárszinten más és más lehet .htaccess használatával) így valamely fájl hiba vagy elérhetetlenség esetén a felhasználó nem ijesztő böngésző hibaüzenetet, hanem egy barátságos hibajelző weboldalt lát.

Végül megjegyzendő, hogy mivel az Apache működése és a kérések kiszolgálása során a PHP szkriptek részére hozzáférést szeretnénk biztosítani a szerver parancssorához, így az Apache user-nek - amely user jogosultságaival tudunk Apache-on keresztül hozzáférni a szerveren bármihez alapértelmezés szerint - sudo jogosultságot kell adnunk, jelszókérés mellőzésével. Ezt a /etc/sudoers fájlban az alábbi sor hozzáadásával tudjuk megtenni:

www-data All=(ALL) NOPASSWD:ALL

Postfix, mint parancssoros email kliens

Az mérési jegyzőkönyv elküldésére, mint parancssoros SMTP kliens a Postfix-re esett választásunk, amelyen a későbbiekben akár saját email szervert is beállíthatunk.

Az csomagok telepítése után a /etc/postfix/main.cf fájlban a külső email kiszolgáló domain-je(esetünkben smtp.gmail.com) és portszáma(esetünkben a TCP 587) megadása után, szükséges a fiókunkhoz való jogosultságok beállítása. Ezt a libsasl2-modules csomag jogosultság kezelőjével érjük el, mivel biztonsági okokból TLS hitelesítést használunk. Ehhez szükséges a username password párost és náhány alapadatot tartalmazó /etc/postfix/sasl_passwd és /etc/postfix/sasl_passwd.db fájlok létrehozása és a /etc/postfix/main.cf fájl végéhez az alábbi direktívák hozzáfűzése:

smtp_sasl_auth_enable = yes

smtp_sasl_security_options = noanonymous

smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

smtp_use_tls = yes

smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt

Az emailek küldését pedig a sendemail csomag, sendemail parancsának megfelelő kapcsolói és paraméterezése segítségével végezzük.

⚠️ **GitHub.com Fallback** ⚠️