diff --git a/Photos/screenshot_web_ui.png b/Photos/screenshot_web_ui.png new file mode 100644 index 0000000..3bb450f Binary files /dev/null and b/Photos/screenshot_web_ui.png differ diff --git a/project.adoc b/project.adoc index baac1a9..ebfe2fd 100644 --- a/project.adoc +++ b/project.adoc @@ -100,6 +100,15 @@ image::Photos/arduino2.jpg[300,200] της θέσης του parking για τον οποίο είναι υπεύθυνος. Με κόκκινο χαρακτηρίζεται η θέση που είναι δεσμευμένη από ένα όχημα και με μπλε η ελεύθερη θέση, όπως φαίνεται στις παραπάνω εικόνες. +==== Προγραμματισμός Κόμβου +Για τον πτογραμματισμό του Arduino Uno χρησιμοποιήσαμε μία σειριακή σύνδεση του μικροελγκτή με τον +υπολογιστή μας ο οποίος έφερε εγκατεστημένο το IDE του Arduino στον οποίο υπήρχαν όλες οι απαραότητες +βιβλιοθήκες για την υλοποίησή του. Η διαδικασία "καψήματος" ενός μικροελεγκτή Arduino είναι πολύ απλή. +Το μόνο που χρειάζεται να κάνει κανείς είναι να δώσει δικαιώματα γραψήματος και ανάγνωσης στην συσκευή +ttyACM0 που βρίσκεται στο directory (/dev/ στα linux) και λίγες γνώσεις από κώδικα. + +Η γλώσσα του Arduino είναι γλώσσα που μοιάζει πάρα πολύ με τη C. + ==== Λειτουργία του Parking Sensor Κάθε κόμβος στέλνει στην σειριακή του τον κωδικό της θέσης, με τον οποίο έχει προγραμματιστεί το Arduino, και την κατάσταση του parking, κωδικοποιημένα με τον διαχωριστή "#". Για την κατάσταση του parking ορίζουμε @@ -123,51 +132,130 @@ image::Photos/arduino2.jpg[300,200] * 1 x micro SD (Loaded with Raspbian OS) * 1 x Ethernet Link (Connects to nearest Network) or WiFi adapter -==== Υλοποίηση και Προγραμματισμός +==== Υλοποίηση Gateway Κόμβου Η υλοποίηση αποτελείται από την εγκατάσταση του Raspbian OS (light version) στο Raspberry και τη δημιουργία ενός proccess σε γλώσσα Python (v3). Το process αυτό διαβάζει από την σειριακή θύρα του την πληροφορία που λαμβάνει από ένα Arduino Uno με -την μορφή <κωδικός θέσης>#<διαθεσιμότητα 0 ή 1>. Ύστερα αποκωδικοποιεί την πληροφορία η οποία περιγράφει τον κωδικό της θέσης +την μορφή <κωδικός θέσης>#<διαθεσιμότητα 0 ή 1>. Ύστερα αποκωδικοποιεί αυτή την πληροφορία, η οποία περιγράφει τον κωδικό της θέσης και την διαθεσιμότητα της, και την αποστέλει μέσω ενός REST API με την μέθοδο POST σε έναν WEB Server. Για να αποσταλεί η πληροφορία -στον WEB Server πρέπει να πάρει την μορφή JSON (JavaScript Object Notation). +στον WEB Server πρέπει να πάρει την μορφή JSON (JavaScript Object Notation) και να έχει αυθεντικοποιηθεί από αυτό (** βλέπε παρακάτω). -Η μέθοδος του POST γίνεται στην περίπτωσή που η κατάσταση του Parking μεταβληθεί. Σε αντίθετη περίπτωση ο Server δεν ενημερώνεται. +Η μέθοδος του [POST] γίνεται στην περίπτωσή που η κατάσταση του Parking μεταβληθεί. Σε αντίθετη περίπτωση ο Server δεν ενημερώνεται. -Στον ίδιο φάκελο του κώδικα βρίσκεται ένα configuration αρχείο το οποίο περιέχει ένα JSON με την μορφή: +Στον ίδιο φάκελο του κώδικα βρίσκεται ένα configuration αρχείο το οποίο περιέχει κάποιες ρυθμίσεις του κόμβουσε μορφή JSON. +Οι ρυθμίσεις αυτές αφορούν ουσιαστικά την IP και την πόρτα του WEB Server που ένας τέτοιος κόμβος θα πρέπει να επικοινωνεί, +τα στοιχεία αυθεντικοποίησής του καθώς και τον κωδικό της θέσης του parking που εξυπηρετεί. Το αρχείο θα έχει τη μορφή: [source, JSON] ---- { "ip": "iot-smart-parking.herokuapp.com", - "port": "443" + "port": "443", + "username": "root", + "password": "root", + "device": 1 } ---- -Το αρχείο αυτό περιέχει ρυθμίσεις που αφορά τη σύνδεσή του με τον WEB Server την διευθυνδή του δηλαδή και την πόρτα -που ακούει. + +==== Προγραμματισμός Κόμβου +Ο επικοινωνία και ο προγραμματισμός του κόμβου αυτού, που είναι βασισμένος σε ένα Raspberry Pi 1, έγινε με σύνδεση (ssh) +έχοντας βέβαια και οι δύο (Raspberry και εμείς) πρόσβαση στο ίδιο δίκτυο. Η γλώσσα που χρησιμοποιήσαμε για τον έλεγχο +της σειριακής θύρας και την επικοινωνία του με ένα REST WEB Server ήταν η Python (version 3). ==== Διασύνδεηση στο Διαδίκτυο Ο κόμβος Gateway έχει διασύνδεση με το διαδίκτυο μέσω ενός καλωδίου Ethernet (UTP) έτσι ώστε να μπορέσει -να στείλει την πληροφορία στο διαδίκτυο, δηλαδή στον WEB Server. +να στείλει την πληροφορία που παράγει από τα δεδομένα του μικροελεγκτή Arduino (Σενσορ) στο διαδίκτυο, δηλαδή +στον REST WEB Server. Από την άλλη επικοινωνεί με το Arduino με μία σειριακή σύνδεση. -== Server Node (3~ο~ μέρος - Κεντρικός Server όπου κρατά την κατάσταση της κάθε θέσης του Parking) +=== Server Node (3~ο~ μέρος - Κεντρικός Server όπου κρατά την κατάσταση της κάθε θέσης του Parking) Ο κόμβος αυτός υλοποιεί ένα process γραμμένο σε γλώσσα προγραμματισμού Python (v3). Αυτό το process υλοποιεί ένα REST API έτσι ώστε να μπορούν να επικοινωνούν εύκολα οι Gateway κόμβοι μας με αυτόν. Στην είσοδό του και στην έξοδό του η πληροφορία έχει την μορφή JSON. -Ο server αποθηκεύει όλα τα απαραίτητα δεδομένα σε μία σχεσιακή βάση δεδομένων MySQL, η οποία διαθέτει έναν πίνακα. +Ο Server αποθηκεύει όλα τα απαραίτητα δεδομένα σε μία σχεσιακή βάση δεδομένων MySQL, η οποία διαθέτει έναν πίνακα. Ο πίνακας κρατά όλα τα απαραίτητα πεδία που είναι: * Τον κωδικό της θέσης parking * Την διαθεσιμότητά της αντίστοιχης θέση (0 ή 1) -=== Εκτέλεση του Process στο Cloud +Ακόμα υπάρχει και ένας δεύτερος πίνακας σε αυτή που έχει καταχωρημένα στοιχεία αυθεντικοποίησης που μπορεί να +χρησιμοποιήσει ένας κόμβος (Gateway Node) για να μπορεί να ενημερώνει την κατάσταση μίας θέσης Parking. Ο πίνακας +αυτός έχει τα απαραίτητα πεδία: + + * Τον κωδικό του χρήστη. + * Το όνομα χρήστη (username). + * Έναν κωδικό πρόσβασης (password). + +[source, sql] +---- +CREATE TABLE IF NOT EXISTS PARKING ( + PARKING_CODE INT(4) NOT NULL UNIQUE, + PARKING_STATUS BOOLEAN NOT NULL +); + +CREATE TABLE IF NOT EXISTS USERS ( + USER_NO INT(4) AUTO_INCREMENT, + USER_NAME VARCHAR(40) NOT NULL UNIQUE, + USER_PASS VARCHAR(40) NOT NULL, + PRIMARY KEY(USER_NO) +); +---- + +==== Υλοποίηση Κόμβου +Για τον προγραμματισμό του κόμβου επιλέχθηκε η γλώσσα προγραμματισμού Python (version 3). Για την υλοποίηση του WEB Server +χρησιμοποιήσαμε ένα WSGI και συγκεκριμένα το FLASK module της Python. Για την εκτέλεσή του έχουμε δύο υλοποιήσεις. Τη μία +που είναι με το FLASK όπου η εκτέλεση θα πραγματοποιηθεί σε έναν από τους υπολογιστές μας και η άλλη που είναι με gunicorn- +WEB Server στη Python όπου η εκτέλεση θα πραγματοποιηθεί σε μία υπηρεσία του Heroku. + + +==== Προγραμματισμός REST API WEB Server +Το REST API ενεργοποιεί δύο (τρεις) υπηρεσίες. Αυτές είναι: + +* / [GET]: επιστρέφει ένα Array από JSON objects, ένα JSON για κάθε θέση του parking αν είναι διαθέσιμη ή όχι κωδικοποιημένα με 0 ή 1. +Τα δεδομένα που επιστρέφει γίνονται fetch από τη βάση δεδομένων. + +Για παράδειγμα: + +[source, json] +---- +[{"no": 1, "status": false}, {"no": 2, "status": false}, {"no": 3, "status": false}, {"no": 4, "status": true}, {"no": 5, "status": false}, {"no": 6, "status": false}, {"no": 7, "status": false}, {"no": 8, "status": false}] +---- + +* /parkingStatus [POST] (content-type = "application/json"): που μας επιτρέπει να αλλάξουμε την κατάσταση μίας θέσης parking. Στο POST τα δεδομένα +ορίζονται στο body σε αναπαράσταση JSON, έτσι ώστε ο Server να είναι ικανός να τα επεξεργαστεί και να τα αποθηκεύσει +στη βάση δεδομένων που χρησιμοποιούμε. + +Για παράδειγμα: + +[source, json] +---- +{"no": 2, "status": false} +---- + +Ακόμα το REST API υλοποιεί μηχανιμσό αυθεντικοποίησης έτσι ώστε οι μεταβολές-ενημερώσεις των θέσεων του parking +να γίνονται μόνο από τους εξουσιοδοτημένους κόμβους του συστήματος. Αυτό επιτυγχάνεται με την ενεργοποίηση μίας +υπηρεσίας όπως περιγράφεται παρακάτω: + +* /authentication [POST] (content-type = "application/json): Η υπηρεσία αυτή κάνει register ένα Session σε κάθε +εξουσιοδοτημένο κόμβο ο οποίος αυθεντικοποιείται από τον Server με username και password. Όταν ο server αυθεντικοποιήσει +έναν κόμβο τότε ορίζει για αυτόν ένα χαρακτηριστικό που είναι ο κωδικός της θέσης που βρίσκεται, και ο Server του γυρνάει +ένα Session_id. Με βάση αυτό το κλειδί μπορεί ο κάθε (εξουσιοδοτημένος) κόμβος να χρησιμοποιήσει μία τέτοια υπηρεσία +όπως αυτή της καταχώρησης της διαθεσιμότητας κάθε θέσης από τους κόμβους αντίστοιχα. + + +==== Εκτέλεση του Process στο Cloud Για την εκτέλεση του process χρησιμοποιούμε μία πλατφόρμα IAAS (Infrastructure as a Service) - link:++https://www.heroku.com/platform++[Heroku], για την οποιά μπορούμε να βρούμε περεταίρω πληροφορίες στον σύνδεσμο παραπάνω. +Η πλατφόρμα μας επιτρέπει να ανεβάσουμε τον κώδικα του Server μας (Python) και να τον εκτελέσουμε στο Cloud. + Στην δωρεάν έκδοσή του δεν έχουμε περιορισμούς στο τμήμα του HTTP service που εκτελούμε, ενώ στη βάση δεδομένων -υπάρχουν περιοριμοί στις συνδέδεις που μπορούν να γίνουν ανα κάποιο χρονικό διάστημα (περίπου 10 συνδέσει ανα 1 ώρα). +υπάρχουν περιοριμοί στις συνδέδεις που μπορούν να γίνουν ανα κάποιο χρονικό διάστημα (περίπου 10 συνδέσει ανα 1 ώρα) και ένας +αριθμός Query (~3500) ανά 1~2 ώρες. + +Στα πλαίσια της άσκησης δεν θα δημιουργηθεί κάποιο πρόβλημα όσων αφορά την εκτέλεση του κεντρικού Server στο Cloud. [.float-group] -- @@ -182,9 +270,8 @@ image::Photos/itops-pizza_as_a_service.png[1000,800] εγκαθισούμε στο project που μόλις φτιάξαμε μία MySQL βάση δεδομένων για να μπορούμε να αποθηκεύσουμε τα δεδομένα μας. ==== Deployment -* Το πρώτο πράγμα που χρειαζόμαστε είναι όλες οι απαραίτητες βιβλιοθήκες που χρησιμοποιεί ο κώδικας, έτσι -ώστε να γνωρίζει το Heroku τι να μας προσφέρει. Αυτό επιτυγχάνεται με την αρχειοθέτηση αυτών σε ένα αρχείο -ονόματι requirements.txt . +* Το πρώτο πράγμα που χρειαζόμαστε είναι όλες οι απαραίτητες βιβλιοθήκες που χρησιμοποιεί ο κώδικας, έτσι ώστε να γνωρίζει +το Heroku τι να μας προσφέρει. Αυτό επιτυγχάνεται με την αρχειοθέτηση αυτών σε ένα αρχείο με όνομα requirements.txt . Το αρχείο που περιέχει όλα τα απαραίτητα modules για τον κώδικά μας είναι: @@ -199,12 +286,12 @@ mysql-connector * Έπειτα την δημιουργία ενός αρχείου που περιγράφει το που βρίσκεται η κύρια συνάρτηση μας (main) για την έναρξη του process. Αυτό το αρχείο ονομάζεται Procfile . Στο αρχείο αυτό αναφέτεται ένα gunicorn module. -Ο gunicorn είναι ένας Python HTTP WEB server. Αυτό ουσιαστικά είναι ο ο πυρήνας για την εκτέλεση του API μας. +Το gunicorn είναι ένα Python HTTP WEB server. Αυτό ουσιαστικά είναι ο πυρήνας για την εκτέλεση του REST API μας. * Έπειτα με μια απομακρυσμένη σύνδεση στη βάση μας της οποίας τα στοιχεία πρόσβασης γίνονται στο Heroku, πραγματοποιούμε μία σύνδεση και δημιουργούμε τον πίνακά μας για την αποθήκευση. -Το αρχείο αυτό έχει τη μορφή αυτή: +* Τέλος το αρχείο Procfile το οποίο περιέχει το αρχείο το οποίο φορτώσει το gunicorn το οποίο έχει τη μορφή: [source, conf] ---- @@ -235,48 +322,29 @@ export FLASK_DEBUG=1 flask run --host=[IP-v4] --port=8080 ---- -==== Περιγραφή REST API -Το REST API ουσιαστικά σηκώνει δύο υπηρεσίες. Αυτές είναι: - -* / [GET]: επιστρέφει ένα Array από JSON objects, ένα JSON για κάθε θέση του parking αν είναι διαθέσιμη ή όχι κωδικοποιημένα με 0 ή 1. -Τα δεδομένα που επιστρέφει γίνονται fetch από τη βάση δεδομένων. - -Για παράδειγμα: - -[source, json] ----- -[{"no": 1, "status": false}, {"no": 2, "status": false}, {"no": 3, "status": false}, {"no": 4, "status": true}, {"no": 5, "status": false}, {"no": 6, "status": false}, {"no": 7, "status": false}, {"no": 8, "status": false}] ----- - -* /parkingStatus [POST] (content-type = "application/json"): που μας επιτρέπει να αλλάξουμε την κατάσταση μίας θέσης parking. Στο POST τα δεδομένα -ορίζονται στο body σε αναπαράσταση JSON, έτσι ώστε ο Server να είναι ικανός να τα επεξεργαστεί και να τα αποθηκεύσει -στη βάση δεδομένων που χρησιμοποιούμε. - -Για παράδειγμα: -[source, json] ----- -{"no": 2, "status": false} ----- -Ακόμα το REST API υποστυρίζει μηχανιμσό αυθεντικοποίησης έτσι ώστε οι μεταβολές-ενημερώσεις των θέσεων του parking -να γίνονται μόνο από τους εξουσιοδοτημένους κόμβους του συστήματος. Αυτό επιτυγχάνεται με την ενεργοποίηση μίας -υπηρεσίας όπως περιγράφεται παρακάτω: +=== Διεπαφή Χρήστη (4~ο~ μέρος) +==== Η διεπαφή του χρήστη +Η διεπαφή του χρήστη αποτελείται από μία HTML σελίδα η οποία ενσωματώνει δύο JavaScript Processes. +Σκοπός αυτής είναι η αναπαράσταση της κατάστασης του Parking σε ένα γραφικό, φιλικό προς τον χρήστη περιβάλλον. +Η σελίδα λοιπόν επεικονίζει για κάθε θέση parking με χρώμα κόκκινο την "μη ελεύθεση" και με πράσινο την "ελεύθερη". -* /authentication [POST] (content-type = "application/json): +Ένα παράδειγμα μέσω στιγμιοτύπου παρουσιάζεται παρακάτω. -== Διεπαφή Χρήστη (4~ο~ μέρος) -=== Η διεπαφή του χρήστη -Η διεπαφή του χρήστη αποτελείται από μία HTML σελίδα η οποία ενσωματώνει δύο JavaScript Processes. -Σκοπός αυτής είναι η αναπαράσταση της κατάστασης του Parking. Η σελίδα λοιπόν επεικονίζει για κάθε θέση -parking με χρώμα κόκκινο την "μη ελεύθεση" και με πράσινο την "ελεύθερη". +[.float-group] +-- +[.center] +.Στιγμιότυπο παραδείγματος εκτέλεσης της διεπαφής χρήστη. +image::Photos/screenshot_web_ui.png[1000,800] +-- == Autonomous Parking -Το αυτότομο πρκάριμα αποτελείται από το όχημα με εγκατεστημένους τους απάραίτητους αισθητήρες και ελεγκτές -καθώς και έναν μικροελεγκτή (Arduino) για τον έλεγχο αυτών των ελεγκτών. Σκοπός είναι το όχημα να μπορεί +Το αυτόνομο πρκάριμα αποτελείται από το όχημα με εγκατεστημένους τους απάραίτητους αισθητήρες και ελεγκτές +καθώς, έναν μικροελεγκτή (Arduino) για τον έλεγχο αυτών των ελεγκτών και ένα Raspberry Pi1. Σκοπός είναι το όχημα να μπορεί να μάθει μέσω του διαδικτύου το "Status" του parking και να παρκάρει στην 1η διαθέσιμη θέση εφ' όσων -υπάρχει μία τουλάχιστων διαθέσιμη θέση στον χώρο στάθμευσης. +υπάρχει μία τουλάχιστoν διαθέσιμη θέση στον χώρο στάθμευσης. *Η υλοποίηση του αυτόνομου parking χωρίζεται σε δύο βασικά μέρη.* @@ -286,7 +354,7 @@ parking με χρώμα κόκκινο την "μη ελεύθεση" και μ * Το 2~ο~ μέρος αποτείται από τον κόμβο ο οποίος θα έχει πρόσβαση στο διαδίκτυο, όπου αφού ελέγξει αν υπάρχει διαθέσιμη θέση και γνωρίζει ποια είναι η πρώτη ελεύθερη θέση, να δώσει εντολή στον μικροελεγκτή να παρκάρει σε αυτή. -=== Microcotroller and Car +=== Microcotroller and Car (1~ο~ Μέρος) ==== Υλικά Κόμβου * 1 x Arduino Uno @@ -299,7 +367,7 @@ parking με χρώμα κόκκινο την "μη ελεύθεση" και μ * 1 x Car * 1 x Raspberry Pi -==== Υλοποίηση και Προγραμματισμός +==== Υλοποίηση Microcontroller on Car Ο motor driver, το Servo motor καθώς και ο Ultrasonic αισθητήρας κουμπώνουν στον μικροελεγκτή Arduino Uno που χρησιμοποιούμε, τον οποίο τον εγκαθηστούμε πάνω στο καλούπι του οχήματος το οποίο έχει εγκατεστημένα 4 τροχούς. Οι τροχοί οδηοούνται από 4 moters τα οποία τροφοδοτούνται από τον motor driver. @@ -314,6 +382,13 @@ image::Photos/diagram.png[1000,800] -- +=== Gateway Κόμβος (2~ο~ Μέρος) +Ο Gateway κόμβος του αυτόνομου οχήματος που θα έρθει στην θέση να παρκάρει μόνο του στο parking (ΙοΤ), είναι υπεύθυνος +για την διασύνδεση του οχήματος με το διαδίκτυο. Γι' αυτό το λόγο το process που σχεδιάσαμε να τρέχει σε αυτό το σημείο +είναι υπεύθυνο για την αναζήτηση της πληροφορίας ποια είναι η πρώτη ελεύθερη για να παρκάρει το όχημα και στη συνέχεια +να αποστέλει τον αριθμό της θέσης στον μικροελεγκτή Arduino ο οποίος είναι υπεύθυνος να πάρει αυτή την τιμή και να κατευθύνει +το όχημα. + .Reminder [NOTE] diff --git a/project.html b/project.html index 132013e..dbb451c 100644 --- a/project.html +++ b/project.html @@ -630,7 +630,20 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
-

