Documente Academic
Documente Profesional
Documente Cultură
Proiect de diplomă
prezentat ca cerinţă parţială pentru obţinerea titlului de
Inginer în domeniul Electronică şi Telecomunicaţii
programul de studii de licenţă program Reţele şi Software de
Telecomunicaţii
2017
Anexa 6
LISTA TABELELOR................................................................................................................................ VI
JUSTIFICARE ............................................................................................................................................ 1
INTRODUCERE ........................................................................................................................................ 3
i
3.1.2 Socket-uri ...................................................................................................................................................18
3.2 Componenta frontend - interfața cu utilizatorul (HTML, JavaScript) 18
3.2.1 HTML ..........................................................................................................................................................19
3.2.2 JavaScript ...................................................................................................................................................19
3.3 Componenta backend - data access layer (php , nodejs) 20
3.3.1 PHP .............................................................................................................................................................21
3.3.1.1 Generarea dinamică a conținutului ....................................................................................................22
3.3.1.2 Convertirea unor caractere in entitati HTML .....................................................................................22
3.3.1.3 Criptarea șirurilor de caractere ..........................................................................................................22
3.3.1.4 Utilizarea datelor introduse in formularele HTML .............................................................................22
3.3.1.5 Gestionarea sesiunilor in PHP.............................................................................................................23
3.3.1.6 Crearea sesiunilor ...............................................................................................................................23
3.3.1.7 Variabilele de sesiune .........................................................................................................................23
3.3.2 Node.js .......................................................................................................................................................24
3.4 Baza de date (MySQL) 25
3.4.1 Conectarea la server și selectarea bazei de date .......................................................................................26
3.4.2 Interacțiunea cu bazele de date utilizând PHP ..........................................................................................27
3.4.3 Transmiterea interogărilor către baza de date ..........................................................................................28
3.4.4 Inchiderea conexiunii .................................................................................................................................29
3.4.5 Extragerea datelor în urma unei interogări ...............................................................................................29
3.4.6 Câteva probleme de securitate a bazelor de date .....................................................................................29
3.5 Design și ergonomie (css) 30
3.5.1 Limbajul CSS ...............................................................................................................................................30
ii
5.1.4 Securitatea in LoRaWAN ............................................................................................................................39
5.2 Programarea interfeței 40
5.2.1 Implementarea unui formular de inregistrare ...........................................................................................40
5.2.2 Implementarea unui formular de autentificare (login) ..............................................................................43
5.2.3 Crearea unui modul de schimbare a parolei/ a email-ului.........................................................................44
5.3 Scheletul platformei web 45
5.3.1 Adăugarea unui senzor ..............................................................................................................................48
5.3.2 Editarea unui senzor ..................................................................................................................................50
5.3.3 Eliminarea unui senzor ...............................................................................................................................51
5.3.4 Grupuri .......................................................................................................................................................52
5.4 Backend și tratarea alertelor în soluția propusă 54
5.4.1 Scenariul apariției unei alerte și tratarea acesteia.....................................................................................54
5.4.2 Afișarea alertelor în browser .....................................................................................................................56
5.4.3 Stocarea alertelor ......................................................................................................................................57
5.4.4 Trimiterea alertelor pe email .....................................................................................................................59
5.4.5 Grafice și notificări .....................................................................................................................................61
ANEXA 1 .................................................................................................................................................. 69
iii
Lista figurilor
Fig. 1 Detector portabil de gaz (sursa:[ 16 ] ) ................................................................................. 6
Fig. 2 Detectoare de gaz fixe (sursa: [ 17 ]).................................................................................... 7
Fig. 3 Pelistor cu protecție de oțel inoxidabil (sursa: [ 20])........................................................... 7
Fig. 4 Detector cu fotoionizare (sursa: [ 22]) .................................................................................. 8
Fig. 5 Detector de gaz cu infraroșu (sursa: [ 25]) ........................................................................... 8
Fig. 6 Chip cu senzor cu semiconductori (sursa: [ 28]) .................................................................. 8
Fig. 7 Detector ultrasonic de gaze (sursa: [ 30 ] ) ........................................................................... 9
Fig. 8 Arhitectura unui sistem de monitorizare (sursa: [ 35] ) ...................................................... 12
Fig. 9 Centrală de alarmă (sursa: [ 36]) ....................................................................................... 12
Fig. 10 Dispozitiv de avertizare cu sirenă și lumini (sursa: [ 36]) ............................................... 13
Fig. 11 Panou de control (sursa:[ 36] ) ........................................................................................ 13
Fig. 12 Algoritmul de procesare a mesajelor de alarmare de la stațiile locale ............................. 14
Fig. 13 Monitorizarea sistemlor de alarmă de la distanță (sursa: [ 42 ]) ..................................... 16
Fig. 14 Arhitectură simplificată a unei aplicații web .................................................................... 17
Fig. 15 Etapele de funcționare a unui cod JavaScript (sursa: [ 53 ]) ............................................ 20
Fig. 16 Pornirea modulelor necesare Apache și MySQL ............................................................. 26
Fig. 17 Specificații ale serverului MySQL ................................................................................... 26
Fig. 18 Baza de date "login" folosită în lucrare, și tabelele componente ..................................... 27
Fig. 19 Componentele tehnologiei pe niveluri .............................................................................. 32
Fig. 20 Arhitectură unei rețele LoRaWAN (adaptare după : [ 63 ]) ............................................. 33
Fig. 21 Exemplificarea firului de execuție al autentificării .......................................................... 36
Fig. 22 Mesajele afișate în consolă în urma procesului de autentificare ...................................... 37
Fig. 23 Structura unui modul local pentru detecția scurgerilor de gaz ......................................... 37
Fig. 24 Rate LoRaWAN de transmisie a datelor. (sursa : [ 67 ] )................................................. 39
Fig. 25 Formular de înregistrare ................................................................................................... 40
Fig. 26 Tabela "user" .................................................................................................................... 40
Fig. 27 Procesul de autentificare ................................................................................................... 43
Fig. 28 Formular de autentificare.................................................................................................. 44
Fig. 29 Formular schimbare parolă/e-mail.................................................................................... 44
Fig. 30 Pagina de start a platformei .............................................................................................. 46
Fig. 31 Captură din pagina principală ........................................................................................... 46
v
Fig. 32 Pagina principală a platformei .......................................................................................... 47
Fig. 33 Submeniuri ale "Manage sensors" .................................................................................... 47
Fig. 34 Fereastra de adăugare a unui senzor ................................................................................. 48
Fig. 35 Tabela "sensor" ................................................................................................................. 50
Fig. 36 Pagina de editare a unui senzor ........................................................................................ 50
Fig. 39 Afișarea grupurilor existente ............................................................................................ 52
Fig. 37 Ștergerea unui modul ........................................................................................................ 52
Fig. 38 Formular pentru managementul grupurilor ...................................................................... 52
Fig. 41 Conținutul și structura tabelei sgroup ............................................................................... 53
Fig. 40 Meniul de navigare ........................................................................................................... 53
Fig. 42 Conținutul și structura tabelei sensor_group .................................................................... 54
Fig. 43 Diagrama pentru scenariul de transmitere a alarmei ........................................................ 54
Fig. 44 Pagina principală cu alerta de gaz .................................................................................... 57
Fig. 45 Tabela alert și structura sa ................................................................................................ 57
Fig. 46 Configurare server email .................................................................................................. 60
Fig. 47 Email cu notificare alertă .................................................................................................. 61
Fig. 48 Notificări ........................................................................................................................... 61
Fig. 49 Grafic număr de alerte în funcție de senzor ...................................................................... 63
Fig. 50 Selectarea unui senzor și vizualizarea momentelor de alertă ........................................... 63
Lista tabelelor
Tab. 1 Tabel comparativ între tipuri de rețele: ............................................................................ 34
Tab. 2 Determinarea prin simulare a numărului de coliziuni și a erorii de bit pentru un gateway
LoRa .............................................................................................................................................. 38
vi
Lista acronimelor
ADSL - Asymmetric Digital Subscriber Line
AES - Advanced Encryption System
AERS - Alarms and Events Reception System
AJAX - Asynchronous JavaScript And XML
ANRE - Autoritatea Națională de Reglementare în domeniul Energiei
API - Application Program Interface
AppEUI - Application Identifier
AppSKey - Application Session Key
ASP - Active Server Pages
BCC - Blind Carbon Copy
CC - Carbon Copy
CSS - Cascade Style Sheets / Chirp Spread Spectrum
DevAddr - End Device Address
DevEui End - Device Identifier
DB - Database
DNS - Domain Name Server
FAQ - Frequently Asked Questions
GUI - Graphical User Interface
GPRS - General Packet Radio Services
GSM - Global System for Mobile Communications
HTML - Hypertext Markup Language
HTTP - Hypertext Transfer Protocol
HOKLAS - Hong Kong Laboratory Accreditation Scheme
IBM - International Business Machines
IEEE EUI64 - Institute of Electrical and Electronics Engineers 64-Bit Extended Unique Identifier
IIS - Internet Information Services
IoT - Internet of Things
IP - Internet Protocol
IMAP - Internet Message Access Protocol
ISM - Institute for Supply Management
ISO - International Organization for Standardization
JSON - JavaScript Object Notation
LAN - Local Area Network
LoRa - Long Range
LoRaWAN - Long Range Wide Area Network
LPWAN - Low Power Wide Area Network
M2M - Machine to machine
MAC - Medium Access Layer
MD5 Message-Digest Algorithm 5
MX - Mail Exchange
NwkSKey - Network Session Key
OTAA - Over The Air Autenthication
PHP - PHP: Hypertext Preprocessor
PER - Packet Error Rate
PERL - Practical Extraction and Report Language
POP3 - Post Office Protocol
PPS - Pulse Per Second
QoS - Quality of Service
vii
RNMCA - Reteaua Naţională de Monitorizare Automată a Calităţii Aerului
SGBD- sistem de gestiune a bazelor de date
SMTP - Simple Mail Transfer Protocol
TCP/IP - Transfer Control Protocol/ Internet Protocol
URL - Universal Resource Locator
VPN - Virtual Private Network
W3C - Consorțiul World Wide Web
XAMPP - cross-platform, Apache, MySQL,PHP, Perl
XHR - XMLHttpRequest
viii
Justificare
Tehnologia s-a dezvoltat în ritm accelerat în ultima vreme, aplicațiile internetului pătrunzând în
cele mai neașteptate locuri. Tot mai multe inovații, menite să ușureze sau să creeze o viață mai
sigură, utilizează conexiunea la internet pentru transfer de informații, culegere de date,
avertizare, informare etc. Alături de internet, un aport deosebit la această expansiune tehnologică
îl au comunicațiile mobile de voce și date. Acoperirea rețelelor de comunicații mobile în
standardul GSM nu mai este acum o problemă, dimensiunea mică a celulelor și puterile reduse,
necesare la emisie a stațiilor mobile fiind atu-uri pentru densități fără precedent ale
echipamentelor de culegere a datelor și aplicațiilor mobile din teren.
După atingerea, în anul 2011, a limitelor versiunii IPv4, noi orizonturi au fost deschise pentru
extinderea entităților conectate la internet. Astfel, conceptul IoT (Internet of Things) a adus cu el
posibilitatea de a crea medii controlabile de la distanță, autonome, programabile sau care să se
comporte într-un anumit mod, bazat pe o comandă a unei inteligențe artificiale.
La nivel european, numeroase proiecte de cercetare din cadrul programelor cadru recomandate
de UE sunt orientate către dezvoltarea de soluții "verzi", prin economisire de energie, protecția
mediului în conceptul unificat de "smart city". Au fost lansate spre consultare publică ghiduri și
informații sau recomandări privind bunele practici internaționale, soluțiile și tehnologiile
inteligente aplicabile la nivel local și regional, care pot transforma comunitățile în orașe
inteligente, cu acces liber la produse și servicii de calitate, cu sisteme de sănătate și educație
moderne și cu administrații publice transparente, ce pot chiar guverna împreună cu cetățeanul.
1
Astfel de proiecte nu au întârziat să apară și în România, prin implicarea Ministerului
Comunicațiilor și pentru Societatea Informatională, ce a lansat Dezbaterea Publică de idei cu
tema „SmartCity Romania”. Numărul orașelor românești care și-au anunțat intenția de a accede
la statutul de Smart City crește rapid. Numai în ultimele luni, lista s-a îmbogățit cu Oradea,
Constanța și Alba Iulia, proiect care va fi prezentat în cadrul expo-conferinței naționale "Smart
Cities of România 2016". Dar, deși numărul "pretendenților" crește constant, prezența României
în clasamentele internaționale ale orașelor inteligente este încă una modestă. În vederea
promovării și implementării conceptului de smart city, s-a făcut apel la implicarea atât a
entităților din domeniul comunicațiilor cât și la cetățeni pentru a contribui cu idei, soluții,
recomandări, cerințe ce vor fi concretizate sub formă unui ghid de prezentare.
Ținând cont de cele de mai sus, tematica aleasă pentru proiect este modernă, oportună și
îndreptată către siguranța vieții omului. Proiectul își propune investigarea celor mai moderne
soluții pentru culegerea de date, conectivitate și ergonomie în exploatare, pentru realizarea unei
soluții de detecție a gazelor bazată pe tehnologii web și comunicații LoRaWAN.
2
Introducere
Siguranța personală și cea a familiei reprezintă probleme de interes prioritar în cele mai diferite
situații. Sunt binecunoscute accidentele datorate scurgerilor de gaze, ca și efectele devastatoare
pe care acestea le pot produce. Emanațiile de gaze pot provoca explozii sau incendii, punând nu
numai locatarii în pericol, ci și integritatea structurală a unei construcții și chiar a celor
învecinate. Orice încăpere care are montată o centrală cu gaze trebuie protejată cu un detector, și
din acest motiv, în ultima vreme, o categorie de dispozitive foarte des căutate și cumpărate au
ajuns să fie modelele tip detector de gaze pentru încăperi.
3
Pe plan internațional, în Hong Kong există "The Air Quality Monitoring Network of Hong
Kong". Rețeaua e proiectată și operată la cele mai înalte standarde internaționale și este
certificată de Hong Kong Laboratory Accreditation Scheme (HOKLAS) și și-a câștigat
aprecierea experților din întreagă lume și a programului ONU de monitorizare a mediului.
(sursa: [ 8 ] )
De asemenea, rețeaua de monitorizare a calității aerului din Canada culege date ce sunt apoi
folosite de către cercetători pentru descoperirea unor schimbări privind calitatea aerului și
elaborarea de statistici. Stațiile de măsurare testează calitatea noxelor ce pot proveni atât din țara
respectivă cât și din surse exterioare. De aceste măsurători depind deciziile luate la nivelul de
stat privind eficiența regulamentelor actuale, găsirea de noi soluții, elaborarea unor modele de
propagare a noxelor și urmărirea altor schimbări în mediul înconjurător.
Aceste sisteme senzoriale utilizează toată gama de tehnologii moderne pentru culegere,
prelucrare, analiză și distribuire a datelor. Pot exista mai multe feluri de dispozitive de alarmare
în caz de pericol de incendiu. Se pot da ca exemplu următoarele modele:
-dispozitive cu termostat și senzor de monoxid de carbon;
-dispozitive ce integrează mai mulți senzori: de fum, de praf, de poluare, umiditate,
compoziția aerului;
-dispozitive cu senzori de ionizare și fotoelectrici.
Cea mai importantă funcție a modelelor convenționale este de a sesiza dacă într-un anumit spațiu
sunt prezente emanații de gaze naturale (în general metan) și eventual de a semnala acest fapt sau
a introduce un detector de gaz preventiv cu electrovalve, ce oprește alimentarea încăperii cu
respectivul combustibil. Senzorii cei mai eficienți sunt cei cu sensibilitatea reglabilă. Indicele
limitei de explozie este o valoare standard calculată, în funcție de care utilizatorul trebuie să
seteze un procentaj de reactivitate. Acest lucru semnifică faptul că aparatul poate fi configurat
astfel încât să dea alarmă atunci când în atmosferă se ating procentaje de 15%, 10% sau chiar 5%
din cantitatea considerată minimă pentru explozie. De cealaltă parte, la o sensibilitate prea mare,
alarma se poate activa și atunci când în respectivă încăpere se desfășoară activități obișnuite,
nepericuloase, întrucât chiar și o cantitate mică de aerosoli poate stimula senzorul. Pentru aceste
categorii de senzori este foarte important de considerat durata de viață, aceasta fiind limitată la
un număr de ani sau chiar luni de funcționare. (sursa: [ 10 ] , [ 11 ] )
4
În viitor, aceste sisteme vor putea fi interconectate cu ușurință dacă se va merge pe o politică de
uniformizare a standardelor și formatelor de date utilizate de aceste sisteme.
5
Capitolul 1. Soluții actuale de detecție a gazelor
1.1 Detectoare pentru gaze
Un detector pentru gaz este un dispozitiv având scopul de a identifica prezența sau scurgerea de
gaze toxice sau inflamabile dintr-o încăpere. De cele mai multe ori, aparatul are în componență
un senzor chimic care poate sesiza prezența eventualului gaz și ca urmare poate genera un
semnal de ieșire corespunzător scopului. Variantele mai costisitoare pot funcționa și ca sistem de
control, permițând sistarea automată a alimentării cu gaz a încăperii.
Dispozitivele pot fi folosite pentru a descoperi prezența de gaze combustibile, inflamabile,
toxice, sau chiar scăderea nivelului de oxigen. Semnalul de ieșire fie este transmis-în cadrul unui
sistem de detectare, semnalizare și avertizare incendiu unui panou de control (în instituții, centre
comerciale sau rezidențiale ori clădiri industriale), fie este convertit într-un semnal audio sau
luminos local.
Tipurile de senzori folosite de aceste aparate fac parte din categoriile următoare:
detectoare electrochimice
pelistoare
detectoare cu fotoionizare
senzori cu infraroșu
senzori ultrasonici
senzori cu semiconductori.
Toate acestea sunt folosite pentru o varietate mare de aplicații și pot fi întâlnite în rafinării și
complexe industriale, farmaceutice, centre de lucru cu mărfuri periculoase sau tratamente
chimice , producții de vehicule , centre de testare a aerului și case. (sursa: [ 15 ] )
Cele două feluri principale de detectoare de gaz sunt: portabile sau pentru fixare pe perete. Cele
portabile sunt folosite cel mai adesea de personalul din fabrici și rafinării pentru a monitoriza în
permanență starea atmosferica a mediului în care se află muncitorii și ele pot fi purtate pe
echipamentul de lucru sau pot fi ținute în mână. Se pot adresa și publicului larg, în cazul în care
se dorește un dispozitiv cu care să se localizeze emanațiile din anumite zone ale casei pentru a
descoperi sursa scurgerii de gaz. Ele funcționează pe baterii și transmit semnale sonore sau
vizuale: alarme și aprinderea de leduri.
6
Dispozitivele fixate pe perete se folosesc de obicei pentru sesizarea mai multor tipuri de gaz și se
montează în încăperi unde se dorește o protecție și supraveghere permanentă.
1.1.2 Pelistoare
Un pelistor este un dispozitiv capabil să detecteze gazele ce au o conductivitate termică mult
peste cea a aerului, cum sunt de exemplu elementele combustibile. Elementul detector este o
piesă de material de ceramică sinterizat și dopat cu o substanță catalitică, a cărui rezistentă se
modifică în prezența gazului. Fenomenul se produce datorită căldurii generate de arderea gazului
detectat.
Aceste detectoare prezintă dezavantajul de a fi periculoase, putând genera explozii, și de aceea,
elementul principal al detectorului este protejat de o capsulă de oțel inoxidabil. (sursa:[ 20])
7
provine din faptul că măsuratorile nu depind de compus. Sfera de utilizare a acestor detectoare
este în monitorizarea mediului și controlul atmosferei industriale. (sursa: [ 21])
9
Senzorii de gaz sau senzorii chimici atrag în ultima vreme un interes deosebit datorită
domeniului larg de aplicare în industrie, supravegherea mediului ambiant, explorarea spațiului,
biomedicină și industria farmaceutică. Senzorii de gaze cu o sensibilitate ridicată și selectivitate
sunt indicați pentru detectarea scurgerilor unor gaze explozibile precum hidrogenul, sau pentru
detecția în timp real a gazelor toxice sau patogene din industrie. De asemenea există o cerere
crescândă a acestor senzori datorită abilităților de monitorizare a mediului ambiant.
Următoarele criterii sunt considerate de bază pentru un sistem eficient de monitorizare a gazelor:
sensibilitate și selectivitate ridicate;
răspuns și timp de refacere rapid;
consum redus;
temperatură de operare redusă și independența față de temperatură.
Cele mai recente descoperiri ale nanotehnologiei au deschis un potențial ridicat în construirea
unor senzori portabili cu consum redus și cost redus, foarte sensibili.
1
Nm3 - unitate de masura echivalenta pentru un metru cub de gaz
10
consumat, atunci un consumator ce beneficiază de alimentare cu gaze naturale cu un conținut
energetic ridicat ar avea mai puțin de plătit decât unul ce dispune doar de alimentare cu gaze cu
conținut energetic redus, și acest lucru ar determină o încălcare a legilor protecției
consumatorului. Din acest motiv s-a luat decizia ca taxarea să se facă în funcție de cantitatea de
energie rezultată în urma arderii gazului, și nu de volumul de gaz consumat.
Începând cu 01 ianuarie 2007, factura aferentă consumului de gaze indică în paralel, cu titlu
informativ, volumul de gaze naturale consumate (mc), respectiv echivalentul în unități de energie
(kwh), prețul gazului natural fiind exprimat în lei/kwh.
Conversia volumului de gaze naturale în unități de energie se face conform umatoarei formule:
Puterea calorifică superioară a gazelor naturale indică energia totală degajată prin arderea
completă, în aer, a unui metru cub de gaz natural. Această se stabilește lunar în funcție de
structura surselor de gaze naturale din care se asigură consumul. Puterea calorifică superioară
medie este egală cu 10.490,079 kwh/1000 mc . (sursa: [ 12 ] , [ 13 ] )
Pe baza analizei standardului SR EN ISO 6976 / 2005 și a unor comparații între compozițiile gazelor
provenite din mai multe zăcăminte diferite, s-a observat faptul că pentru o măsurare corectă trebuie
să se tină seamă de încadrarea consumatorului într-una din zonele de calitate, respectiv de putere
calorifică superioară a gazelor din zonă respectivă.
În zilele noastre, când procesele sunt atât de complexe, calitatea măsurărilor și controlul de siguranță
sunt esențiale, uneori de ele depinzând chiar calitatea vieții. Controlul calității și măsurătorile de
mediu trebuie efectuate cu mare precizie, corectitudine și în mod regulat, pe baza unor normative
tehnice corespunzătoare. Institutului Național de Metrologie, în conformitate cu standardul ISO
6142:1998, îi revine sarcina desemnării unității de măsură a gazelor prin verificări, etalonări și
incercări de model. Alte aspecte de care se ține cont la îndeplinirea acestei responsabilități sunt:
multitudinea și diversitatea de aparate gazanalitice existențe pe piață, performanțele la care au ajuns
acestea, tehnologiile de ultimă generație la care s-a ajuns pentru detectarea compușilor din gazul
metan, dorința de a factura cantitatea de energie obținută prin arderea gazului, și nu a volumului
efectiv de gaz consumat. De asemenea, este foarte importantă prezența Institutului Național de
Metrologie în cercul de interese din acest domeniu ca factor moderator. (surse: [ 33 ])
11
Capitolul 2. Arhitecturi ale sistemelor de monitorizare a
conținutului de gaze
2.1 Sisteme de centrale locale cu posibilitatea de legare la calculator
13
Multe dintre sistemele de alarmă sunt deseori cuplate cu un serviciu de monitorizare, folosind un
modul de comunicație. În eventualitatea unei alarme se trimite automat un mesaj de alarmă către
dispeceratul de pază și/sau telefonul mobil al proprietarului. Ca modalități de transmitere a
evenimetelor, se poate opta pentru comunicații: seriale fir de tip: RS232, RS485, RS422,
Ethernet, modem Dialup, modem ADSL linii telefonice, radio, GSM GPRS, GSM, Internet.
Senzor(i) Senzor(i) Senzor(i)
Filtrare mesaje
Adaptor interfață
comunicații
Mediu comunicații
Decodor mesaje
Programator
mesaje
Jurnal
evenimen
te sistem
Stivă mesaje
14
unei situații de alarmă, precum apariția gazelor, a fumului etc. Procesorul central dispune de cel
puțin un port de ieșire cu scopul de a livra rapoarte și mesaje de alarmă către un dispozitiv
terminal într-un format util pentru intervenția umană. În mod specific, la sistemele cu interogare,
fiecare unitate locală individuală interoghează senzorii dacă starea acestora s-a schimbat din
normală în declanșată.
Fiecare unitate locală dispune de memorie proprie pentru a stoca date referitoare la adresa și
starea declanșată a fiecărui senzor. Inițierea comunicațiilor presupune ca unitățile locale să între
în operare în urma detecției unei schimbări a stării senzorilor și să inițieze stabilirea unei legături
de comunicație între unitatea respectivă și un port de intrare a procesorului central. Datele citite
din memorie într-un format propriu sunt codate în format digital adaptat pentru transmisie pe
legătură de comunicație. Mesajul este stocat în sistemul central iar acesta corelează logic datele
primite de la senzor cu segmentele corespunzătoare pentru determinarea validității mesajului de
alarmă. Există următoarele variante de operare:
detecția electronică a nevalidității unui mesaj de alarmă și transmitere a unui raport de
recepționare : mesaj eronat;
declanșarea stării de alarmă la recepționarea unui mesaj valid sau a unui raport într-un
format utilizabil pentru intervenție umană.
(surse: [ 34],[ 36],[ 37],[ 38],[ 39],[ 40],[ 41])
15
Fig. 13 Monitorizarea sistemlor de alarmă de la distanță (sursa: [ 42 ])
16
O aplicație web este rezidentă pe un server, fiind accesată prin intermediul unei rețele (Internet)-
de către utilizatori, care folosesc un client web (browser). De obicei, o aplicație web este
structurată pe trei niveluri:
1. browserul web;
2. tehnologia utilizată pentru generarea dinamică a conținutului (de exemplu server
de aplicații);
3. sursa de date, reprezentată de obicei de o bază de date cu mai multe tabele (DB).
Comunicația dintre aceste niveluri se poate realiza bidirecțional. Cele mai întâlnite două cazuri
sunt:
browserul trimite cereri nivelului intermediar, care efectuează apoi interogări ale bazei de
date și generează un rezultat pe care îl întoarce browserului.
serverul primește avertismente/ notificări din exterior (generate, de exemplu, de senzori)
și anunță clientul despre aceste evenimente, cerând browserului să le afișeze
Conținutul servit browserului de către serverul web poate fi static (adică stocat în fișiere de pe
calculatorul-server) și dinamic (generat de scripturi/programe sau API-uri apelate de serverul
web). Livrarea conținutului static este mult mai rapidă decât cea a conținutului dinamic, dar la
ora actuală necesitatea de conținut dinamic, interactiv este mult mai mare.
Avantajele folosirii unei aplicații web ca interfață cu pentru o platformă de gestiune a unor
senzori sunt:
• aplicația este creată modular, oferind posibilitatea extinderii capabilităților de bază oferite;
• nu este necesară instalarea de software suplimentar;
• programarea aplicației se poate face în orice limbaj cunoscut de dezvoltator;
• asigurarea suportului pentru conexiuni securizate prin criptarea fluxurilor de date;
• oferă utilizatorului posibilitatea de configurare a unor caracteristici ale modului de navigare și
afișare;
• stocarea bazelor de date pe web server.
3.1.2 Socket-uri
Comunicarea între server și client se face conform unui set de reguli (protocol). Identificarea
serverului de către client și invers se realizează prin intermediul unor socluri, numite în engleză
socket-uri. Deoarece pe un calculator pot fi instalate simultan mai multe programe server, e
nevoie că apelurile de la diferiți clienți să ajungă la programul server corect, iar pentru asta se
procedează în felul următor: se "ascultă" pe un anumit port. Portul e un număr de 16 biți cuprins
între 0 și 65535, dintre care cele cu valori mai mici de 1024 sunt rezervate pentru servicii
predefinite. Unele porturi pot fi "ocupate" implicit de anumite aplicații : de exemplu, serverul
MySQL folosește implicit portul 3306, iar serverul Apache portul 80.
Combinația dintre adresa IP și un număr de port este întrebuințată pentru crearea termenului
abstract de socket. Datele între client și server sunt schimbate prin socket: un client caută
serverul, stabilește o conexiune prin care poate fi transmisă informația, pentru ca la final să se
deconecteze lăsând liber socket-ul pentru o utilizare ulterioară. Alegerea portului pentru client nu
este importantă, deoarece serverul nu are nevoie să cunoască dinainte de la care port vor trimite
clienții cereri. Serverul va ști cine a trimis o cerere din faptul că pachetul trimis de socket-ul
clientului conține numărul de port și adresa IP a mașinii lui.
(surse: [ 43],[ 44],[ 45],[ 46])
18
De asemenea, o interfață complicată sau ne-intuitivă îl poate determina pe utilizator să renunțe
efectiv la încercarea de a folosi aplicația, chiar dacă aceasta este perfect funcțională. Astăzi, una
din cele mai agreate și ușor de implementat metode de interacțiune cu utilizatorii este o pagină de
internet. Dezvoltarea de frontend este practica creării unui schelet de pagină web, folosind
HTML, CSS și JavaScript, pentru ca utilizatorul să interacționeze direct cu aceasta. Provocarea
acestei sarcini este accea că tehnicile și "uneltele" de programare sunt în continuă schimbare, iar
un dezvoltator trebuie să cunoască ritmul de dezvoltare al domeniului său. Scopul designului
unei pagini web este acela că atunci când utilizatorul o accesează, să poată vedea simplu și rapid
informația într-un format ușor de citit și relevant.
3.2.1 HTML
HyperText Markup Language (HTML) este scheletul oricărui proces de implementare a unui
site web, fără de care pagina nu poate exista. Se bazează pe un limbaj de marcare, orientat către
prezentarea documentelor text pe o singură pagină, și este cel mai cunoscut și folosit limbaj de
creare de documente web, care pot fi apoi interpretate și afișate de un browser.
"Hypertext" se referă la faptul că textul are legături (linkuri) către diverse alte elemente
incorporate în el. De exemplu, dacă utilizatorul apăsa pe un cuvânt sau frază ce conține un link,
el va fi redirecționat către o altă pagină web.
"Limbajul de marcare" este un limbaj ce pune la dispoziție mijloace prin care conținutul unui
document este asociat cu o multitudine de indicații de redare. Indicațiile de redare pot varia de la
decorațiuni minore ale textului, cum ar fi specificarea faptului că un anumit cuvânt trebuie
subliniat sau că o imagine trebuie introdusă, pană la scripturi sofisticate, hărti de imagini, tabele
și formulare. Metadatele pot include informații despre titlul și autorul documentului, informații
structurale despre cum este impărtit documentul în diferite segmente, paragrafe, liste, titluri etc.
și informații cruciale care permit ca documentul să poată fi legat de alte documente pentru a
forma astfel hiperlink-uri.
Paginile HTML sunt formate din etichete sau tag-uri și au extensia „.html” sau „.htm”. În marea
lor majoritate aceste etichete sunt pereche, una de deschidere <etichetă> și altă de închidere
</etichetă >, există cazuri care nu se închid, atunci se folosește < etichetă />. Conținutul
existent aceste etichete este clasificat funcție de semnificația etichetelor: titlu, paragraf de text,
imagine, videoclip, tabel, formular așa departe. Navigatorul web interpretează aceste etichete
afișând rezultatul pe ecran.
Deoarece HTML este doar un limbaj de prezentare, neajunsurile acestuia următoarele:
inexistența suportului pentru programare;
lipsa informației semantice.
3.2.2 JavaScript
JavaScript este un limbaj de programare cu o gamă de utilizare foarte largă și variată, orientat
pe obiect și al cărui scop utilizat în principal în contextul acestei lucrări este introducerea unor
funcționalități în paginile web. Se poate afirma că JavaScript este întocmai opusul HTML-ului,
în sensul că, dacă HTML este un limbaj declarativ care descrie ceea ce se vede, JavaScript este
un limbaj bazat pe declanșarea unor evenimente, ce descrie cum funcționează ceea ce se vede. El
transformă o pagină HTML statică într-una dinamică, cu conținut modificat de datele de intrare
oferite de utilizator. În plus, folosind o tehnică denumită AJAX (Asynchronous JavaScript And
XML), codul JavaScript poate extrage în mod activ conținut din Internet (independent de cererile
de conținut HTTP) și poate reacționa la evenimente din partea serverelor, adăugând un adevărat
19
dinamism experienței utilizatorului. Motivele pentru care această tehnică, împreună cu
programarea în JavaScript, este tot mai preferată de dezvoltatorii de platforme online sunt
următoarele:
poate determina conținutul paginii să se modifice fără a fi nevoie să se reîncarce întreaga
pagină;
poate trimite cereri sau primi mesaje de la / către server chiar și după ce pagina web a fost
încărcată și expusă de browser;
funcționează asincron.
Etapele de funcționare a unui cod JavaScript:
1. Are loc un eveniment pe pagina web (de exemplu, este apăsat un buton);
2. JavaScript creează un obiect XMLHttpRequest;
3. Obiectul XMLHttpRequest trimite o cerere la web server;
4. Serverul procesează cererea;
5. Serverul trimite un răspuns înapoi la pagina web;
6. Răspunsul este citit de codul JavaScript;
7. JavaScript execută o sarcină predefinită (de exemplu, aduce conținut nou pe pagină).
20
PHP (PHP:HyperText Preprocessor - *.php, *.php3, *.php4, *.phtml) - PHP este o
combinație de C, Perl și Java și este utilizat, de cele mai multe ori, împreună cu serverul
web Apache;
JavaScript și Server-side JavaScript: Nodejs (*.ssjs, *.js);
Perl (Practical Extraction and Report Language) via modul CGI.pm (*.cgi, *.ipl, *.pl) -
limbaj care se bazează pe C și are câteva utilitare UNIX. Are avantajul de a fi foarte
flexibil și conține numeroase module și scripturi scrise deja ce pot fi găsite cu ușurință în
bibliotecile sale online;
Python (*.py) - limbaj oferind posibilitatea programării structurate dar și orientate pe
obiect și incluzând și elemente din paradigma functională. Este un limbaj de scripting,
ceea ce inseamnă că este interpretat și nu compilat, economisind mult timp în procesul de
dezvoltare și debugging;
Google Apps Script (*.gs)
Ruby (*.rb, *.rbw) (examplu: Ruby on Rails) - limbaj de programare generic, reflexiv,
dinamic și orientat pe obiecte;
ASP(Active Server Pages) (*.asp) - este o platformă de programare web creată de
Microsoft, fiind utilizată cu serverul web Microsoft IIS;
ColdFusion Markup Language (*.cfm) - cadru de lucru utilizat în special pentru crearea
de site-uri dinamice.
Componenta backend a unei pagini web se referă la tot ceea ce ține de managementul de
conținut, aceasta însemnând: server, legăturile cu interfața și baza de date. Conceptul este
denumit astfel pentru a sugera sarcinile executate în spate ale aplicației, invizibile utilizatorului.
Ea este scrisă în majoritatea cazurilor în PHP, Python sau Nodejs, de cele mai multe ori în PHP.
În backend avem API-ul, clasele, modelele, tot ce ține de "server-side". În lucrarea de față,
majoritatea codului pentru relaționarea cu servere este scris în PHP. (surse: [ 54],[ 55])
3.3.1 PHP
Prin PHP se înțelege atât limbajul de scripting, cât și serverul de aplicații, cel din urmă având
rolul de a procesa scripturile scrise utilizând acest limbaj. La ora actuală, el este folosit în cel mai
mare sistem de blogging din lume, WordPress, și de asemenea, în cel mai răspândit site de
socializare din lume, Facebook. Modul cel mai frecvent de folosire al lui este prin încapsulare în
HTML. Secvențele de cod PHP sunt delimitate de un marcaj de start și unul de stop ( <?php și
?> ). Un fișier .php poate conține în interiorul sau atât cod PHP, cât și text simplu, cod CSS,
JavaScript sau HTML.
Sarcinile pe care le poate îndeplini PHP sunt:
generare de conținut web dinamic;
colectare de date prin formulare;
creare, deschidere, citire, scriere, ștergere de date/fișiere de pe server;
trimitere sau recepționare de cookies;
permitere de sesiuni de comunicare;
criptarea fluxurilor de date;
modificarea bazelor de date.
21
3.3.1.1 Generarea dinamică a conținutului
Formatele textuale sau marcajele/secvențele sunt generate prin intermediul instrucțiunilor echo
și print. Astfel, pot fi afișate în browser valorile unor variabile, date de tip șir de caractere sau
marcaje HTML, ca în exemplul următor:
Spre deosebire de echo, instrucțiunea print acceptă un singur argument și întoarce valoarea 1
dacă afișarea a avut loc și 0, în caz contrar.
22
De menționat că scriptul de prelucrare poate fi o secțiune de cod PHP care să fie încapsulată
chiar în același cod HTML care face afișarea formularului în browser. Pentru a specifica
scriptului de procesare ce acțiune să îndeplinească în momentul activării sale, se folosesc
elementele:
<form action = "script.php">
...
</form>
Este posibil ca datele alese de client să fie trimise pe server și fără a utiliza un formular, ci prin
adăugare pe baza unui link <a href = "*" > Link </a>.
<?php
ini_set("session.use_cookies", 1);
ini_set("session.use_only_cookies",1);
session_start();
?>
23
<?php
session_start();
$_SESSION['username'] = "frh_hbc";
$_SESSION['password'] = "h56HSWR89!aop";
?>
Eliminarea unei variabile înregistrate în sesiune se face prin atribuirea elementului său valoarea
false: $_SESSION["variabila"] = false; sau prin folosirea funcției unset:
unset($_SESSION["variabila"]); Pentru a elimina toate elementele unei sesiuni fără distrugerea sa,
se folosește funtia session_unset().Distrugerea unei sesiuni are loc atunci când se închide
browserul sau când se efectuează operația de logout, iar datele din aceasta sunt șterse. Exemplu:
<?php
session_start();
session_unset();
session_destroy();
?>
Dacă un utilizator uită să efectueze operația de logout, modulul de management al sesiunilor
PHP are un mecanism propriu de siguranță prin care șterge fișierele de sesiune neutilizate. Acest
lucru previne încărcarea serverului cu fișiere de sesiune redundante și reduce riscul că un
potențial atacator să afle SESSION ID și să se folosească de o sesiune veche a unui utilizator.
Pentru a activa mecanismul acesta, în fișierul php.ini trebuie setate valorile a trei directive:
session.gc_maxlifetime - implicit 24 de minute;
session.gc_probability;
session.gc_divide.
3.3.2 Node.js
Node.js este un mediu de lucru dezvoltat în manieră open-source și care permite un grad mare de
interoperabilitate cu alte platforme de lucru, având rolul de a executa cod JavaScript orientat spre
servere. Din punct de vedere istoric, JavaScript era folosit în principal pentru partea de client,
scripturile sale fiind integrate în paginile HTML și executate de un motor de rulare JavaScript
din browser-ul utilizatorului. Node.js a fost creat pentru a permite ca același limbaj JavaScript să
fie folosit orientat spre server, să poată fi rulat pentru a produce conținut dinamic pentru paginile
web înainte că acestea să fie trimise browser-ului clientului.
Expresia ".js" din numele produsului se referă chiar la extensiile pe care le au fișierele scrise în
JavaScript. Arhitectura node.js este bazată pe evenimente declanșatoare, care au loc asincron.
Acest design a fost creat în special pentru a dezvolta aplicații real-time, jocuri, chat-uri.
Platforma a fost construită pe motorul V8 al Chrome, și are drept caracteristică principală
folosirea callback-urilor.
In programarea calculatoarelor, un callback este un cod, mai precis -o funcție, care este dată ca
argument unei alte funcții din partea căreia se așteaptă să facă apel la callback la un moment
precis de timp. Momentul de timp este asociat cu declanșarea unui eveniment-astfel există
callback-uri care au loc imediat la momentul rulării funcției de bază (sincrone) , sau callback-uri
care au loc la un moment de timp mai îndepărtat (asincrone). Callback-urile sunt, de fapt, părți
de cod care sunt "executate" după ce o anumită acțiune se petrece (exemple:
OnGameModeInit atunci când pornește un anume mod al jocului, OnPlayerConnect când un
jucător se conectează, OnPlayerDeath când un jucător moare și așa mai departe). Callback-urile,
de obicei, au deja în nume evenimentul când se petrec-deci e foarte ușor a interpreta ce face un
callback doar analizând numele lui. Aceste coduri sunt, de cele mai multe ori, implementate de
sistemul de operare prin subrutine de întrerupere.
24
La ce se poate folosi nodejs:
API-uri JSON;
Aplicații în timp real – aplicații web, de rețele sociale și mesagerie instantanee, software
de chat, monitorizare în timp real etc.;
Aplicații cu o singură pagină;
Aplicații cu acțiuni declanșate de evenimente (event-driven);
Aplicații care trebuie să proceseze mii de conexiuni și fluxuri de date către alte sisteme;
Aplicații care asigură un schimb intensiv de date cu backend-ul;
Aplicații mobile in Node.js – folosind API-uri JavaScript pentru aplicații mobile
compatibile cu Node.js;
Dispozitive IoT – tehnologie wearable, dispozitive încorporabile și robotică.
In contextul acestei lucrări, node.js este folosit în primul rând pentru a construi legătura cu
serverul de la care se vor primi alertele legate de senzorii de gaz (la momente de timp
neprevăzute) Cea mai mare diferență dintre node.js și PHP este aceea că majoritatea funcțiilor
din PHP se blochează până la terminare (comenzile se execută doar după ce s-a terminat execuția
comenzii precedente), în timp ce funcțiile din node. js sunt gândite ca ne-blocabile (comanda se
execută în paralel și utilizează callback-uri pentru a semnaliza succesul sau eșecul execuției).
Serverul de aplicații PHP poate utiliza mai multe sisteme de gestiune a bazelor de date, cel mai
folosit fiind MySQL. phpMyAdmin este un program aplicație utilizat pentru administrarea
bazelor de date MySQL printr-o interfață web. În lucrarea această, instrumentul phpMyAdmin
este folosit cu scopurile de a deschide conexiuni cu serverul MySQL pe care vor fi create bazele
de date, trimiterea de interogări către acestea și preluarea rezultatelor întoarse de server.
Pentru a permite designerilor și programatorilor web să lucreze mai ordonat și mai simplu, fără a
fi nevoiți să instaleze o multitudine de programe utilitare, dezvoltatorii de la Apache Friends au
conceput un pachet de programe software gratuite, cu licență "open source" și cu posibilitate de
interoperabilitate (cross-platform) care constă într-un Apache HTTP Server, o bază de date
MySQL și interpretoare pentru scripturile scrise în limbajele de programare PHP și Perl.
25
Numele este format din acronimele:
X (de la "cross-platform")
Apache Server
MySQL
PHP
Perl
Programul acționează ca un web server capabil de a servi pagini dinamice, și vine, de asemenea ,
cu modulul phpMyAdmin incorporat. Instalarea XAMPP ia mult mai puțin timp decât instalarea
fiecărei componente în parte.
26
Se pot realiza configurări ale serverelor, configurări ale interfeței, citirea unor documentații și
vizualizarea bazelor de date. La selectarea uneia dintre acestea, sunt afișate tabelele din
componența ei.
Structura tabelelor și datele din acestea pot fi modificate nu numai prin execuția unui cod care se
conectează la acestea, ci și din interfață, dând comenzi MySQL într-un terminal.
Este important de punctat însă că scopul folosirii acestui utilitar nu este rularea comenzilor din
interfața web, la care utilizatorii nu au acces, ci ușurința programării platformei web destinate
utilizatorilor care doresc să-și monitorizeze de la distanță senzorii de gaz achiziționați. Deci,
orice modificare apărută în bazele de date va fi determinată de către acțiunile efectuate și datele
introduse de consumatori pe platforma online.
Explicarea codului:
Funcția mysql_connect()primește ca argumente-sub forma unor șiruri de caractere- numele
gazdei pe care este instalat serverul MySQL (acesta fiind mașina de lucru pe care se execută
codul, deci adresă de loopback 127.0.0.1 ), numele utilizatorului și parola. Acestea din urmă se
27
pot modifica în fișierul de configurare al utilitarului phpMyAdmin config.inc.php (localizat in
folderul phpMyAdmin) , unde se modifică urmatoarele linii:
$cfg['Servers'][$i]['auth_type'] = 'config';
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = 'password16';
$cfg['Servers'][$i]['extension'] = 'mysqli';
$cfg['Servers'][$i]['AllowNoPassword'] = true;
Dacă conexiunea nu se poate stabili în mod corect, funcția mysql_connect() va returna valoarea
0, și semnalăm această situație printr-un mesaj "Nu se poate stabili conexiunea". Funcțiile die()
și mysql_error()sunt funcții specifice pentru manipularea erorilor. Dacă funcția a fost executată
corect, atunci ea întoarce un identificator de conexiune, de tip resursa, numit și identificator de
legătură.
Observație: Este posibilă conectarea la MySQL și în situația în care serverul rulează pe altă
mașină, caz în care numele hostului trebuie să coincidă cu numele de domeniu (de exemplu,
"altdomeniu.org"). Dacă este necesar să se folosească alt port decât cel implicit, acest lucru se va
preciza explicit astfel: "127.0.0.1:4000".
În codul de mai sus, parametrii de conectare au fost precizați ca valori ale unor variabile PHP,
abordare utilă în dezvoltări de aplicații complexe. În lucrarea de față, pentru simplificare, s-a
folosit un cod mai condensat:
mysql_connect("127.0.0.1", "root", "password16");
mysql_select_db("login");
Efectul va fi același ca și în primul caz, doar că aici se utilizează o funcție diferită, creată într-o
manieră orientată spre obiecte, pentru a funcționa cu versiuni de PHP și MySQL mai noi. În
codul de mai sus, variabila $conn este de tipul obiect, iar elementele sale se accesează prin
simbolul "->".
28
Exemple de aplicări ale funcției:
$query1 = mysql_query("SELECT * FROM sensor WHERE sensor_id = '$_POST[sensor_id]'") or
die(mysql_error()); - codul selectează toți senzorii având un anumit identificator
29
date. Atacurile de tipul SQL Injection pot fi blocate printr-o filtrare corectă. Pentru aceasta se
folosește una din funcțiile următoare:
string addslashes(string sir_caractere) - întoarce șirul transmis ca argument, în care a
fost adăugat câte un caracter backslash înaintea caracterelor speciale
string mysql_real_escape_string(string sir_caractere [,resource identificator]) -
aceeași acțiune, adăugând backslash și înaintea caracterelor \x00, \n, \r, \xla.
dacă directiva magic_quotes_gpc este activată (având valoarea "on" în fișierul php.ini),
atunci toate caracterele amintite se prefixează automat și nu mai este nevoie să se
folosească funcțiile precendente
Exemplu de SQL Injection: dacă numele de utilizator și parola cerute într-un formular nu sunt
filtrate după aceea, un atacator poate introduce, de exemplu:
$_POST['username'] = 'maria';
$_POST['password'] = "' OR ''='";
Interogarea ar arăta astfel:
SELECT * from user WHERE user= 'maria' AND password= '' OR ''='';
Se observă că instrucțiunea SQL a fost modificată prin introducerea lui "OR" care va avea mereu
valoarea true. Deci s-ar permite autentificarea oricărui utilizator fără o parolă validă (numele
utilizatorului introdus nici nu mai are importanță).
O altă măsură de siguranță ce se aplică bazelor de date este scrierea codului pentru stabilirea
conexiunii la serverul SQL într-un fișier separat și mutarea sa undeva în afara fișierului htdocs.
Folosirea se va face cu comenzi de include și require.
3.5.1 Limbajul CSS (Cascade Style Sheets) a fost creat de către Consorțiul World Wide Web
(W3C) în anul 1996 pentru a înlătura procedurile de formatare a textului și înfrumusețare grafica
din HTML. Deoarece codul CSS de descriere formală este salvat într-un fișier extern, cu extensia
.css, principalul avantaj al acestei separări între scheletul unei pagini web și elementele sale
estetice este cel al unei mai bune organizări a codului și posibilitatea de a modifica chiar și în
30
întregime aspectul unei pagini modificând doar un singur fișier. Acestuia îi trebuie creată o
referință în interiorul secțiunii <head> a codului HTML, în felul următor:
Când browserul "citește" fișierul CSS, modifică aspectul documentului HTML în concordanță cu
informațiile din codul de descriere formală. Dacă se dorește aplicarea unui anumit stil doar pe o
singură pagină web, atunci codul CSS poate fi încorporat în întregime în codul HTML, folosind
etichetele (tags) <style> și </style>.
Sintaxa CSS este foarte simplă: se înșiruie elementele de marcare definite în documentul HTML
asupra cărora se doresc a se face modificări estetice și apoi se definesc proprietăți urmate de o
anume valoare. Elementele de marcare HTML sunt identificate și selectate pe baza numelui, id-
ului, clasei sau atributului lor. Id-ul oricărui element HTML trebuie să nu se repete în cadrul unei
pagini, pentru că selectorul CSS să poată realiza o identificare unică.
(sursa: [ 60] )
4.1.2 FLASHNET
FLASHNET este o companie ce se dezvoltă rapid și se ocupă cu integrarea celor mai noi
tehnologii IT din domeniul energiei și cel al telecomunicațiilor în soluții hardware și software
pentru îmbunătățirea infrastructurii orașelor. Fondată în 2005, compania este membră a LoRa
Alliance. Una dintre cele mai recente soluții dezvoltate de aceasta este inteliLIGHT, un sistem
fiabil de management al iluminatului stradal bazat pe senzori.
În această lucrare a fost realizată o arhitectură de culegere a datelor de la senzorii de gaz
funcționând pe protocolul LoRa care sunt înregistrați drept module pe platforma online a
inteliLIGHT.
31
O rețea LoRaWAN e formată pe structură star la nivelul de jos, unde există senzori și noduri
colectoare (gateway-uri) transparente pentru date, interconectate prin conexiuni IP standard, iar
senzorii transmit pe protocolul LoRa. Cerințele de la o astfel de rețea sunt:
• consum foarte redus de putere al senzorilor (aceștia trebuie să poată funcționa ani de zile cu
aceeași baterie);
• capacitate de procesare a informațiilor de la miliarde de dispozitive;
• distanță de transmisiune mare (zeci de kilometri);
• Quality of Service (QoS);
• securitate;
• putere de penetrare mare prin clădiri;
• costuri de dezvoltare mici;
• scalabilitate;
• rată de transmisiune adaptivă (între 300 bps și 5 kbps).
Tehnologia LoRaWAN are implicații doar asupra nivelurilor Fizic și Legătură de Date. La nivel
Fizic, protocolul operează în benzi de frecventă nelicențiate (ISM-pentru uz industrial, științific
și medical). Pentru transmiterea datelor sunt folosite tehnici de modulație cu spectru imprăștiat.
LoRaWAN operează în benzile ISM fără licență de 863-870 Mhz și 433 Mhz. La fiecare
transmisie, canalul folosit de dispozitivul terminal este schimbat într-un mod pseudo-aleator.
Tipul de modulație este cu spectru împrăștiat, fiind un tip particular de modulație chirp (CSS-
Chirp Spread Spectrum) și a fost creat de SemTech. Diferența dintre cele două este aceea că
modulația LoRa folosește factori de împrăștiere ortogonali care duc la rate de bit diferite-acestea
reduc interferența între comunicații. Semnalele chirp se caracterizează prin faptul că au o
frecvență ce se modifică cu o rată fixă sau exponențială. Datorită imunității la interferențe și
distanței de comunicație mari pe care le poate asigura, modulația CSS a fost inițial folosită în
aplicații militare și spațiale.
32
Stație de bază (Gateway) LoRa: Este poarta de acces prin care rețeaua primește datele de la
noduri și apoi le transferă prin internet la serverul de rețea. Conexiunea la serverul de rețea
LoRa poate fi Ethernet, celulară sau orice alte legături de telecomunicații cu fir sau fără fir
care ofer conexiune la internet. Stațiile de bază sunt conectate la serverul de rețea folosind
conexiuni IP standard. Stația de bază trebuie să fie capabilă să susțină un număr mare de
conexiuni. Se folosește o viteză de transfer adaptivă, datorată ortogonalității semnalelor unele
față de altele. Nodurile care sunt mai aproape de gateway vor avea viteză de transmisiune mai
mare, pentru a nu menține banda ocupată și pentru a îmbunătăți timpul de transmisie pentru
nodurile îndepărtate.
Server de rețea (network server): Serverul de rețea care controlează viteza de transmisie a
datelor. Având în vedere modul în care acesta poate fi implementat și conectat, complexitatea
implementarii unei rețele LoRa este foarte scăzută.
Server de aplicații: Din serverul de aplicații se pot accesa aplicațiile care consumă datele de la
noduri și le afișează în așa fel încât să ofere informațiile cele mai relevante pentru client. Mai
mult de atât, LoRa permițând comunicarea bi-direcțională între noduri și serverul de rețea, se
pot trimite comenzi de la distanță către noduri, aceste comenzi pot fi de gestiune a nodurilor
(actualizarea softului de la distanță) dar și de control a unor elemente dintr-un sistem.
Conform specificațiilor, arhitectura unei rețele de tip LoRaWAN este următoarea:
Deoarece dispozitivele de pe Nivelul Fizic pot fi foarte variate, ele sunt categorisite pe clase, și
acestea sunt apoi adaptate la cele mai specifice nevoi: necesitatea de timp de viață lung (baterie),
sau necesitatea de întârzieri reduse (low latencies).
dispozitivele de clasa A:
- cele mai eficiente energetic;
- este posibil să asculte încontinuu, nu se pune problema de întârzieri;
- fiecare transmisiune pe uplink este urmată de alte 2 scurte transmisiuni downlink;
- se utilizează principiul diviziunii în timp;
- transmiterea pe ruta ascendentă poate fi inițiată de mod la orice moment de timp.
Comunicațiile pe ruta descendentă (server-nod) se pot realiza doar în cadrul celor două ferestre
33
temporale. Dacă serverul dorește să comunice nodului, în orice altă perioadă, va trebui să aștepte
următoarele ferestre temporale, când dispozitivul este în mod recepție.
dispozitive de clasa B:
-legatura downlink are un mecanism de control al întârzierii
-permit si existența unor ferestre temporale (sloturi) suplimentare la intervale
prestabilite/ programate. Pentru ca dispozitivele clasa B să poată recepționa informația
transmisă de server în ferestrele suplimentare, stația de bază va trimite un semnal de
sincronizare. În acest fel, serverul va știi momentul în care nodul este în ascultare.
Securitatea într-o rețea LoRaWAN este implementată prin algoritmul AES (Advanced
Encryption System) și are două niveluri:
pentru rețea: se verifică apartenența dispozitivului la rețea
pentru aplicație: operatorul nu are acces la datele abonatului
34
serverul ascultă în permanență mesajele provenite de la modulele instalate
Având în vedere că sistemul utilizează internetul și nu este o soluție de tip închis, în aplicațiile
industriale practice este recomandabilă protecția informației prin controlul accesului operatorilor,
utilizarea unor rețele private VPN sau alte metode de interzicere a accesului neautorizat la
configurările aplicației.
Modelul experimental realizat în cadrul acestei lucrări s-a axat doar pe demonstrarea
funcționalității tehnologiile web fără a luă în considerare și măsuri suplimentare de securizare a
informațiilor.
Arhitectura folosește tehnologia LoRa care presupune instalarea unei rețele LPWA (Low Power
Wide Area) pe baza căreia să se poată dezvolta diverse aplicații ce necesită transfer mic de date.
Această rețea ar fi compusă din următoarele elemente:
• un server central care culege și gestionează informațiile primite de la gateway-uri
• gateway-uri, acestea fiind reprezentate de stații de bază concentratoare de date
• noduri, denumite module LoRa
clientIntelilight.on('connect', function(connection) {
console.log('WebSocket Client Connected');
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log("Received: '" + JSON.stringify(message.utf8Data) + "'");
myMessage = JSON.stringify(message.utf8Data);
console.log(myMessage);
for(var i = 0, len = clients.length; i < len; i++) {
clients[i].emit("message",myMessage);
}
35
}
});
function sendLogin() {
if (connection.connected) {
var s='{ "op": "login", "user": "viviana", "pass": "viviana1"}';
connection.sendUTF(s);
}
}
sendLogin();
});
clientIntelilight.connect('http://fc1.intelilight.eu:59080/JSON ', null, null, null);
Se apelează metoda "connect" în care este necesar să se specifice adresa URL a host-ului
serverului. Serverul răspunde la această comandă, trimițând un mesaj "connect". Se apelează
metoda "on", iar dacă mesajul este "connect", se va tipări informarea 'WebSocket Client
Connected'. În continuare este nevoie să se realizeze autentificarea utilizatorului. Pentru aceasta
se creează, și mai apoi se apelează funcția sendLogin , unde se testează dacă există o conexiune
stabilită deja, și în caz afirmativ, se trimite serverului, prin metoda sendUTF(s), un șir de
caractere s reprezentând un JSON cu datele de autentificare ale utilizatorului. Conform
protocolului, serverul trebuie să trimită înapoi la client un mesaj de forma: '"{\"priv\": \"\",
\"op\": \"login\", \"ok\": 1}"'
Client Server
inteliLIGHT inteliLIGHT
“connect”
operation:
login , OK
Notă importantă: codul node.js este asincron, ceea ce înseamnă că funcțiile nu se execută în
ordinea scrierii lor, ci declanșate de evenimente. De aceea este necesară folosirea callback-urilor,
pentru a verifica succesul execuției lor și memorarea datelor la momentul potrivit.
Unitate de
alimentare
(sursa: [ 66] )
37
Blocul de date transmis de modulul local cuprinde mesajul standard de stare normală, repetabil la
intervalul de timp prestabilit (1 minut) și care crează încărcarea uzuală a rețelei de
comunicații, și mesaje de alertă, care sunt declanșate de prezența gazului în apropierea
senzorului. Deoarece politica de raportare este de tipul polling (raportare doar în caz de
eveniment), se estimează că încărcarea suplimentară a rețelei de comunicații este puțin probabilă
și poate fi modelata matematic cu un coeficient aleator , ce poate fi determinat statistic din
numărul evenimentelor de acest tip înregistrare în viața reală.
în care:
- debitul total introdus de un mesaj în rețea;
k - numărul total de mesaje "Heartbeat"
- lungimea unui mesaj "Heartbeat"
- probabilitatea de sesizare a unei scurgeri de gaz
- lungimea unui mesaj "GAS ALERT"
Informația utilă dintr-un bloc de date (payload) este codată hexazecimal în mesajul
"486561727462656174" semnificând șirul de caractere "Heartbeat", respectiv în mesajul
"47415320414c4552542" semnificând "GAS ALERT".
Un exemplu de mesaj de tipul Heartbeat este următorul:
"{\"op\": \"push\", \"deveui\": \"0004a30b001b7f29\", \"port\": 1, \"count\": 2041,
\"payload\": \"486561727462656174\", \"ts\": 1496005078}"
2
sursa: www.thethingsnetwork.org/forum
38
800 350 40%
1000 450 45%
Specificațiile LoRaWAN menționează faptul că orice modul local trebuie să suporte următoarele
rate de transmisie a datelor:
Modulul folosit în lucrare folosește configurația SF7/125kHZ. SF7 este factorul de împrăștiere al
sistemului. Fiecare simbol din payload este reprezentat pe chips, ceea ce duce la o rată
efectivă de 5470 bit/s. Cu cât factorul de împrăștiere este mai mare, cu atât durata unei
transmisiuni este mai mare. La un data rate egal cu 5, pachetului îi ia 66 milisecunde să fie
transmis. Timpul de așteptare până la posibilitatea transmiterii următorului pachet este 6.5
secunde, spre deosebire de 160 secunde, cât ar dura la un data rate egal cu 0. Pe de altă parte,
folosirea de rate mari a datelor face semnalul mai susceptibil la zgomot.
39
Application Key (AppKey) - Cheie de aplicație codată AES128 ce este folosită pentru a
calcula cheile de sesiune NwkSKey și AppSKey.
40
Codul HTML care descrie elementele secțiunii destinate înregistrării pe platformă este
următorul:
<div id="Sign-Up">
<form method="POST" action="connection1.php">
...
<p> <button class="button" id="button"> Sign Up</button>
</form>
</div>
Similar pentru câmpul de e-mail și pentru confirmarea parolei. Eticheta <input> anunța un câmp
ce va conține date de intrare care se așteaptă să fie introduse de utilizator. Tipul " text" este cel
mai comun, fiind folosit pentru șiruri de caractere de un rând, iar tipul "password" maschează
caracterele pentru a nu fi vizibile la introducere. ID-ul fiecărui câmp de input este esențial pentru
referirea datelor în script-ul de procesare. În caz că utlizatorul are deja un cont, este invitat să
urmărească link-ul pentru autentificare:
<p> Already a member?</p>
<p class="go_and_login" > <a href="https://127.0.0.1/login/login.html" class="button2" >Log
in</a></p>
Informațiile trimise prin metoda POST sunt invizibile (toate șirurile de caractere introduse în
câmpuri sunt incorporate în secțiunea body a cererii HTTP). Ne dorim acest lucru pentru a nu
face vizibile aceste informații în URL-ul paginii. Ele sunt recepționate în variabila superglobala
(vector) $_POST, și pot fi accesate de oriunde că elemente ale acestui vector.
Toate informațiile vor fi procesate de un script definit în fișierul connection1.php, pe care îl voi
explica pe secțiuni mai jos:
Se realizează conexiunea la baza de date "login", așa cum s-a explicat în paragraful 3.4.1 , iar în
caz de eșec se afișează un mesaj de eroare. Se definește funcția de înregistrare a unui cont nou în
baza de date:
41
function SignUp(){
if(!empty($_POST['user'])) {
$query = mysql_query("SELECT * FROM user WHERE username = '$_POST[user]'") or
die(mysql_error());
if(!$row = mysql_fetch_array($query) ){
NewUser();
}
else echo 'exist'
;
}
}
Id-ul câmpului unde utilizatorul își scrie username-ul ales este folosit pentru a acesa valoarea sa
din variabila $_POST['user']. Se verifică dacă acesta nu este NULL, și în caz afirmativ, se
verifică dacă utilizatorul există deja în baza de date. Dacă da, se va afișa un mesaj corespunzător,
iar dacă nu, se crează o funcție de înregistrare a unui nou utilizator:
function NewUser(){
$fullname = mysql_real_escape_string(htmlspecialchars(trim($_POST['name'])));
$username =mysql_real_escape_string(htmlspecialchars(trim($_POST['user'])));
$password = mysql_real_escape_string(htmlspecialchars(trim($_POST['pass'])));
$email = mysql_real_escape_string(htmlspecialchars(trim($_POST['email'])));
$query = "INSERT INTO user (username, password, fullname, email) VALUES
('$username','$password', '$fullname', '$email')";
Codul AJAX se execută la apăsarea butonului "Sign Up" amintit mai sus. Prin metoda HTTP
POST, va trimite o alertă pe pagină care semnalizează rezultatul procedurii de autentificare, iar
în caz de succes face redirecționarea pe pagina redirect.php.
42
5.2.2 Implementarea unui formular de autentificare (login)
Procedeul de login este asemănător cu cel de înregistrare, cu diferența că acest formular permite
și păstrarea utilizatorului logat cu ajutorul unei sesiuni PHP: start_session();.Detalii despre
acestea se găsesc în paragraful 3.3.6. Codul HTML pentru afișarea paginii de autentificare este
realizat în aceeași manieră ca cel de înregistrare. Modul de verificare a numelui și a parolei se
face prin consultarea tabelei "user", folosind interogarea următoare:
$qry = "SELECT * FROM user WHERE username='".$username."' AND password='".$password."' ";
$res = mysql_query($qry);
Se foloseste metoda HTTP POST iar script-ul de procesare este process.php, ce va fi descris prin
urmatoarea organigrama:
Pornirea sesiunii
session_start()
Salvarea datelor
utilizatorului,
eliminarea
caracterelor “\”
Conectarea la
tabela de date
Cautarea
utilizatorului in
tabela “user”
nu Utilizatorul a da
fost gasit
Redirectionarea
pe alta pagina prin
transmiterea
unui header si
oprirea executiei
scriptului
Folosind mecanismul sesiunilor oferit de PHP, datele rămân persistente și disponibile altor
pagini, astfel că se poate verifica la orice accesare dacă utilizatorul este autentificat sau nu.
Dacă utilizatorul a solicitat să fie deconectat (logout), se apelează:
if(isset($_GET['logout'])){
session_unset();
session_destroy();
header("Location: login.html");}
43
Și acestui script i-a fost adăugat un fișier AJAX având același scop ca și mai înainte, și anume
informarea utilizatorului despre autentificarea cu succes
printr-o notificare, fără a fi nevoie de o reîncărcare a paginii
web.
Design-ul celor două formulare a fost creat prin adăugare de
pagini de stiluri (CSS).
Modificarea aspectului formularului:
#frm{
border: solid gray 2px;
width: 20%;
border-radius: 5px;
margin: auto auto;
background-color: rgba(255, 255, 255, 0.5);
padding: 75px;
}
}
else echo 'User not found';
} ;
45
Fig. 30 Pagina de start a platformei
Pentru a putea folosi funcționalitățile, este necesară înregistrarea și apoi autentificarea. După
realizarea acestor operațiuni, utilizatorul este redirecționat pe pagina principală a platformei, de
unde poate gestiona senzorii și își poate vizualiza alertele.
46
Fig. 32 Pagina principală a platformei
47
Se aplică apoi elemente de grafică, precum poziția textului în spațiul destinat lui, culoarea sa,
culoarea fundalului, centrarea sa, colorarea fiecărei secțiuni în albastru la deplasarea cursorului
pe respectiva secțiune, etc. Toate acestea sunt descrise în pagină de stiluri CSS.
Primul pas în procesul de gestionare al senzorilor de gaz este adăugarea unui dispozitiv pe
platformă. A fost creată cu ajutorul stilurilor CSS o fereastră-formular modulară (modal form) ,
care se deschide atunci când utilizatorul apasă Manage sensors - Add sensor in meniul orizontal.
Codul care face fereastra să apăra este implementat în JavaScript:
var modal = document.getElementById('id01');
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
iar accesarea acesteia se face funcția JavaScript onclick și prin selectarea sa după id-ul
elementului.
<button class="button1" onclick="document.getElementById('id01').style.display='block'"
style="width:auto;">Add sensor</button>
/* Fundalul */
.modal {
display: none; /* ascuns in mod prestabilit */
position: fixed; /* pozitie fixa */
z-index: 1;
left: 0;
top: 0;
width: 100%; /* laxime maxima */
height: 100%; /* inaltime maxima */
overflow: auto; /* activare derulare pagina */
background-color: rgb(0,0,0); /* culoare de fundal alba */
background-color: rgba(0,0,0,0.4); /* opacitate */
padding-top: 60px;
}
/* setari generale buton */
button {
background-color: #333;
48
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
cursor: pointer;
width: 100%;
}
.cancelbtn {
width: auto;
padding: 10px 18px;
background-color: #f44336;
}
.close {
position: absolute;
right: 25px;
top: 0;
color: #000;
font-size: 35px;
font-weight: bold;
}
Câmpul "Sensor ID" trebuie completat cu codul unic "deveui" , de 16 caractere, înscris pe orice
dispozitiv LoRa (detalii despre acesta se găsesc în paragraful 5.1.3), iar câmpul "Comment" oferă
posibilitatea de a vedea mai multe amănunte despre respectivul senzor.
La apăsarea butonului "Proceed" se execută codul "addsensor.php".
$sensor_id = $_POST['sensor_id'];
$sensor_id2 = hexdec($sensor_id);
$comm =mysql_real_escape_string(htmlspecialchars(trim($_POST['comm'])));
$currentuser= $_SESSION['username'];
$currentid= $_SESSION['id'];
if(!empty($_POST['sensor_id'])) {
$query = "INSERT INTO sensor (sensor_id, comment, user_id) VALUES
('$sensor_id2','$comm', '$currentid')";
$data = mysql_query ($query)or die(mysql_error());
if($data) {....}
};
Prima parte a codului nu a mai fost inclusă aici, ea reprezentând conectarea la baza de date care
se face așa cum a mai fost prezentat anterior. În urma acesteia, se obțin valorile introduse de
utilizator în câmpuri, prin metoda HTTP POST, și de asemenea se salvează numele și ID-ul user-
ului din variabilele de sesiune. Acestea sunt folosite apoi în interogarea MySQL de inserare a
senzorului în tabela "sensor", descrisă în figura de mai jos.
49
Fig. 35 Tabela "sensor"
În codul prezentat anterior , la îndeplinirea condiției din if($data) {....} , a fost inclusă și
adăugarea senzorului pe serverul inteliLIGHT, prin apelarea unui API de la sursa [ 65]
Comanda de adăugare se regăsește în instrucțiunile:
$data2='{
"op": "mod_add",
"deveui": "' . $sensor_id . '",
"devaddr": "11223344"
}';
fwrite($sock, my_encode($data2)) or die('error:' . $errno . ':' . $errstr);
if ($result->num_rows > 0) {
echo "<table><tr><th>Sensor ID</th><th>Comment</th></tr>";
while($row = $result->fetch_assoc()) {
echo "<tr><td>" . $row["sensor_id"]. "</td><td>" . $row["comment"]. " </td></tr>";
}
echo "</table>";
50
} else {
echo "0 results";
}
$conn->close();
if(!empty($_POST['sensor_id'])) {
$query1 = mysql_query("SELECT * FROM sensor WHERE sensor_id =
'$_POST[sensor_id]'") or die(mysql_error());
if(!$row = mysql_fetch_array($query1) ){
echo 'Sensor id not found';
header( "refresh:2; url=editsensor.php" }
else {
$query2 = mysql_query("UPDATE sensor set comment='" . $_POST["comment"]
. "' WHERE sensor_id = '$_POST[sensor_id]' ") or die(mysql_error());
header( "refresh:2; url=editsensor.php" );
echo "Sensor updated";
}
}
else echo "Type a sensor ID";
if(!empty($_POST['sensor_id'])) {
$sensor_id2 = bcdechex($_POST['sensor_id']);
$query1 = mysql_query("SELECT * FROM sensor WHERE sensor_id =
'".$_POST['sensor_id']."' ") or die(mysql_error());
if(!$row = mysql_fetch_array($query1) ){
echo 'Sensor id not found';
header( "refresh:2; url=deletesensor.php" );} }
else {
$query2 = mysql_query("DELETE FROM sensor WHERE sensor_id =
'".$_POST['sensor_id']."' ") or die(mysql_error());
51
Prin folosirea API-ului de la adresa [ 65 ], în cod au
fost incluse și instrucțiunile de conectare la serverul
LoRa și eliminarea modulului de detecție a gazelor:
//del module
$data2='{
"op": "mod_del",
"deveui": "' . $sensor_id2 . '"
"devaddr": "11223344"
}';
fwrite($sock, my_encode($data2)) or die('error:' .
$errno . ':' . $errstr);
5.3.4 Grupuri
Am creat posibilitatea ca un utilizator să poată gestiona grupuri în care să adauge senzori pe care
dorește să îi poată face vizibili și altor utilizatori. Acest lucru este util dacă se dorește partajarea
senzorilor între mai mulți utilizatori, sau monitorizarea acestora de pe mai multe conturi.
Grupurile și senzorii conținuți de acestea sunt vizibile oricui, indiferent dacă utilizatorul
autentificat în momentul prezent îi are sau nu atașați propriului cont.
La accesarea paginii de grupuri se afișează un tabel cu grupurile existente, urmat de un formular
în care se poate alege crearea, ștergerea sau vizualizarea conținutului unui grup.
52
La selectarea vizualizării unui grup, va fi afișat un tabel cu toți senzorii aparținând acelui grup.
Utilizatorul are posibilitatea de a adăuga unul din senzorii grupului în propriul cont, prin
completarea unui formular unde va preciza ID-ul senzorului dorit, urmând apoi să poată primi
alerte de la acesta.
În partea stânga a paginii se află un meniu vertical de navigare, vizibil la apăsarea butonului
"Open Navigation". Utilizatorul poate adăuga anumiți sau toți senzorii deținuți într-unul din
grupuri sau îi poate șterge.
Procedurile de adăugare și ștergere a senzorilor sau de creare și eliminare a grupurilor se fac în
aceeași manieră prezentată anterior. Maparea grupurilor în baza de date MySQL am realizat-o
prin două tabele:
tabela sgroup , ce ține evidența grupurilor și are câmpurile id (cheie primară) și name
tabela sensor_group, care ține evidența senzorilor din interiorul grupurilor. Câmpurile
sale sunt id (cheie primară), sensor_id și group_id. Corespondența se face prin ultimele
două câmpuri, astfel că fiecare linie a tabelului este un senzor având un anumit sensor_id
și face parte dintr-un anume grup identificat prin group_id.
53
Fig. 42 Conținutul și structura tabelei sensor_group
54
Pachetul de date trimis, semnificând o alertă de gaz, are următoarea structură:
"{\"op\": \"push\", \"deveui\": \"0004a30b001b7f29\", \"port\": 1, \"count\": 2041,
\"payload\": \"47415320414c4552542\", \"ts\": 1496005078}"
și este stocat într-o variabilă globală myMessage și va fi procesat ca un JSON din care vom extrage
datele de interes: ID-ul senzorului (deveui), tipul alertei (payload) și momentul de timp
"timestamp" (ts).
În codul nodejs de conectare la server inteliLIGHT, am adăugat secțiunea răspunzătoare de
crearea serverului aplicației web și a unui socket prin librăria socket.io, care sunt necesare la
obținerea și livrarea mesajului către clienții HTML (ferestrele de browser deschise)-ce vor fi
modelați prin vectorul clients.
Socket.io este o librărie JavaScript pentru aplicații web de timp real. Validează comunicarea în
timp real, declanșată de evenimente și bidirecțională între clienți și servere, și are două părți: o
sublibrarie pentru client ce va rula în browser și o sublibrarie pentru server. Pentru partea de
server, am creat un server HTTP care ascultă pe portul 30222 și care va trimite mesaje prin
PUSH notification către toți clienții conectați.
Din punctul de vedere al aplicației web, utilizatorul este portretizat ca o pagină web HTML-un
client HTML. Pentru partea aceasta, în codul HTML al paginii principale a platformei, se adaugă
următoarele instrucțiuni:
se crează o instanță socket.io a clientului
în caz de conectare a unui client : se afișează în browser un mesaj de anunțare a
conectivității
în caz de recepționare mesaj de alertă de la serverul aplicației web:
folosind câmpul deveui din mesaj și având stocate toate ID-urile senzorilor
utilizatorului autentificat în momentul prezent, se verifică dacă mesajul
recepționat este de la unul din senzorii deținuți de acesta
folosind câmpul payload, se verifică dacă tipul mesajului este GAS
ALERT
55
dacă ambele condiții sunt îndeplinite:
se afișează în browser un mesaj de alertă gaz
se stochează datele despre alertă în baza de date
se trimite un email utilizatorului cu o notificare
în caz de întrerupere a conexiunii: se afișează în browser un mesaj de anunțare a deconectării
clientului.
Toate punctele vor fi detaliate mai jos.
56
Fig. 44 Pagina principală cu alerta de gaz
Am extras toate ID-urile senzorilor deținuți de utilizatorul autentificat în momentul prezent din
variabila de sesiune $_SESSION['sensors'] , pentru a face verificarea dacă senzorul care a generat
o alertă aparține utilizatorului.
<?php
session_start();
if (isset($_SESSION['sensors'])) {
$array= $_SESSION['sensors'];
} else $array=0; ?>
57
Vectorul $array îl voi folosi în scriptul corespunzător tratării alertelor:
var vector = <?php echo json_encode($array);?>;
var flag =0;
var senzor;
var parsedJSON = JSON.parse(data);
for (i = 0; i < vector.length; i++) {
if (zeroFill(d2h(vector[i]),16) == parsedJSON.deveui){
flag= 1;
senzor = vector[i];
console.log("this is a owned sensor");
}
}
Am salvat în variabile separate câmpurile de interes , ale căror valori urmează să le întroduc în
tabela alert.
}
});
Dacă condiția de a fi primit o alertă de gaz din partea unui senzor deținut este îndeplinită, am
afișat alerta în browser și am folosit un cod numit ajax.php pentru a face adăugarea datelor în
mod automat, printr-un XMLHttpRequest. XMLHttpRequest (prescurtat XHR) este un API în
forma unui obiect care dispune de metode pentru transmiterea datelor între un browser și un
server , fără a mai fi nevoie de vreo intervenție a utilizatorului. Extragerea datelor din XHR în
scopul de a modifica o pagină web deja încărcată are la bază același concept ca al unui cod
AJAX. Chiar dacă denumirea API-ului include "XML", aceasta nu este singura formă de
trimitere a datelor, ci se poate folosi și JSON, HTML sau text simplu.
Metoda "open" se folosește pentru a inițializa o cerere HTTP de a folosi un obiect XHR. Primul
parametru specificat este metoda HTTP aplicată pentru trimiterea cererii. În cazul de față ,
metodă este GET. Al doilea parametru este un șir de caractere specificând URL-ul cererii.
58
Am menționat în URL valorile despre alertă pe care doresc să le trimit scriptului ajax.php,
împreună cu acesta. Al treilea parametru este o valoare boolean care specifică dacă cererea este
una sincronă sau asincronă. Precizarea "true" semnifică o cerere asincronă, care nu va aștepta
niciun răspuns din partea serverului și va continua cu execuția scriptului.
Metoda "send" trimite efectiv cererea către server.
În scriptul ajax.php, se folosește corespunzător metoda GET pentru obținerea datelor despre o
alertă:
session_start();
mysql_connect("127.0.0.1", "root", "password16");
mysql_select_db("login");
$deveui = mysql_real_escape_string($_GET['deveui']);
$payload = mysql_real_escape_string($_GET['payload']);
$ts = mysql_real_escape_string($_GET['ts']);
$odata= date('Y-m-d H:i:s', $ts);
Inserarea efectivă a acestora în tabela alert se face prin executarea unei interogări MySQL
$query = mysql_query("INSERT INTO alert (sensor_id, type, startdate) VALUES
('$deveui','$payload', '$odata')") or die(mysql_error());
to - destinatarul
subject - un șir de caractere specificând subiectul mailului
txt - corpul mailului
headers - parametru opțional, pentru a specifica destinatari de tipul CC sau BCC, precum
și expeditorul
parameters - parametrul adițional, poate fi utilizat pentru a transmite fanioane
suplimentare programului configurat pentru a transmite poșta, definit de opțiunea de
configurare sendmail_path. Spre exemplu, acesta poate fi utilizat pentru a stabili adresa
expeditorului de pe plic când se utilizează sendmail cu opțiunea -f.
Pentru ca funcția PHP mail () să funcționeze, este nevoie de instalarea și configurarea unui server
de email. Am folosit serverul hMailServer , în care am configurat domeniul 127.0.0.1, internetul
ca gateway default 0.0.0.0, protocoalele SMTP, IMAP și POP3 și o adresă de mail validă de pe
care să fie trimise mesajele.
59
Fig. 46 Configurare server email
Odată configurat acest server SMTP, funtia mail() livrează mai departe emailul către server
pentru transmiterea către destinatar folosind Simple Mail Transfer Protocol. Livrarea de emailuri
, la oa actuală, prezintă mult mai multe cerințe decât poate funcția PHP să satisfacă, punându-se
accentul pe securitate și blocarea mesajelor de spam, dar în lucrarea prezentă am dorit să
demonstrez funcționalitatea livrării unei alerte pe email către un utilizator în timp real, la un
nivel de bază. Funcția PHP se comportă ca o căsuță poștală: se uită la adresa serverului de mail
indicată în fișierul de configurări php.ini, realizează apoi o conexiune cu serverul hMailServer
folosind în mod predefinit TCP și portul 25, îi trimite mesajul acestuia, iar serverul de mail:
60
Exemplu de email recepționat:
Fig. 48 Notificări
61
Pașii implementării codului pentru această funcționalitate sunt:
se selectează toate informațiile din tabela alerts despre acele alerte aparținând senzorilor
deținuți de utilizator
if ($_SESSION['sensors'] !== 0) {
$array= $_SESSION['sensors'];
$ids = join("','",$array);
$sql = "SELECT alert_id , sensor_id, type, startdate FROM alert WHERE sensor_id IN
('$ids')";
//...
}
dacă au fost găsite rezultate, se genreaza în mod dinamic o secțiune <div></div> în codul
HTML al paginii pe care au fost aplicate un anumit design folosind CSS, și se definește
un vector care va conține codurile colorilor pe care le vom folosi la afișare
if ($result->num_rows > 0) {
echo '<div class="col-container">';
$count =$result->num_rows;
$colors = ['#bf9f40', '#dfaf20', '#dfdf20', '#d9d926', '#ffff00', '#ffbf00',
'#ff8000', '#e67300' ,'#d95326', '#d95326', '#ff4000', '#d92626', '#ff0000', ];
$currentIndex = 0;
cât timp există alerte neafisate (interogarea MySQL conține un rezultat), se încapsulează
detaliile despre această în secțiunea ei <div> corespunzătoare. Vizual, notificările sunt
aranjate una după alta, cronologic, ca o linie a unui tabel.
} else echo "0 results"; // daca interogarea MySQL n-a gasit rezultate
} else echo "No sensors"; //daca variabila superglobala $_SESSION['sensors'] nu contine nimic
De asemenea, alte informații despre alerte mai pot fi vizualizate sub formă de grafice, pe care
utilizatorul le accesează din meniul "Graphs" al meniului orizontal principal. Am creat două
astfel de reprezentări. Submeniul "View graphs" deschide o pagină în care se pot vedea senzorii
care au generat alerte până în momentul prezent și numărul de alerte per senzor, oferind o
imagine de ansamblu asupra evoluției sistemului de monitorizare.
62
Fig. 49 Grafic număr de alerte în funcție de senzor
Submeniul "Alerts in time" oferă o viziune în timp asupra alertelor fiecărui senzor. Se deschide o
pagină de unde utilizatorul vede senzorii deținuți și selectează unul dintre ei. Pentru acesta i se
va afișa mai jos un grafic cu momentele de timp ale tuturor alertelor generate de senzorul
selectat.
63
6. Concluzii și dezvoltări viitoare
Tehnologiile moderne de comunicații și detecție au permis dezvoltarea unor sisteme performante
de monitorizare și alarmare. Scopul prezentei lucrări a fost acela de a realiza un modul
experimental pentru monitorizarea unor senzori de gaz ce folosesc tehnologia LoRa pentru
transmiterea informațiilor sau alertelor. De asemenea, s-au utilizat tehnici de programare
orientată către servere (server scripting) pentru implementarea funcționalității și limbajele pentru
interfațarea web, de tip HTML, CSS și JavaScript. Arhitectura sistemului propus cuprinde un
senzor de gaz, gateway LoRa, server LoRa, server de aplicație și clientul HTML (utilizatorul).
Un nivel de noutate deosebit, pe care tehnologia LoRa îl aduce este acela de a elimina
infrastructura de comunicații bazată pe conductoare fizice (sau fibră optică), ceea ce produce
importante economii de materiale, manoperă și energie. De asemenea, nivelul de securitate este
asigurat parolă și username criptate, dar pentru aplicații pe scară largă de tip industrial se pot
prevedea măsuri suplimentare pentru creșterea protecției.
Se poate afirma că realizarea acestei teme a constituit o provocare tehnică de nivel înalt, dat fiind
faptul că în timpul facultății nu am însușit cunoștințe extinse privind mediile de programare
orientate către web design, lucrul la acest proiect necesitând un număr semnificativ de ore de
pregătire și căutare de informații. Cu toate acestea, rezultatul scontat a fost atins, rămânând însă,
ca dezvoltări viitoare, crearea aplicației pentru platforma Android, pentru a putea administra
toate operațiile de pe un smart phone.
Noile oportunități introduse de tehnologiile de comunicații wireless de tip LoRa WAN crează
elementele necesare extinderii sistemelor de telemăsură, telecontrol și alarmare, permițând
accesul mobil la numeroase facilități de programare, monitorizare și informare privind sistemele
senzoriale instalate în cele mai diverse aplicații.
64
Bibliografie
65
[ 32 ] Colin Davidson, Holographic sensors for aeropspace applications,
http://www.ceb.cam.ac.uk/research/groups/rg-healthcare-biotechnology/research-themes/biosensors-
diagnostics/holo-sensors accesat pe 29.11.2016
[ 33 ] Reteaua nationala de mnonitorizare a calitatii aerului, http://www.anpm.ro/ro/reteaua-nationala-de-
monitorizare-a-calitatii-aerului/ accesat pe 01.11.2016
[ 34 ] Environment and climate change, Canada https://www.ec.gc.ca/air-sc-r/default.asp?lang=En&n=C87142DF-1
accesat pe 01.11.2016
[ 35 ] Statii de monitorizare a gazelor, http://www.multilab.ro/gaze/monitoare_gaze.html 03.11.2016
[ 36 ] Ce trebuie sa stim despre un sistem de alarma? , mai 2014 , http://www.supraveghere24.ro/3-notiuni-de-baza-
despre-un-sistem-de-alarma accesat pe 03.11.2016
[ 37 ] K.J.Braxton, Patent US4141006A, US05/705,357
[ 38 ] Gas detection gets smart, http://www.ishn.com/articles/104117-gas-detection-gets-smart accesat pe
07.11.2016
[ 39 ] Dann Albright, 6 smart sensors that protect your family and property from harm, iunie 2015 ,
http://www.makeuseof.com/tag/6-smart-detectors-protect-family-property-harm/ accesat pe 07.11.2016
[ 40 ] Laurentiu Ionescu , Kepler: detector de gaz, octombrie 2015, http://smartiot.ro/noutati/kepler-detector-de-gaz/
07.11.2016
[ 41 ] Cum alegi un detector de gaz bun, http://clovis.ro/casa-gradina/supraveghere-securitate/cele-mai-bune-
detectoare-de-gaz/ accesat pe 07.11.2016
[ 42 ] Joaquin del Rio, Remote control and monitoring of fire alarm systems,
http://upcommons.upc.edu/bitstream/handle/2117/
11354/REMOTE%20CONTROL%20AND%20MONITORING%20OF%20FIRE%20ALARM%20SYSTEMS.pdf?
sequence=1 accesat pe 08.11.2016
[ 43 ] Cornel Mironel Niculae, Modelul client server, martie 2008,
http://fpce9.fizica.unibuc.ro/telecom/m_cl_sv.htm accesat pe 25.11.2016
[ 44 ] Aplicatii de retea. Socluri. URL,
https://www.ms.sapientia.ro/~manyi/teaching/oop/oop_romanian/curs9/curs9.html accesat pe 25.11.2016
[ 45 ] What is a socket? , https://www.tutorialspoint.com/unix_sockets/what_is_socket.htm accesat pe 25.11.2016
[ 46 ] What is a socket? , https://docs.oracle.com/javase/tutorial/networking/sockets/definition.html accesat pe
25.11.2016
[ 47 ] HyperText Markup Language , https://ro.wikipedia.org/wiki/HyperText_Markup_Language accesat pe
01.12.2016
[ 48 ] Alexandru Chirvasa, Ce inseamna frontend si ce inseamna backend?
http://webblog.bestwebimage.ro/2014/06/ce-inseamna-front-end-si-ce-inseamna-back-end/ accesat pe 01.12.2016
[ 49 ] Ava Garcia, The importance of visual consistency in UI design, noiembrie 2015
http://www.uxpassion.com/blog/the-importance-of-visual-consistency-in-ui-design/ accesat pe 01.12.2016
[ 50 ] Drew Wutca, Susan Harkins, Ten reasons to turn your Access applications into Web applications, aprilie
2008, http://www.techrepublic.com/blog/10-things/10-reasons-to-turn-your-access-applications-into-web-
based-applications/ 07.12.2016
[ 51 ] Server side scripting languages, https://en.wikipedia.org/wiki/Server-side_scripting#Languages accesat pe
29.12.2016
[ 52 ] Introducere in limbajul Python, http://cs.curs.pub.ro/wiki/asc/asc:lab1:index accesat pe 29.12.2016
[ 53 ] AJAX Introduction, https://www.w3schools.com/xml/ajax_intro.asp accesat pe 29.12.2016
[ 54 ] Server -side languages , https://www.codeschool.com/beginners-guide-to-web-development/server-side-
languages accesat pe 29.12.2016
[ 55 ] Server side scripting, https://en.wikipedia.org/wiki/Server-side_scripting accesat pe 29.12.2016
[ 56 ] PHP Introduction, https://www.w3schools.com/php/php_intro.asp accesat pe 29.12.2016
[ 57 ] Node.js, https://en.wikipedia.org/wiki/Node.js accesat pe 29.12.2016
[ 58 ] Callback, https://en.wikipedia.org/wiki/Callback_(computer_programming) accesat pe 29.12.2016
[ 59 ] Callbacks, http://forum.sa-mp.com/showthread.php?t=342242 accesat pe 14.01.2017
[ 60 ] Traian Anghel, Programarea Web pentru liceu, editura Polirom, 2008
[ 61 ] A technical overview of LoRa® and LoRaWAN,
https://www.lora-alliance.org/portals/0/documents/whitepapers/LoRaWAN101.pdf accesat pe 23.01.2017
[ 62 ] http://www.flashnet.ro/project/intelilight/ accesat pe 27.06.2017
[ 63 ] What is LoRa? http://www.atim.com/en/technologies-2/lorawan/ accesat pe 10.02.2017
66
[ 64 ] Cleidson R. B. de Souza, David Redmiles, Li-Te Cheng, Sometimes You Need to See Through Walls — A
Field Study of Application Programming Interfaces,
http://watsonweb.watson.ibm.com/cambridge/Technical_Reports/2004/TR2004-14.pdf accesat pe 02.05.2017
[ 65 ] http://fc1.intelilight.eu:59080/docapi. accesat pe 27.06.2017
[ 66 ] Proiectul Alba Iulia – Smart City, varianta Orange. Hotspoturi wi-fi, senzori de monitorizare a calităţii
aerului şi aplicaţie mobilă pentru cetăţeni, octombrie 2016, http://alba24.ro/proiectul-alba-iulia-smart-city-varianta-
orange-hotspoturi-wi-fi-senzori-de-monitorizare-a-calitatii-aerului-si-aplicatie-mobila-pentru-cetateni-527433.html
accesat pe 02.05.2017
[ 67 ] Interfacing with LoRaWAN,
https://assets.lairdtech.com/home/brandworld/files/Interfacing%20with%20LoRaWAN%20-%20RM186.pdf accesat
pe 02.05.2017
67
Anexa 1
redirect.php
<?php
session_start();
if (isset($_SESSION['sensors'])) {
$array= $_SESSION['sensors'];
} else $array=0;
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-
transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!--info despre document-->
<title>InsideAcc</title>
<link rel="stylesheet" type="text/css" href="styleaddsensormodal.css">
<link rel="stylesheet" type="text/css" href="styleredirect.css">
<script type="text/javascript" src="script/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="script/scriptbuton.js"></script> <!--script de la add sensor button-->
<h2> <img src="img_avatar3.png" alt="Avatar" class="avatar" align="middle"> Welcome</h2>
<?php
echo $_SESSION['username'];
?>
<h2 align="center"> Administrative Area</h2>
<style>
.....
</style>
</head>
<body>
<ul>
<li class="dropdown">
<a href="#" class="dropbtn" >Personal settings</a>
<div class="dropdown-content">
<a href="https://127.0.0.1/login/change_pass/change_pass.html">Change password</a>
<a href="https://127.0.0.1/login/change_email/change_email.php">Change email adress</a>
</div>
</li>
<li class="dropdown" >
<a href="#" class="dropbtn" >Manage sensors</a>
<div class="dropdown-content">
<button class="button1" onclick="document.getElementById('id01').style.display='block'"
style="width:auto;">Add sensor</button>
<a href="https://127.0.0.1/login/deletesensor.php">Remove sensor</a>
<a href="https://127.0.0.1/login/editsensor.php">Edit sensor</a>
<a href="https://127.0.0.1/login/groups.php">Groups</a>
</div>
</li>
<li><a href="https://127.0.0.1/login/notifhtml.php">Notifications</a></li>
<li class="dropdown">
<a href="#" class="dropbtn">View data</a>
<div class="dropdown-content">
<a href="http://127.0.0.1/login/graph.php">View graphs</a>
<a href="http://127.0.0.1/login/graphintime.php">Alerts in time</a>
</div>
</li>
<li><a href="process.php?logout=1">Logout</a></li>
</ul>
<div class="clr"></div>
<div id="wrapper">
<img src="mainpic_redirect.jpg" width="1400" height="490" alt="mainpic_redirect" />
</div>
<!--aici e sectiunea pentru butonul din manage sensors-->
<div id="id01" class="modal">
<form class="modal-content animate" method="POST" action="addsensor.php">
<div class="imgcontainer">
<span onclick="document.getElementById('id01').style.display='none'" class="close" title="Close
Modal">×</span>
</div>
69
<div class="container">
<label><b>Sensor ID</b></label>
<input type="text" placeholder="ID must have 16 characters" id= "sensor_id" name="sensor_id"
required>
<label><b>Comment</b></label>
<input type="text" placeholder="Enter more info" id="comm" name="comm" >
<button type="submit">Proceed</button>
</div>
<div class="container" style="background-color:#f1f1f1">
<button type="button" onclick="document.getElementById('id01').style.display='none'"
class="cancelbtn">Cancel</button>
</div>
</form>
</div> <!--incheiere sectiune buton-->
<p class="bottom" > </p></br>
</body>
<script src="http://127.0.0.1:30222/socket.io/socket.io.js"></script>
<script>
// Create a Socket.IO instance, passing it our server
function d2h(d) { return (+d).toString(16); };
function zeroFill( number, width )
{ width -= number.length;
if ( width > 0 )
{ return new Array( width + (/\./.test( number ) ? 2 : 1) ).join( '0' ) + number; }
return number + ""; // always return a string
};
function h2d(s) {
function add(x, y) {
var c = 0, r = [];
var x = x.split('').map(Number);
var y = y.split('').map(Number);
while(x.length || y.length) {
var s = (x.pop() || 0) + (y.pop() || 0) + c;
r.unshift(s < 10 ? s : s - 10);
c = s < 10 ? 0 : 1; }
if(c) r.unshift(c);
return r.join('');
}
70
console.log(typeof parsedJSON.deveui);
console.log(parsedJSON.payload);
for (i = 0; i < vector.length; i++) {
console.log(zeroFill(d2h(vector[i]),16));
console.log(vector[i]);
if (zeroFill(d2h(vector[i]),16) == parsedJSON.deveui){
flag= 1;
senzor = vector[i];
console.log("am intrat in flag egal 1");
}
} // de la for
var deveui = senzor;
var payload;
var payload2 = h2d(parsedJSON.payload);
var ts = parsedJSON.ts;
if (parsedJSON.payload =='47415320414c45525421') {payload = 2;} //gaz
if (parsedJSON.payload =='486561727462656174') {payload = 1;} //heartbeat
if (parsedJSON.payload == '47415320414c45525421'&& flag ==1){
console.log("gaz");
document.body.innerHTML += '<div class="alert warning fixed"><span
class="closebtn" onclick="this.parentNode.parentNode.removeChild(this.parentNode); return
false;">×</span><p>GAS ALERT</p></div>';
if (window.XMLHttpRequest) {xmlhttp = new XMLHttpRequest();}
xmlhttp.open("GET", "ajax.php?deveui=" + deveui + "&payload=" + payload +
"&ts=" + ts , true);
xmlhttp.send();
console.log("date adaugate si email trimis ");
ajax.php
<?php
session_start();
date_default_timezone_set ('Europe/Bucharest' );
mysql_connect("127.0.0.1", "root", "password16");
mysql_select_db("login");
$deveui = mysql_real_escape_string($_GET['deveui']);
$payload = mysql_real_escape_string($_GET['payload']);
$ts = mysql_real_escape_string($_GET['ts']);
$odata= date('Y-m-d H:i:s', $ts);
$query = mysql_query("INSERT INTO alert (sensor_id, type, startdate) VALUES ('$deveui','$payload',
'$odata')") or die(mysql_error());
$to = $_SESSION['email'];
$subject = "ALERT";
$txt = "You have an ALERT from sensor " . $deveui . " received at " . $odata;
$headers = "From: iwanttomakeatest16@gmail.com" . "\r\n" .
"CC: mineav08@gmail.com";
mail($to,$subject,$txt,$headers);
?>
codconectareinnodejsfinal.js
var host = 'fc1.intelilight.eu'; // same as the FC web interface port
var port = 59080; // same as the FC web interface port
var user = 'viviana';
var pass = 'viviana1';
var myMessage = null;
var clients = [];
var WebSocketClient = require('websocket').client;
var http = require('http');
71
var clientIntelilight = new WebSocketClient();
clientIntelilight.on('connectFailed', function(error) {
console.log('Connect Error: ' + error.toString());
});
clientIntelilight.on('connect', function(connection) {
console.log('WebSocket Client Connected');
connection.on('error', function(error) {
console.log("Connection Error: " + error.toString());
});
connection.on('close', function() {
console.log('echo-protocol Connection Closed');
});
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log("Received: '" + JSON.stringify(message.utf8Data) + "'");
myMessage = JSON.stringify(message.utf8Data);
myMessage2 = message.utf8Data;
myMessage2.replace(/\\/gi, '');
for(var i = 0, len = clients.length; i < len; i++) {
clients[i].emit("message",myMessage2);
}
}
});
function sendLogin() {
if (connection.connected) {
var s='{ "op": "login", "user": "viviana", "pass": "viviana1"}';
connection.sendUTF(s);
}
}
}
sendLogin();
});
clientIntelilight.connect('http://fc1.intelilight.eu:59080/JSON ', null, null, null);
var express = require('express');
var app = express();
var server = app.listen(30222, function(req, res){
console.log('Server listening on 30222');});
var io = require('socket.io')(server);
var bufferutil = require('bufferutil');
io.on('connection', function(socket){
console.info('New client connected (id=' + socket.id + ').');
clients.push(socket);
// When socket disconnects, remove it from the list:
socket.on('disconnect', function() {
var index = clients.indexOf(socket);
if (index != -1) {
clients.splice(index, 1);
console.info('Client gone (id=' + socket.id + ').');
}
});
});
login.html
<!DOCTYPE html>
<html>
<head>
<title> Login Page</title>
<link rel="stylesheet" type="text/css" href="stylelogin.css">
</head>
<body background="plainbackground.jpg">
<div class="imgcontainer">
<img src="img_avatar3.png" alt="Avatar" class="avatar">
</div>
<div id="frm">
<form id="myForm" action="process.php" method="POST">
<p><label> Username:</label>
<input type="text" size="30" id="user" name="user"
placeholder="Username"/> </p>
<p><label> Password: </label>
72
<input type="password" size="30" id="pass" name="pass"
placeholder="Password"/> </p>
<p><button class="button" id="login"> Login</button></p>
<p><input type="checkbox" checked="checked"> Remember me</p>
<p> Not having an account yet?
<a href="https://127.0.0.1/signup/signup.html">Register</a></p>
<p> Go back to <a href="https://127.0.0.1/html-default/index.html">main
page</a></p>
</form>
</div>
<script type="text/javascript" src="script/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="script/scriptlogin.js"></script>
</body>
</html>
process.php
<?php
session_start();
$username = $_POST['user'];
$password = $_POST['pass'];
$username = stripcslashes($username);
$password = stripcslashes($password);
$username = mysql_real_escape_string($username);
$password = mysql_real_escape_string($password);
//connect to the server and select database
mysql_connect("127.0.0.1", "root", "password16");
mysql_select_db("login");
//query the database for user
$qry = "SELECT * FROM user WHERE username='".$username."' AND password='".$password."' ";
$res = mysql_query($qry);
$num_row = mysql_num_rows($res);
$row=mysql_fetch_assoc($res);
if( $num_row == 1 ) {
echo 'Success';
$_SESSION['username'] = $row['username'];
$_SESSION['password'] = $row['password'];
$_SESSION['email'] = $row['email'];
$_SESSION['id'] = $row['id'];
$_SESSION['sensors']=0;
$qry2 = "SELECT * FROM sensor WHERE user_id= '$_SESSION[id]' " ;
$res2 = mysql_query($qry2);
if (!$res2) {die('Could not query:' . mysql_error());
} else { if (mysql_num_rows($res2)){
while ($row2 = mysql_fetch_array($res2)) {$array[] = $row2['sensor_id'];}
$_SESSION['sensors']=$array;
}
}
}
else { echo 'Failed to login';}
if(isset($_GET['logout'])){
session_unset();
session_destroy();
header("Location: login.html");
}
?>
scriptloginajax.js
$(document).ready(function(){
$("#login").click( function() {
var username=$("#user").val();
var password=$("#pass").val();
var dataString="user="+username+"&pass="+password;
alert(dataString);
if($.trim(username).length>0 & $.trim(password).length>0){
$.ajax({
type: "POST",
url: "process.php",
data: dataString,
crossDomain: true,
73
cache: false,
beforeSend: function(){ $("#login").html('Connecting...');},
success: function(data){
$("#login").html('Done');
alert(data);
if(data=="Success"){window.location = "redirect.php";}
else if(data=="Failed"){
alert("Login error");
$("#login").html('Login');}
}
});
}return false;
});
});
signup.html
<!DOCTYPE HTML>
<html>
<head>
<title>Sign Up</title>
<link rel="stylesheet" type="text/css" href="signupstyle.css">
<style>
body {
background: url("plainbackground.jpg ");
background-size: 1600px 1000px;
background-repeat: no-repeat;
}
</style>
</head>
<body>
<div class="imgcontainer">
<img src="newuser.jpg" alt="Avatar" class="avatar">
</div>
<div id="Sign-Up">
<form method="POST" action="connection1.php">
<p> <label>Full name</label>
<input type="text" size="30" id="name" name="name" placeholder="Full Name"/>
</p>
<p> <label>Username</label>
<input type="text" size="30" id="user" name="user" placeholder="Username"/>
</p>
<p> <label>Password </label>
<input type="password" size="30" id="pass" name="pass" placeholder="Password"/>
</p>
<p> <label>Confirm Password </label>
<input type="password" size="30" id = "cpass" name="cpass" placeholder="Password"/>
</p>
<p> <label>Email</label>
<input type="text" size="30" id="email" name="email" placeholder="Email"/>
</p>
<p> <button class="button" id="button"> Sign Up</button>
<p> Already a member?</p> <p class="go_and_login" > <a href="https://127.0.0.1/login/login.html"
class="button2" >Log in</a></p>
</form>
</div>
<script type="text/javascript" src="script/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="script/test.js"></script>
</body>
</html>
connection1.php
<?php
define('DB_HOST', '127.0.0.1');
define('DB_NAME', 'login');
define('DB_USER','root');
define('DB_PASSWORD','password16');
$con=mysql_connect(DB_HOST,DB_USER,DB_PASSWORD) or die("Failed to connect to MySQL: " . mysql_error());
$db=mysql_select_db(DB_NAME,$con) or die("Failed to connect to MySQL: " . mysql_error());
74
function SignUp(){
if(!empty($_POST['user'])) { //checking the 'user' name, is it empty or have some text
$query = mysql_query("SELECT * FROM user WHERE username = '$_POST[user]'") or
die(mysql_error());
if(!$row = mysql_fetch_array($query) ){
NewUser();
}
else echo 'exist';
}}
function NewUser(){
$fullname = mysql_real_escape_string(htmlspecialchars(trim($_POST['name'])));
$username =mysql_real_escape_string(htmlspecialchars(trim($_POST['user'])));
$password = mysql_real_escape_string(htmlspecialchars(trim($_POST['pass'])));
$email = mysql_real_escape_string(htmlspecialchars(trim($_POST['email'])));
$query = "INSERT INTO user (username, password, fullname, email) VALUES ('$username','$password',
'$fullname', '$email')";
$data = mysql_query ($query)or die(mysql_error());
if($data) echo 'success';
else echo 'failed';
}
SignUp();
?>
singupajax.js
$(document).ready(function(){
$("#button").click(function(){
var fullname=$("#name").val();
var username=$("#user").val();
var password=$("#pass").val();
var email=$("#email").val();
var dataString="name="+fullname+"&user="+username+"&pass="+password+"&email="+email;
if($.trim(fullname).length>0 & $.trim(username).length>0 & $.trim(password).length>0 &
$.trim(email).length>0)
{$.ajax({
type: "POST",
url: "connection1.php",
data: dataString,
crossDomain: true,
cache: false,
beforeSend: function(){ $("#button").html('...');},
success: function(data){
console.log(data);
if (data.trim()=='success'){
alert("Success"); $("#button").html('Done'); window.location = "https://127.0.0.1/login/login.html";}
if (data.trim()=='exist'){
alert("You already have an account"); $("#button").html('Sign Up'); window.location =
"https://127.0.0.1/login/login.html";}
if (data.trim()=="failed"){
alert("Something went wrong");}
}
});
}
return false;
});
});
addsensor.php
<?php
session_start();
function bchexdec($hex)
{ $dec = 0;
$len = strlen($hex);
for ($i = 1; $i <= $len; $i++) {
$dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));
}
return $dec;
}
define('DB_HOST', '127.0.0.1');
define('DB_NAME', 'login');
75
define('DB_USER','root');
define('DB_PASSWORD','password16');
$con=mysql_connect(DB_HOST,DB_USER,DB_PASSWORD) or die("Failed to connect to MySQL: " . mysql_error());
$db=mysql_select_db(DB_NAME,$con) or die("Failed to connect to MySQL: " . mysql_error());
$sensor_id = $_POST['sensor_id'];
$sensor_id2 = bchexdec($sensor_id);
$comm =mysql_real_escape_string(htmlspecialchars(trim($_POST['comm'])));
$currentuser= $_SESSION['username'];
$currentid= $_SESSION['id'];
if(!empty($_POST['sensor_id'])) {
$query = "INSERT INTO sensor (sensor_id, comment, user_id) VALUES ('$sensor_id2','$comm', '$currentid')";
$data = mysql_query ($query)or die(mysql_error());
if($data) { codconectareserver();
}
else echo 'Failed';
}
?>
scriptbutonadd.js
// Get the modal
var modal = document.getElementById('id01');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
editsensor.php
<?php
session_start();
?>
<!DOCTYPE html>
<html>
<head>
<style>
...
</style>
</head>
<body>
<?php
$servername = "127.0.0.1";
$username = "root";
$password = "password16";
$dbname = "login";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$currentid= $_SESSION['id'];
$sql = "SELECT sensor_id, comment FROM sensor where user_id='".$currentid."' ";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "<table><tr><th>Sensor ID</th><th>Comment</th></tr>";
// output data of each row
while($row = $result->fetch_assoc()) {
echo "<tr><td>" . $row["sensor_id"]. "</td><td>" . $row["comment"]. " </td></tr>";
}
echo "</table>";
} else {
echo "0 results";
}
$conn->close();
?>
<div id="editsensor">
<form method="POST" action="editsensorconnection.php">
<p> <label>ID of sensor you want to change</label>
76
<input type="text" size="30" id="sensor_id" name="sensor_id" />
</p>
<p> <label>Change comment </label>
<input type="text" size="30" id="comment" name="comment"/>
</p>
<p> <button class="button" id="button"> Proceed</button>
<p> Go back to
<a href="https://127.0.0.1/login/redirect.php">main page</a></p>
</form>
</div>
</body>
</html>
editsensorconnection.php
<?php
define('DB_HOST', '127.0.0.1');
define('DB_NAME', 'login');
define('DB_USER','root');
define('DB_PASSWORD','password16');
$con=mysql_connect(DB_HOST,DB_USER,DB_PASSWORD) or die("Failed to connect to MySQL: " . mysql_error());
$db=mysql_select_db(DB_NAME,$con) or die("Failed to connect to MySQL: " . mysql_error());
if(!empty($_POST['sensor_id'])) {
$query1 = mysql_query("SELECT * FROM sensor WHERE sensor_id = '$_POST[sensor_id]'") or
die(mysql_error());
if(!$row = mysql_fetch_array($query1) ){
echo 'Sensor id not found';
header( "refresh:2; url=editsensor.php" ); //wait for 2 seconds before redirecting}
else {
$query2 = mysql_query("UPDATE sensor set comment='" . $_POST["comment"] . "'
WHERE sensor_id = '$_POST[sensor_id]' ") or die(mysql_error());
header( "refresh:2; url=editsensor.php" ); //wait for 2 seconds before
redirecting
echo "Sensor updated";}
}
else echo "Type a sensor ID";
?>
delsensor.php
<?php
session_start();
?>
<!DOCTYPE html>
<html>
<head>
<style>
...
</style>
</head>
<body>
<?php
$servername = "127.0.0.1";
$username = "root";
$password = "password16";
$dbname = "login";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$currentid= $_SESSION['id'];
$sql = "SELECT sensor_id, comment FROM sensor where user_id='".$currentid."' ";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "<table><tr><th>Sensor ID</th><th>Comment</th></tr>";
// output data of each row
while($row = $result->fetch_assoc()) {
echo "<tr><td>" . $row["sensor_id"]. "</td><td>" . $row["comment"]. " </td></tr>";
77
}
echo "</table>";
} else {echo "0 results";}
$conn->close();
?>
<div id="delsensor">
<form method="POST" action="delsensorconnection.php">
<p> <label>ID of sensor you want to delete</label>
<input type="text" size="30" id="sensor_id" name="sensor_id" />
</p>
<p> <button class="button" id="button"> Proceed</button>
<p> Go back to
<a href="https://127.0.0.1/login/redirect.php">main page</a></p>
</form>
</div>
</body>
</html>
delsensorconnection.php
<?php
session_start();
define('DB_HOST', '127.0.0.1');
define('DB_NAME', 'login');
define('DB_USER','root');
define('DB_PASSWORD','password16');
$con=mysql_connect(DB_HOST,DB_USER,DB_PASSWORD) or die("Failed to connect to MySQL: " . mysql_error());
$db=mysql_select_db(DB_NAME,$con) or die("Failed to connect to MySQL: " . mysql_error());
function bcdechex($dec) {
$hex = '';
do {
$last = bcmod($dec, 16);
$hex = dechex($last).$hex;
$dec = bcdiv(bcsub($dec, $last), 16);
} while($dec>0);
return $hex;
}
if(!empty($_POST['sensor_id'])) {
$sensor_id2 = bcdechex($_POST['sensor_id']);
$query1 = mysql_query("SELECT * FROM sensor WHERE sensor_id = '".$_POST['sensor_id']."' ") or
die(mysql_error());
if(!$row = mysql_fetch_array($query1) ){
echo 'Sensor id not found';
header( "refresh:2; url=deletesensor.php" ); //wait for 2 seconds before redirecting
}
else { $query2 = mysql_query("DELETE FROM sensor WHERE sensor_id =
'".$_POST['sensor_id']."' ") or die(mysql_error());
delfromserver();
}
}
else echo "Type a sensor ID";
?>
notifhtml.php
<?php
session_start();
?>
<!DOCTYPE html>
<html>
<head>
<style>
....
</style>
<?php
$servername = "127.0.0.1";
$username = "root";
$password = "password16";
$dbname = "login";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
78
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
if ($_SESSION['sensors'] !== 0) {
$array= $_SESSION['sensors'];
$ids = join("','",$array);
$sql = "SELECT alert_id , sensor_id, type, startdate FROM alert WHERE sensor_id IN ('$ids')";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$rand1= '<div class="col-container">';
echo $rand1;
$count =$result->num_rows;
$colors = ['#bf9f40', '#dfaf20', '#dfdf20', '#d9d926', '#ffff00', '#ffbf00', '#ff8000',
'#e67300' ,'#d95326', '#d95326', '#ff4000', '#d92626', '#ff0000', ];
$currentIndex = 0;
while ($count > 0) {
$count = $count-1;
$rand2 ='<div class="col" style="background:' . $colors[$currentIndex] . '"><h2> Alert
</h2>';
echo $rand2;
if($row = $result->fetch_assoc()) {
echo "<p> ID: " . $row["alert_id"]. "</p><p> FROM: " . $row["sensor_id"]. "
</p><p> TYPE: " . $row["type"]. "</p><p>" . $row["startdate"]. "</p>";
}
echo "</div>";
if ($currentIndex ==12 ) $currentIndex = 0;
else $currentIndex ++;
}
echo "</div>";
graph.php
<?php
session_start();
include("fusioncharts/fusioncharts.php");
$hostdb = "127.0.0.1"; // MySQl host
$userdb = "root"; // MySQL username
$passdb = "password16"; // MySQL password
$namedb = "login"; // MySQL database name
// Establish a connection to the database
$dbhandle = new mysqli($hostdb, $userdb, $passdb, $namedb);
if ($dbhandle->connect_error) {
exit("There was an error with your connection: ".$dbhandle->connect_error);}
?>
<html>
<head>
<title>Graph</title>
<link rel="stylesheet" type="text/css" href="fusioncharts/style.css" />
<script src="fusioncharts/fusioncharts.js"></script>
</head>
<body>
<?php
if ($_SESSION['sensors'] == 0) { echo "No sensors"; }
else { $array= $_SESSION['sensors'];
$ids = join("','" , $array);
$strQuery = "SELECT sensor_id, COUNT(*) FROM alert WHERE sensor_id IN ('$ids') GROUP BY
sensor_id" ;
79
$result = $dbhandle->query($strQuery) or exit("Error code ({$dbhandle->errno}):
{$dbhandle->error}");
if ($result) {
$arrData = array(
"chart" => array(
"caption" => "Alerts over time",
"xAxisName" => "Sensor",
"yAxisName" => "Number of alerts",
"refreshinterval" => "5",
"numDivLines" => "0" ,
"showYAxisValues" => "1",
"numdisplaysets" => "10",
"labeldisplay" => "rotate",
"showValues" => "1",
"showRealTimeValue" => "0",
"theme" => "fint"
)
);
$arrData["data"] = array();
while($row = mysqli_fetch_array($result)) {
array_push($arrData["data"], array(
"label" => $row[0],
"value" => $row[1],
"displayValue" => $row[1]
)
);
};
$jsonEncodedData = json_encode($arrData);
$columnChart->render();
// Close the database connection
$dbhandle->close();
} else { echo "MySQL error"; };
};
?>
<div id="chart-1"><!-- Fusion Charts will render here--></div>
</body>
</html>
graphintime.php
<?php
session_start();
$hostdb = "127.0.0.1"; // MySQl host
$userdb = "root"; // MySQL username
$passdb = "password16"; // MySQL password
$namedb = "login"; // MySQL database name
// Establish a connection to the database
$dbhandle = new mysqli($hostdb, $userdb, $passdb, $namedb);
if ($dbhandle->connect_error) {
exit("There was an error with your connection: ".$dbhandle->connect_error);
}
?>
<html>
<head>
<style>
....
</style>
<title>Graph</title>
<script src="fusioncharts/fusioncharts.js"></script>
</head>
<body>
<?php
include("fusioncharts/fusioncharts.php");
if ($_SESSION['sensors'] == 0) { echo "No sensors"; }
else {
$array= $_SESSION['sensors'];
$ids = join("','" , $array);
$currentid= $_SESSION['id'];
$sql = "SELECT sensor_id, comment FROM sensor where user_id='".$currentid."' ";
80
$result = $dbhandle->query($sql);
if ($result->num_rows > 0) {
echo "<table><tr><th>Sensor ID</th><th>Comment</th></tr>";
// output data of each row
while($row = $result->fetch_assoc()) {
echo "<tr><td>" . $row["sensor_id"]. "</td><td>" . $row["comment"]. " </td></tr>";
}
echo "</table>";
} else {
echo "0 results";
}
if(!empty($_POST['sensor_id'])) {
$strQuery = "SELECT sensor_id, startdate FROM alert WHERE sensor_id =
'".$_POST['sensor_id']."' ORDER BY startdate ASC LIMIT 20";
$result = $dbhandle->query($strQuery) or exit("Error code ({$dbhandle->errno}):
{$dbhandle->error}");
// If the query returns a valid response, prepare the JSON string
if ($result) {
// The `$arrData` array holds the chart attributes and data
$arrData = array(
"chart" => array(
"caption" => "Alerts over time",
"xAxisName" => "Time",
"yAxisName" => "Alert ID",
"refreshinterval" => "5",
"numDivLines" => "0" ,
"showYAxisValues" => "0",
"numdisplaysets" => "10",
"labeldisplay" => "rotate",
"showValues" => "0",
"showRealTimeValue" => "0",
"theme" => "fint"
)
);
$arrData["data"] = array();
while($row5 = mysqli_fetch_array($result)) {
array_push($arrData["data"], array(
"label" => $row5['startdate'],
"value" => 0.5 ,
"displayValue" => $row5["startdate"]
)
);
};
$jsonEncodedData = json_encode($arrData);
$columnChart = new FusionCharts("line", "myFirstChart" , 800, 600, "chart", "json",
$jsonEncodedData);
// Render the chart
$columnChart->render();
// Close the database connection
$dbhandle->close();
} else { echo "MySQL error"; };
};
};
?>
<div id="editsensor">
<form method="POST" action="graphintime.php">
<p> <label>View graph for: </label>
<input type="text" size="30" id="sensor_id" name="sensor_id" />
</p>
<p> <button class="button" id="button"> Proceed</button> </p>
<p> Go back to <a href="https://127.0.0.1/login/redirect.php">main page</a></p>
</form>
</div>
<div id="chart"><!-- Fusion Charts will render here--></div>
</body>
</html>
81
graphintimeconn.php
<?php
include("fusioncharts/fusioncharts.php");
$hostdb = "127.0.0.1"; // MySQl host
$userdb = "root"; // MySQL username
$passdb = "password16"; // MySQL password
$namedb = "login"; // MySQL database name
// Establish a connection to the database
$dbhandle = new mysqli($hostdb, $userdb, $passdb, $namedb);
if ($dbhandle->connect_error) {
exit("There was an error with your connection: ".$dbhandle->connect_error);
}
if ($_SESSION['sensors'] == 0) { echo "No sensors"; }
else { $array= $_SESSION['sensors'];
$ids = join("','" , $array);
currentid= $_SESSION['id'];
$sql = "SELECT sensor_id, comment FROM sensor where user_id='".$currentid."' ";
$result = $dbhandle->query($sql);
if ($result->num_rows > 0) {
echo "<table><tr><th>Sensor ID</th><th>Comment</th></tr>";
// output data of each row
while($row = $result->fetch_assoc()) {
echo "<tr><td>" . $row["sensor_id"]. "</td><td>" . $row["comment"]. " </td></tr>";
}
echo "</table>";
} else {
echo "0 results";
}
if(!empty($_POST['sensor_id'])) {
$strQuery = "SELECT alert_id, startdate FROM alert WHERE sensor_id =
'".$_POST['sensor_id']."' ORDER BY startdate ASC LIMIT 20";
$result = $dbhandle->query($strQuery) or exit("Error code ({$dbhandle->errno}):
{$dbhandle->error}");
// If the query returns a valid response, prepare the JSON string
if ($result) {
// The `$arrData` array holds the chart attributes and data
$arrData = array(
"chart" => array(
"caption" => "Alerts over time",
"xAxisName" => "Time",
"yAxisName" => "Alert ID",
"refreshinterval" => "5",
"numDivLines" => "0" ,
"showYAxisValues" => "1",
"numdisplaysets" => "10",
"labeldisplay" => "rotate",
"showValues" => "0",
"showRealTimeValue" => "0",
"theme" => "fint"
)
);
$arrData["data"] = array();
while($row5 = mysqli_fetch_array($result)) {
array_push($arrData["data"], array(
"label" => $row5['startdate'],
"value" => $row5[0],
"displayValue" => $row5["startdate"]
)
);
};
$jsonEncodedData = json_encode($arrData);
$columnChart = new FusionCharts("line", "myFirstChart" , 800, 600, "chart-1", "json",
$jsonEncodedData);
// Render the chart
$columnChart->render();
// Close the database connection
$dbhandle->close();
} else { echo "MySQL error"; };
82
};
};
?>
groups.php
<?php
session_start();
?>
<!DOCTYPE html>
<html>
<head>
<style>
....
</style>
</head>
<body>
<span style="font-size:40px;cursor:pointer;color:white" onclick="openNav()">☰ Open navigation</span>
<?php
$servername = "127.0.0.1";
$username = "root";
$password = "password16";
$dbname = "login";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$currentid= $_SESSION['id'];
$sql = "SELECT id, name FROM sgroup";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "<table><tr><th>Group ID</th><th>Group name</th></tr>";
// output data of each row
while($row = $result->fetch_assoc()) {
echo "<tr><td>" . $row["id"]. "</td><td>" . $row["name"]. " </td></tr>";
}
echo "</table>";
} else {
echo "0 results";
}
?>
<div id="groups">
<form method="POST" action="groupconnection.php">
<p> <label>ID of group you want to view</label>
<input type="text" size="30" id="id" name="id" />
</p>
<p> <label>Create a new group</label>
<input type="text" size="30" id="name" name="name"
placeholder="Type a group name" />
</p>
<p> <label>Delete a group</label>
<input type="text" size="30" id="delname" name="delname"
placeholder="Name of group to delete" />
</p>
<p> <button class="button" id="button"> Proceed</button>
<p> Go back to <a
href="https://127.0.0.1/login/redirect.php">main page</a></p>
</form>
</div>
<div id="mySidenav" class="sidenav">
<a href="javascript:void(0)" class="closebtn" onclick="closeNav()">×</a>
<a href="https://127.0.0.1/login/addtogroup.php">Add sensors in group</a>
<a href="https://127.0.0.1/login/addalltogroup.php">Add all owned sensors in a group</a>
<a href="https://127.0.0.1/login/delfromgroup.php">Delete sensors from group</a>
</div>
<script>
function openNav() {
83
document.getElementById("mySidenav").style.display = "block";
}
function closeNav() {
document.getElementById("mySidenav").style.display = "none";
}
</script>
</body>
</html>
groupconnection.php
<!DOCTYPE html>
<html>
<head>
<style>
....
</style>
</head>
<body>
<?php
$servername = "127.0.0.1";
$username = "root";
$password = "password16";
$dbname = "login";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
if(!empty($_POST['id'])) {
$sql = "SELECT group_id, sensor_id FROM sensor_group WHERE group_id = '$_POST[id]'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "<table><tr><th>Group ID</th><th>Sensor ID</th></tr>";
// output data of each row
while($row = $result->fetch_assoc()) {
echo "<tr><td>" . $row["group_id"]. "</td><td>" . $row["sensor_id"]. " </td></tr>";
}
echo "</table>";
} else {
echo "0 results";
}
}
if(!empty($_POST['name'])) {
$name = $_POST['name'];
$sql2 = "INSERT INTO sgroup (name) VALUES ('$name')";
$result2 = $conn->query($sql2);
if ($result2 > 0) {
header( "refresh:2; url=groups.php" ); //wait for 2 seconds before redirecting
echo 'Group added succesfully';
}
else echo 'Failed';
}
if(!empty($_POST['delname'])) {
$sql3 = "SELECT * FROM sgroup WHERE name = '$_POST[delname]'";
$result3 = $conn->query($sql3);
if ($result3->num_rows>0) {
$sql4="DELETE FROM sgroup WHERE name = '$_POST[delname]' ";
$result4 = $conn->query($sql4);
if ($result4 > 0) {
header( "refresh:2; url=groups.php" ); //wait for 2 seconds before redirecting
echo "Groups updated"; }
}
else {
echo 'Group name not found';
header( "refresh:2; url=groups.php" ); //wait for 2 seconds before redirecting
}
}
84
?>
<div id="fromgrouptoaccount">
<form method="POST" action="fromgrouptoaccount.php">
<p> <label>ID of sensor you want to add to your account</label>
<input type="text" size="30" id="fromgrouptoaccountid" name="fromgrouptoaccountid"
placeholder="If you want to add a sensor type ID here" />
</p>
<p> <label>Comment</label>
<input type="text" size="30" id="fromgrouptoaccountcomm" name="fromgrouptoaccountcomm" />
</p>
<p> <button class="button" id="button"> Proceed</button>
<p> Go back to <a href="https://127.0.0.1/login/redirect.php">main page</a></p>
</form>
</div>
</body>
</html>
addtogroup.php
<?php
session_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-
transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!--info despre document-->
<title>AddToGroup</title>
<script type="text/javascript" src="script/jquery-3.1.1.min.js"></script>
<style>
....
</style>
<div id="addtogroup">
<form method="POST" action="addtogroupconnection.php">
<p> <label>ID of sensor you want to add</label>
<input type="text" size="30" id="sensor_id" name="sensor_id" />
</p>
<p> <label>Destination group </label>
<input type="text" size="30" id="destinationgroup" name="destinationgroup"/>
</p>
<p> <button class="button" id="button"> Proceed</button>
<p> Go back to <a href="https://127.0.0.1/login/groups.php">group page</a></p>
</form>
</div>
</body>
</html>
addtogroupconnection.php
<?php
session_start();
define('DB_HOST', '127.0.0.1');
define('DB_NAME', 'login');
define('DB_USER','root');
define('DB_PASSWORD','password16');
$con=mysql_connect(DB_HOST,DB_USER,DB_PASSWORD) or die("Failed to connect to MySQL: " . mysql_error());
$db=mysql_select_db(DB_NAME,$con) or die("Failed to connect to MySQL: " . mysql_error());
$sensor_id = $_POST['sensor_id'];
$sensor_id2 = hexdec($sensor_id);
$destinationgroup =mysql_real_escape_string(htmlspecialchars(trim($_POST['destinationgroup'])));
if(!empty($_POST['sensor_id'])) {
$result = mysql_query("SELECT id FROM sgroup WHERE name = '".$_POST['destinationgroup']."' ");
$rs = mysql_fetch_array($result);
$destid = $rs['id'];
if ($destid == 0) {
echo 'This group doesnt exist ' . mysql_error();
exit;
}
else {
85
$query = "INSERT INTO sensor_group (group_id, sensor_id) VALUES ('$destid' , '$sensor_id2')";
$data = mysql_query ($query)or die(mysql_error());
if($data) {
header("refresh:3; url=groups.php" ); //wait for 2 seconds before redirecting
echo "Sensor added succesfully to group " , $destinationgroup ;
}
}
} else echo 'Failed';
?>
delfromgroup.php
<?php
session_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-
transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!--info despre document-->
<title>DelFromGroup</title>
<script type="text/javascript" src="script/jquery-3.1.1.min.js"></script>
<style>
...
</style>
</head>
<body>
<div id="delfromgroup">
<form method="POST" action="delfromgroupconnection.php">
<p> <label>Destination group </label>
<input type="text" size="30" id="destinationgroup" name="destinationgroup"/>
</p>
<p> <button class="button" id="button"> Proceed</button>
<p> Go back to <a href="https://127.0.0.1/login/groups.php">group page</a></p>
</form>
</div>
</body></html>
delfromgroupconnection.php
<?php
session_start();
?>
<!DOCTYPE html>
<html>
<head>
<style>
....
</style>
</head>
<body>
<?php
define('DB_HOST', '127.0.0.1');
define('DB_NAME', 'login');
define('DB_USER','root');
define('DB_PASSWORD','password16');
$con=mysql_connect(DB_HOST,DB_USER,DB_PASSWORD) or die("Failed to connect to MySQL: " . mysql_error());
$db=mysql_select_db(DB_NAME,$con) or die("Failed to connect to MySQL: " . mysql_error());
$conn = new mysqli('127.0.0.1', 'root', 'password16', 'login');
$destinationgroup =mysql_real_escape_string(htmlspecialchars(trim($_POST['destinationgroup'])));
if(!empty($_POST['destinationgroup'])) {
$query2= "SELECT id FROM sgroup WHERE name = '".$_POST['destinationgroup']."' ";
$result2 = mysql_query($query2);
if (!$result2) {die('Could not query:' . mysql_error());}
else { $row2= mysql_fetch_row($result2);}
$sql = "SELECT group_id, sensor_id FROM sensor_group WHERE group_id = '$row2[0]'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "<table><tr><th>Group ID</th><th>Sensor ID</th></tr>";
// output data of each row
while($row = $result->fetch_assoc()) {
86
echo "<tr><td>" . $row["group_id"]. "</td><td>" . $row["sensor_id"]. " </td></tr>";
}
echo "</table>";
} else {
echo "0 results";
}
}
?>
<div id="delll">
<form method="POST" action="delllconnection.php">
<p> <label>ID of sensor you want to delete</label>
<input type="text" size="30" id="id" name="id" />
</p>
<p> <button class="button" id="button"> Proceed</button>
<p> Go back to <a href="https://127.0.0.1/login/groups.php">groups</a></p>
</form>
</div>
</body>
</html>
87