1.1.3. Λειτουργία του Parking Sensor

+

1.1.3. Προγραμματισμός Κόμβου

+
+

Για τον πτογραμματισμό του Arduino Uno χρησιμοποιήσαμε μία σειριακή σύνδεση του μικροελγκτή με τον +υπολογιστή μας ο οποίος έφερε εγκατεστημένο το IDE του Arduino στον οποίο υπήρχαν όλες οι απαραότητες +βιβλιοθήκες για την υλοποίησή του. Η διαδικασία "καψήματος" ενός μικροελεγκτή Arduino είναι πολύ απλή. +Το μόνο που χρειάζεται να κάνει κανείς είναι να δώσει δικαιώματα γραψήματος και ανάγνωσης στην συσκευή +ttyACM0 που βρίσκεται στο directory (/dev/ στα linux) και λίγες γνώσεις από κώδικα.

+
+
+

Η γλώσσα του Arduino είναι γλώσσα που μοιάζει πάρα πολύ με τη C.

+
+
+
+

1.1.4. Λειτουργία του Parking Sensor

Κάθε κόμβος στέλνει στην σειριακή του τον κωδικό της θέσης, με τον οποίο έχει προγραμματιστεί το Arduino, και την κατάσταση του parking, κωδικοποιημένα με τον διαχωριστή "#". Για την κατάσταση του parking ορίζουμε @@ -642,7 +655,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b

-

1.1.4. Διασύνδεση Κόμβου

+

1.1.5. Διασύνδεση Κόμβου

Ο κόμβος αυτός συνδέεται με ένας "Gateway" κόμβο (βασισμένος σε Raspberry Pi) ο οποίος είναι υπεύθυνος για την μετάδοση της πληροφορίας στο διαδίκτυο. Η πληροφορία αυτή λαμβάνεται στον "Gateway" κόμβο ο οποίος στη συνέχεια @@ -675,53 +688,60 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b

-

1.2.2. Υλοποίηση και Προγραμματισμός

+

1.2.2. Υλοποίηση Gateway Κόμβου

Η υλοποίηση αποτελείται από την εγκατάσταση του Raspbian OS (light version) στο Raspberry και τη δημιουργία ενός proccess σε γλώσσα Python (v3). Το process αυτό διαβάζει από την σειριακή θύρα του την πληροφορία που λαμβάνει από ένα Arduino Uno με -την μορφή <κωδικός θέσης>#<διαθεσιμότητα 0 ή 1>. Ύστερα αποκωδικοποιεί την πληροφορία η οποία περιγράφει τον κωδικό της θέσης +την μορφή <κωδικός θέσης>#<διαθεσιμότητα 0 ή 1>. Ύστερα αποκωδικοποιεί αυτή την πληροφορία, η οποία περιγράφει τον κωδικό της θέσης και την διαθεσιμότητα της, και την αποστέλει μέσω ενός REST API με την μέθοδο POST σε έναν WEB Server. Για να αποσταλεί η πληροφορία -στον WEB Server πρέπει να πάρει την μορφή JSON (JavaScript Object Notation).

+στον WEB Server πρέπει να πάρει την μορφή JSON (JavaScript Object Notation) και να έχει αυθεντικοποιηθεί από αυτό (** βλέπε παρακάτω).

-

Η μέθοδος του POST γίνεται στην περίπτωσή που η κατάσταση του Parking μεταβληθεί. Σε αντίθετη περίπτωση ο Server δεν ενημερώνεται.

+

Η μέθοδος του [POST] γίνεται στην περίπτωσή που η κατάσταση του Parking μεταβληθεί. Σε αντίθετη περίπτωση ο Server δεν ενημερώνεται.

-

Στον ίδιο φάκελο του κώδικα βρίσκεται ένα configuration αρχείο το οποίο περιέχει ένα JSON με την μορφή:

+

Στον ίδιο φάκελο του κώδικα βρίσκεται ένα configuration αρχείο το οποίο περιέχει κάποιες ρυθμίσεις του κόμβουσε μορφή JSON. +Οι ρυθμίσεις αυτές αφορούν ουσιαστικά την IP και την πόρτα του WEB Server που ένας τέτοιος κόμβος θα πρέπει να επικοινωνεί, +τα στοιχεία αυθεντικοποίησής του καθώς και τον κωδικό της θέσης του parking που εξυπηρετεί. Το αρχείο θα έχει τη μορφή:

{
     "ip": "iot-smart-parking.herokuapp.com",
-    "port": "443"
+    "port": "443",
+    "username": "root",
+    "password": "root",
+    "device": 1
 }
+
+
+

1.2.3. Προγραμματισμός Κόμβου

-

Το αρχείο αυτό περιέχει ρυθμίσεις που αφορά τη σύνδεσή του με τον WEB Server την διευθυνδή του δηλαδή και την πόρτα -που ακούει.

+

Ο επικοινωνία και ο προγραμματισμός του κόμβου αυτού, που είναι βασισμένος σε ένα Raspberry Pi 1, έγινε με σύνδεση (ssh) +έχοντας βέβαια και οι δύο (Raspberry και εμείς) πρόσβαση στο ίδιο δίκτυο. Η γλώσσα που χρησιμοποιήσαμε για τον έλεγχο +της σειριακής θύρας και την επικοινωνία του με ένα REST WEB Server ήταν η Python (version 3).

-

1.2.3. Διασύνδεηση στο Διαδίκτυο

+

1.2.4. Διασύνδεηση στο Διαδίκτυο

Ο κόμβος Gateway έχει διασύνδεση με το διαδίκτυο μέσω ενός καλωδίου Ethernet (UTP) έτσι ώστε να μπορέσει -να στείλει την πληροφορία στο διαδίκτυο, δηλαδή στον WEB Server.

-
+να στείλει την πληροφορία που παράγει από τα δεδομένα του μικροελεγκτή Arduino (Σενσορ) στο διαδίκτυο, δηλαδή +στον REST WEB Server. Από την άλλη επικοινωνεί με το Arduino με μία σειριακή σύνδεση.

- -
-

2. Server Node (3ο μέρος - Κεντρικός Server όπου κρατά την κατάσταση της κάθε θέσης του Parking)

-
+
+

1.3. Server Node (3ο μέρος - Κεντρικός Server όπου κρατά την κατάσταση της κάθε θέσης του Parking)

Ο κόμβος αυτός υλοποιεί ένα process γραμμένο σε γλώσσα προγραμματισμού Python (v3). Αυτό το process υλοποιεί ένα REST API έτσι ώστε να μπορούν να επικοινωνούν εύκολα οι Gateway κόμβοι μας με αυτόν. Στην είσοδό του και στην έξοδό του η πληροφορία έχει την μορφή JSON.

-

Ο server αποθηκεύει όλα τα απαραίτητα δεδομένα σε μία σχεσιακή βάση δεδομένων MySQL, η οποία διαθέτει έναν πίνακα. +

Ο Server αποθηκεύει όλα τα απαραίτητα δεδομένα σε μία σχεσιακή βάση δεδομένων MySQL, η οποία διαθέτει έναν πίνακα. Ο πίνακας κρατά όλα τα απαραίτητα πεδία που είναι:

@@ -734,16 +754,120 @@ REST API έτσι ώστε να μπορούν να επικοινωνούν ε
-
-

2.1. Εκτέλεση του Process στο Cloud

+
+

Ακόμα υπάρχει και ένας δεύτερος πίνακας σε αυτή που έχει καταχωρημένα στοιχεία αυθεντικοποίησης που μπορεί να +χρησιμοποιήσει ένας κόμβος (Gateway Node) για να μπορεί να ενημερώνει την κατάσταση μίας θέσης Parking. Ο πίνακας +αυτός έχει τα απαραίτητα πεδία:

+
+
+
    +
  • +

    Τον κωδικό του χρήστη.

    +
  • +
  • +

    Το όνομα χρήστη (username).

    +
  • +
  • +

    Έναν κωδικό πρόσβασης (password).

    +
  • +
+
+
+
+
CREATE TABLE IF NOT EXISTS PARKING (
+    PARKING_CODE INT(4) NOT NULL UNIQUE,
+    PARKING_STATUS BOOLEAN NOT NULL
+);
+
+CREATE TABLE IF NOT EXISTS USERS (
+	USER_NO INT(4) AUTO_INCREMENT,
+	USER_NAME VARCHAR(40) NOT NULL UNIQUE,
+	USER_PASS VARCHAR(40) NOT NULL,
+	PRIMARY KEY(USER_NO)
+);
+
+
+
+

1.3.1. Υλοποίηση Κόμβου

+
+

Για τον προγραμματισμό του κόμβου επιλέχθηκε η γλώσσα προγραμματισμού Python (version 3). Για την υλοποίηση του WEB Server +χρησιμοποιήσαμε ένα WSGI και συγκεκριμένα το FLASK module της Python. Για την εκτέλεσή του έχουμε δύο υλοποιήσεις. Τη μία +που είναι με το FLASK όπου η εκτέλεση θα πραγματοποιηθεί σε έναν από τους υπολογιστές μας και η άλλη που είναι με gunicorn- +WEB Server στη Python όπου η εκτέλεση θα πραγματοποιηθεί σε μία υπηρεσία του Heroku.

+
+
+
+

1.3.2. Προγραμματισμός REST API WEB Server

+
+

Το REST API ενεργοποιεί δύο (τρεις) υπηρεσίες. Αυτές είναι:

+
+
+
    +
  • +

    / [GET]: επιστρέφει ένα Array από JSON objects, ένα JSON για κάθε θέση του parking αν είναι διαθέσιμη ή όχι κωδικοποιημένα με 0 ή 1. +Τα δεδομένα που επιστρέφει γίνονται fetch από τη βάση δεδομένων.

    +
  • +
+
+
+

Για παράδειγμα:

+
+
+
+
[{"no": 1, "status": false}, {"no": 2, "status": false}, {"no": 3, "status": false}, {"no": 4, "status": true}, {"no": 5, "status": false}, {"no": 6, "status": false}, {"no": 7, "status": false}, {"no": 8, "status": false}]
+
+
+
+
    +
  • +

    /parkingStatus [POST] (content-type = "application/json"): που μας επιτρέπει να αλλάξουμε την κατάσταση μίας θέσης parking. Στο POST τα δεδομένα +ορίζονται στο body σε αναπαράσταση JSON, έτσι ώστε ο Server να είναι ικανός να τα επεξεργαστεί και να τα αποθηκεύσει +στη βάση δεδομένων που χρησιμοποιούμε.

    +
  • +
+
+
+

Για παράδειγμα:

+
+
+
+
{"no": 2, "status": false}
+
+
+
+

Ακόμα το REST API υλοποιεί μηχανιμσό αυθεντικοποίησης έτσι ώστε οι μεταβολές-ενημερώσεις των θέσεων του parking +να γίνονται μόνο από τους εξουσιοδοτημένους κόμβους του συστήματος. Αυτό επιτυγχάνεται με την ενεργοποίηση μίας +υπηρεσίας όπως περιγράφεται παρακάτω:

+
+
+
    +
  • +

    /authentication [POST] (content-type = "application/json): Η υπηρεσία αυτή κάνει register ένα Session σε κάθε +εξουσιοδοτημένο κόμβο ο οποίος αυθεντικοποιείται από τον Server με username και password. Όταν ο server αυθεντικοποιήσει +έναν κόμβο τότε ορίζει για αυτόν ένα χαρακτηριστικό που είναι ο κωδικός της θέσης που βρίσκεται, και ο Server του γυρνάει +ένα Session_id. Με βάση αυτό το κλειδί μπορεί ο κάθε (εξουσιοδοτημένος) κόμβος να χρησιμοποιήσει μία τέτοια υπηρεσία +όπως αυτή της καταχώρησης της διαθεσιμότητας κάθε θέσης από τους κόμβους αντίστοιχα.

    +
  • +
+
+
+
+

1.3.3. Εκτέλεση του Process στο Cloud

Για την εκτέλεση του process χρησιμοποιούμε μία πλατφόρμα IAAS (Infrastructure as a Service) - Heroku, για την οποιά μπορούμε να βρούμε περεταίρω πληροφορίες στον σύνδεσμο παραπάνω.

+

Η πλατφόρμα μας επιτρέπει να ανεβάσουμε τον κώδικα του Server μας (Python) και να τον εκτελέσουμε στο Cloud.

+
+

Στην δωρεάν έκδοσή του δεν έχουμε περιορισμούς στο τμήμα του HTTP service που εκτελούμε, ενώ στη βάση δεδομένων -υπάρχουν περιοριμοί στις συνδέδεις που μπορούν να γίνουν ανα κάποιο χρονικό διάστημα (περίπου 10 συνδέσει ανα 1 ώρα).

+υπάρχουν περιοριμοί στις συνδέδεις που μπορούν να γίνουν ανα κάποιο χρονικό διάστημα (περίπου 10 συνδέσει ανα 1 ώρα) και ένας +αριθμός Query (~3500) ανά 1~2 ώρες.

+
+
+

Στα πλαίσια της άσκησης δεν θα δημιουργηθεί κάποιο πρόβλημα όσων αφορά την εκτέλεση του κεντρικού Server στο Cloud.

@@ -761,14 +885,14 @@ REST API έτσι ώστε να μπορούν να επικοινωνούν ε , περισσότερα για το deployment εδώ. Ακόμα εγκαθισούμε στο project που μόλις φτιάξαμε μία MySQL βάση δεδομένων για να μπορούμε να αποθηκεύσουμε τα δεδομένα μας.

+
-

2.1.1. Deployment

+

1.3.4. Deployment

  • -

    Το πρώτο πράγμα που χρειαζόμαστε είναι όλες οι απαραίτητες βιβλιοθήκες που χρησιμοποιεί ο κώδικας, έτσι -ώστε να γνωρίζει το Heroku τι να μας προσφέρει. Αυτό επιτυγχάνεται με την αρχειοθέτηση αυτών σε ένα αρχείο -ονόματι requirements.txt .

    +

    Το πρώτο πράγμα που χρειαζόμαστε είναι όλες οι απαραίτητες βιβλιοθήκες που χρησιμοποιεί ο κώδικας, έτσι ώστε να γνωρίζει +το Heroku τι να μας προσφέρει. Αυτό επιτυγχάνεται με την αρχειοθέτηση αυτών σε ένα αρχείο με όνομα requirements.txt .

@@ -789,13 +913,17 @@ mysql-connector
  • Έπειτα την δημιουργία ενός αρχείου που περιγράφει το που βρίσκεται η κύρια συνάρτηση μας (main) για την έναρξη του process. Αυτό το αρχείο ονομάζεται Procfile . Στο αρχείο αυτό αναφέτεται ένα gunicorn module. -Ο gunicorn είναι ένας Python HTTP WEB server. Αυτό ουσιαστικά είναι ο ο πυρήνας για την εκτέλεση του API μας.

    +Το gunicorn είναι ένα Python HTTP WEB server. Αυτό ουσιαστικά είναι ο πυρήνας για την εκτέλεση του REST API μας.

    +
  • +
  • +

    Έπειτα με μια απομακρυσμένη σύνδεση στη βάση μας της οποίας τα στοιχεία πρόσβασης γίνονται στο Heroku, +πραγματοποιούμε μία σύνδεση και δημιουργούμε τον πίνακά μας για την αποθήκευση.

    +
  • +
  • +

    Τέλος το αρχείο Procfile το οποίο περιέχει το αρχείο το οποίο φορτώσει το gunicorn το οποίο έχει τη μορφή:

  • -
    -

    Το αρχείο αυτό έχει τη μορφή αυτή:

    -
    web: gunicorn serv:app --preload --timeout 150000
    @@ -822,80 +950,62 @@ mysql-connector
    • -<<<<<<< HEAD -

      Έπειτα με μια απομακρυσμένη σύνδεση στη βάση μας της οποίας τα στοιχεία πρόσβασης γίνονται στο Heroku, -πραγματοποιούμε μία σύνδεση και δημιουργούμε τον πίνακά μας για την αποθήκευση.

      -=======

      Έπειτα με μια απομακρυσμένη σύνδεση στη βάση μας της οποίας τα στοιχεία πρόσβασης δίνονται από Heroku, πραγματοποιούμε μία σύνδεση και δημιουργούμε τον πίνακά μας για την αποθήκευση των δεδομένων.

      ->>>>>>> 6cae23e4eeddcdfcc8a558241aeb46b4de0153df
    -

    2.1.2. REST API

    -
    -

    Το REST API ουσιαστικά σηκώνει δύο υπηρεσίες. Αυτές είναι:

    -
    -
    -
      -
    • -

      / [GET]: επιστρέφει ένα Array από JSON objects, ένα JSON για κάθε θέση του parking αν είναι διαθέσιμη ή όχι κωδικοποιημένα με 0 ή 1. -Τα δεδομένα που επιστρέφει γίνονται fetch από τη βάση δεδομένων.

      -
    • -
    -
    +

    1.3.5. Σε άλλη περίπτωση Deployment στο Localhost

    -

    Για παράδειγμα:

    +

    Στην περίπτωση όπου η πλατφόρμα Heroku μας περιορίζει στα ερωτήματα στη βάση δεδομένων που χρησιμοποιούμε +κάνουμε deploy της εφαρμογής στον localhost. Για να το επιτύχουμε αυτό θα εκτελέσουμε τις εξής εντολές στο +terminal.

    -
    [{"no": 1, "status": false}, {"no": 2, "status": false}, {"no": 3, "status": false}, {"no": 4, "status": true}, {"no": 5, "status": false}, {"no": 6, "status": false}, {"no": 7, "status": false}, {"no": 8, "status": false}]
    +
    export FLASK_APP=serv
    +export FLASK_DEBUG=1
    +flask run --host=[IP-v4] --port=8080
    -
    -
      -
    • -

      /parkingStatus [POST]: που μας επιτρέπει να αλλάξουμε την κατάσταση μίας θέσης parking. Στο POST τα δεδομένα -ορίζονται στο body σε αναπαράσταση JSON, έτσι ώστε ο Server να είναι ικανός να τα επεξεργαστεί και να τα αποθηκεύσει -στη βάση δεδομένων που χρησιμοποιούμε.

      -
    • -
    -
    -

    Για παράδειγμα:

    -
    -
    -
    {"no": 2, "status": false}
    +
    +

    1.4. Διεπαφή Χρήστη (4ο μέρος)

    +
    +

    1.4.1. Η διεπαφή του χρήστη

    +
    +

    Η διεπαφή του χρήστη αποτελείται από μία HTML σελίδα η οποία ενσωματώνει δύο JavaScript Processes. +Σκοπός αυτής είναι η αναπαράσταση της κατάστασης του Parking σε ένα γραφικό, φιλικό προς τον χρήστη περιβάλλον. +Η σελίδα λοιπόν επεικονίζει για κάθε θέση parking με χρώμα κόκκινο την "μη ελεύθεση" και με πράσινο την "ελεύθερη".

    +
    +

    Ένα παράδειγμα μέσω στιγμιοτύπου παρουσιάζεται παρακάτω.

    +
    +
    +
    +
    +1000
    +
    Figure 4. Στιγμιότυπο παραδείγματος εκτέλεσης της διεπαφής χρήστη.
    -
    -

    3. Διεπαφή Χρήστη (4ο μέρος)

    -
    -
    -

    3.1. Η διεπαφή του χρήστη

    -
    -

    Η διεπαφή του χρήστη αποτελείται από μία HTML σελίδα η οποία ενσωματώνει και δύο JavaScript Processes. -Σκοπός αυτής είναι η ανααπαράσταση της κατάστασης του Parking. Η σελίδα λοιπόν ενσωματώνει για κάθε θέση -parking

    -

    4. Autonomous Parking

    +

    2. Autonomous Parking

    -

    Το αυτότομο πρκάριμα αποτελείται από το όχημα με εγκατεστημένους τους απάραίτητους αισθητήρες και ελεγκτές -καθώς και έναν μικροελεγκτή (Arduino) για τον έλεγχο αυτών των ελεγκτών. Σκοπός είναι το όχημα να μπορεί +

    Το αυτόνομο πρκάριμα αποτελείται από το όχημα με εγκατεστημένους τους απάραίτητους αισθητήρες και ελεγκτές +καθώς, έναν μικροελεγκτή (Arduino) για τον έλεγχο αυτών των ελεγκτών και ένα Raspberry Pi1. Σκοπός είναι το όχημα να μπορεί να μάθει μέσω του διαδικτύου το "Status" του parking και να παρκάρει στην 1η διαθέσιμη θέση εφ' όσων -υπάρχει μία τουλάχιστων διαθέσιμη θέση στον χώρο στάθμευσης.

    +υπάρχει μία τουλάχιστoν διαθέσιμη θέση στον χώρο στάθμευσης.

    Η υλοποίηση του αυτόνομου parking χωρίζεται σε δύο βασικά μέρη.

    @@ -913,9 +1023,9 @@ parking

    -

    4.1. Microcotroller and Car

    +

    2.1. Microcotroller and Car (1ο Μέρος)

    -

    4.1.1. Υλικά Κόμβου

    +

    2.1.1. Υλικά Κόμβου

    • @@ -949,7 +1059,7 @@ parking

    -

    4.1.2. Υλοποίηση και Προγραμματισμός

    +

    2.1.2. Υλοποίηση Microcontroller on Car

    Ο motor driver, το Servo motor καθώς και ο Ultrasonic αισθητήρας κουμπώνουν στον μικροελεγκτή Arduino Uno που χρησιμοποιούμε, τον οποίο τον εγκαθηστούμε πάνω στο καλούπι του οχήματος το οποίο έχει εγκατεστημένα 4 τροχούς. Οι τροχοί οδηοούνται από 4 moters @@ -964,10 +1074,21 @@ parking

    1000
    -
    Figure 4. Συνδεσμολογία moter, motor driver, arduino, ultrasonic sensor και servo motor.
    +
    Figure 5. Συνδεσμολογία moter, motor driver, arduino, ultrasonic sensor και servo motor.
    +
    +
    +
    +

    2.2. Gateway Κόμβος (2ο Μέρος)

    +
    +

    Ο Gateway κόμβος του αυτόνομου οχήματος που θα έρθει στην θέση να παρκάρει μόνο του στο parking (ΙοΤ), είναι υπεύθυνος +για την διασύνδεση του οχήματος με το διαδίκτυο. Γι' αυτό το λόγο το process που σχεδιάσαμε να τρέχει σε αυτό το σημείο +είναι υπεύθυνο για την αναζήτηση της πληροφορίας ποια είναι η πρώτη ελεύθερη για να παρκάρει το όχημα και στη συνέχεια +να αποστέλει τον αριθμό της θέσης στον μικροελεγκτή Arduino ο οποίος είναι υπεύθυνος να πάρει αυτή την τιμή και να κατευθύνει +το όχημα.

    +
    @@ -985,14 +1106,9 @@ SLOW SUCCESS BUILDS CHARACTER, FAST SUCCESS BUILDS EGO. - diff --git a/serverNode/DB.sql b/serverNode/DB.sql index 61a2b60..c5b8235 100644 --- a/serverNode/DB.sql +++ b/serverNode/DB.sql @@ -1,7 +1,16 @@ DROP TABLE IF EXISTS PARKING; +DROP TABLE IF EXISTS USERS; CREATE TABLE IF NOT EXISTS PARKING ( PARKING_CODE INT(4) NOT NULL UNIQUE, PARKING_STATUS BOOLEAN NOT NULL ); +CREATE TABLE IF NOT EXISTS USERS ( + USER_NO INT(4) AUTO_INCREMENT, + USER_NAME VARCHAR(40) NOT NULL UNIQUE, + USER_PASS VARCHAR(40) NOT NULL, + PRIMARY KEY(USER_NO) +); + +INSERT INTO USERS(USER_NAME, USER_PASS) VALUES("root", "root");