Browse Source

Update v1.3

master
Evangelos Oulis 5 years ago
parent
commit
ed42449de1
  1. 66
      project.adoc
  2. 88
      project.html
  3. 2
      serverNode/serv.py
  4. 24
      webInterface/parking.html

66
project.adoc

@ -176,9 +176,9 @@ link:++https://www.heroku.com/platform++[Heroku], για την οποιά μπ
image::Photos/itops-pizza_as_a_service.png[1000,800]
--
Για την διαδικασία του deployment εκτελούμε ένα σύνολο βημάτων τα οποία αποτελούνται από την αντιγραφή του κώδικα
σε ένα reposetory του link:++https://github.com/oulievancs/serverNode++[GitHub] και την δημιουργία ενός project στην πλατφόρμα για το
τρέξιμο του process. link:++https://stackabuse.com/deploying-a-flask-application-to-heroku/++[περισσότερα]. Ακόμα
Για το deployment εκτελούμε ένα σύνολο βημάτων τα οποία αποτελούνται από την ανάρτηση του κώδικα
σε ένα repository του link:++https://github.com/oulievancs/serverNode++[GitHub] και την δημιουργία ενός project στην πλατφόρμα Heroku.
, link:++https://stackabuse.com/deploying-a-flask-application-to-heroku/++[περισσότερα για το deployment εδώ]. Ακόμα
εγκαθισούμε στο project που μόλις φτιάξαμε μία MySQL βάση δεδομένων για να μπορούμε να αποθηκεύσουμε τα δεδομένα μας.
==== Deployment
@ -186,29 +186,69 @@ image::Photos/itops-pizza_as_a_service.png[1000,800]
ώστε να γνωρίζει το Heroku τι να μας προσφέρει. Αυτό επιτυγχάνεται με την αρχειοθέτηση αυτών σε ένα αρχείο
ονόματι requirements.txt .
Το αρχείο που περιέχει όλα τα απαραίτητα modules για τον κώδικά μας είναι:
[source, text]
----
flask
flask_restful
flask_cors
gunicorn==19.9.0
mysql-connector
----
* Έπειτα την δημιουργία ενός αρχείου που περιγράφει το που βρίσκεται η κύρια συνάρτηση μας (main) για την
έναρξη του process. Αυτό το αρχείο ονομάζεται Procfile . Στο αρχείο αυτό αναφέτεται ένα gunicorn module.
Ο gunicorn είναι ένας Python HTTP WEB server. Αυτό ουσιαστικά είναι ο ο πυρήνας για την εκτέλεση του API μας.
* Έπειτα με μια απομακρυσμένη σύνδεση στη βάση μας της οποίας τα στοιχεία πρόσβασης γαίνονται στο Heroku,
πραγματοποιούμε μία σύνδεση και δημιουργούμε τον πίνακά μας για την αποθήκευση.
Το αρχείο αυτό έχει τη μορφή αυτή:
[source, conf]
----
web: gunicorn serv:app --preload --timeout 150000
----
.Gunicorn
[NOTE]
====
Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy.
Source: https://gunicorn.org
====
* Έπειτα με μια απομακρυσμένη σύνδεση στη βάση μας της οποίας τα στοιχεία πρόσβασης δίνονται από Heroku,
πραγματοποιούμε μία σύνδεση και δημιουργούμε τον πίνακά μας για την αποθήκευση των δεδομένων.
==== REST API
Το REST API ουσιαστικά σηκώνει δύο υπηρεσίες. Αυτές είναι:
* / [GET]: που πας επιστρέφει για κάθε θέση του parking αν είναι διαθέσιμη ή όχι κωδικοποιημένα με 0 ή 1.
Στο response τα δεδομένα μας παίρνουν μορφή JSON. Τα δεδομένα που επιστρέφει γίνονται fetch από τη βάση δεδομένων.
* / [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]: που μας επιτρέπει να αλλάξουμε την κατάσταση μίας θέσης parking. Στο POST τα δεδομένα
ορίζονται στο body σε αναπαράσταση JSON, έτσι ώστε ο Server να είναι ικανός να τα επεξεργαστεί και να τα αποθηκεύσει
στη βάση δεδομένων που χρησιμοποιούμε.
Για παράδειγμα:
* /parkingStatus [POST]: που μας επιτρέπει να αλλάξουμε την κατάσταση μίας θέσης parking. Το POST των δεδομένων
στο body γίνεται με την JSON αναπαράστασή τους έτσι ώστε να μπορέσει ο Server να τα επεξεργαστεί, ο οποίος στη
συνέχεια αποθηκεύει την νέα θέση στη Βάση δεδομένων.
[source, json]
----
{"no": 2, "status": false}
----
== Διεπαφή Χρήστη (4~ο~ μέρος)
=== Η διεπαφή του χρήστη
Η διεπαφή του χρήστη αποτελείται από μία HTML σελίδα η οποία ενσωματώνει και δύο JavaScript Processes.
Σκοπός αυτής είναι η ανααπαράσταση της κατάστασης του Parking. Η σελίδα λοιπόν ενσωματώνει για κάθε θέση
parking
Η διεπαφή του χρήστη αποτελείται από μία HTML σελίδα η οποία ενσωματώνει δύο JavaScript Processes.
Σκοπός αυτής είναι η αναπαράσταση της κατάστασης του Parking. Η σελίδα λοιπόν επεικονίζει για κάθε θέση
parking με χρώμα κόκκινο την "μη ελεύθεση" και με πράσινο την "ελεύθερη".
== Autonomous Parking

88
project.html

@ -756,9 +756,9 @@ REST API έτσι ώστε να μπορούν να επικοινωνούν ε
</div>
</div>
<div class="paragraph">
<p>Για την διαδικασία του deployment εκτελούμε ένα σύνολο βημάτων τα οποία αποτελούνται από την αντιγραφή του κώδικα
σε ένα reposetory του <a href="https://github.com/oulievancs/serverNode">GitHub</a> και την δημιουργία ενός project στην πλατφόρμα για το
τρέξιμο του process. <a href="https://stackabuse.com/deploying-a-flask-application-to-heroku/">περισσότερα</a>. Ακόμα
<p>Για το deployment εκτελούμε ένα σύνολο βημάτων τα οποία αποτελούνται από την ανάρτηση του κώδικα
σε ένα repository του <a href="https://github.com/oulievancs/serverNode">GitHub</a> και την δημιουργία ενός project στην πλατφόρμα Heroku.
, <a href="https://stackabuse.com/deploying-a-flask-application-to-heroku/">περισσότερα για το deployment εδώ</a>. Ακόμα
εγκαθισούμε στο project που μόλις φτιάξαμε μία MySQL βάση δεδομένων για να μπορούμε να αποθηκεύσουμε τα δεδομένα μας.</p>
</div>
<div class="sect3">
@ -770,14 +770,60 @@ REST API έτσι ώστε να μπορούν να επικοινωνούν ε
ώστε να γνωρίζει το Heroku τι να μας προσφέρει. Αυτό επιτυγχάνεται με την αρχειοθέτηση αυτών σε ένα αρχείο
ονόματι requirements.txt .</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Το αρχείο που περιέχει όλα τα απαραίτητα modules για τον κώδικά μας είναι:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-text" data-lang="text">flask
flask_restful
flask_cors
gunicorn==19.9.0
mysql-connector</code></pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>Έπειτα την δημιουργία ενός αρχείου που περιγράφει το που βρίσκεται η κύρια συνάρτηση μας (main) για την
έναρξη του process. Αυτό το αρχείο ονομάζεται Procfile . Στο αρχείο αυτό αναφέτεται ένα gunicorn module.
Ο gunicorn είναι ένας Python HTTP WEB server. Αυτό ουσιαστικά είναι ο ο πυρήνας για την εκτέλεση του API μας.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Το αρχείο αυτό έχει τη μορφή αυτή:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-conf" data-lang="conf">web: gunicorn serv:app --preload --timeout 150000</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="title">Gunicorn</div>
<div class="paragraph">
<p>Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It&#8217;s a pre-fork worker model. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy.</p>
</div>
<div class="paragraph">
<p>Source: <a href="https://gunicorn.org" class="bare">https://gunicorn.org</a></p>
</div>
</td>
</tr>
</table>
</div>
<div class="ulist">
<ul>
<li>
<p>Έπειτα με μια απομακρυσμένη σύνδεση στη βάση μας της οποίας τα στοιχεία πρόσβασης γαίνονται στο Heroku,
πραγματοποιούμε μία σύνδεση και δημιουργούμε τον πίνακά μας για την αποθήκευση.</p>
<p>Έπειτα με μια απομακρυσμένη σύνδεση στη βάση μας της οποίας τα στοιχεία πρόσβασης δίνονται από Heroku,
πραγματοποιούμε μία σύνδεση και δημιουργούμε τον πίνακά μας για την αποθήκευση των δεδομένων.</p>
</li>
</ul>
</div>
@ -790,16 +836,36 @@ REST API έτσι ώστε να μπορούν να επικοινωνούν ε
<div class="ulist">
<ul>
<li>
<p>/ [GET]: που πας επιστρέφει για κάθε θέση του parking αν είναι διαθέσιμη ή όχι κωδικοποιημένα με 0 ή 1.
Στο response τα δεδομένα μας παίρνουν μορφή JSON. Τα δεδομένα που επιστρέφει γίνονται fetch από τη βάση δεδομένων.</p>
<p>/ [GET]: επιστρέφει ένα Array από JSON objects, ένα JSON για κάθε θέση του parking αν είναι διαθέσιμη ή όχι κωδικοποιημένα με 0 ή 1.
Τα δεδομένα που επιστρέφει γίνονται fetch από τη βάση δεδομένων.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Για παράδειγμα:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="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}]</code></pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>/parkingStatus [POST]: που μας επιτρέπει να αλλάξουμε την κατάσταση μίας θέσης parking. Το POST των δεδομένων
στο body γίνεται με την JSON αναπαράστασή τους έτσι ώστε να μπορέσει ο Server να τα επεξεργαστεί, ο οποίος στη
συνέχεια αποθηκεύει την νέα θέση στη Βάση δεδομένων.</p>
<p>/parkingStatus [POST]: που μας επιτρέπει να αλλάξουμε την κατάσταση μίας θέσης parking. Στο POST τα δεδομένα
ορίζονται στο body σε αναπαράσταση JSON, έτσι ώστε ο Server να είναι ικανός να τα επεξεργαστεί και να τα αποθηκεύσει
στη βάση δεδομένων που χρησιμοποιούμε.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Για παράδειγμα:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-json" data-lang="json">{"no": 2, "status": false}</code></pre>
</div>
</div>
</div>
</div>
</div>
@ -917,7 +983,7 @@ SLOW SUCCESS BUILDS CHARACTER, FAST SUCCESS BUILDS EGO.
</div>
<div id="footer">
<div id="footer-text">
Last updated 2020-01-21 09:12:33 +0200
Last updated 2020-01-21 11:33:54 +0200
</div>
</div>
</body>

2
serverNode/serv.py

@ -62,7 +62,7 @@ class ParkingStatus(Resource):
<body><h1>Not get at '/parkingStatus'.</h1></body>
</html>"""
def post(self):
# Gets the data into a JSON Object.
# Gets the data into as a JSON Object from HTTP request.
data = json.loads(request.data)
# SQL get all Parking places status.

24
webInterface/parking.html

@ -37,20 +37,22 @@ $(document).ready(function(){
$("tr#row0").append("<td width=\"20%\" bgcolor=\"lightgrey\"><div class=\"road\"></div></td>");
$("tr#row0").append("<td width=\"30%\" bgcolor=\"lightgrey\"><div class=\"road\"></div></td>");
$.each(resultData, function(key, val) {
console.log("Key " + key + ", val: " + val);
console.log("Parking No " + val.no + ", val: " + val.status);
content = "";
if (val == 0) {
key ++;
if (val.status == true) {
if (pos == "l") {
content = "<td id=\"park" + key + "\" width=\"30%\">No" + key + "<div id=\"" + key + "\" class=\"full left\"></div></td>";
content = "<td id=\"park" + val.no + "\" width=\"30%\">No" + val.no + "<div id=\"" + val.no + "\" class=\"full left\"></div></td>";
} else {
content = "<td id=\"park" + key + "\" width=\"30%\">No" + key + "<div id=\"" + key + "\" class=\"full\"></div></td>";
content = "<td id=\"park" + val.no + "\" width=\"30%\">No" + val.no + "<div id=\"" + val.no + "\" class=\"full\"></div></td>";
}
} else {
if (pos == "l") {
content = "<td id=\"park" + key + "\" width=\"30%\">No" + key + "<div id=\"" + key + "\" class=\"empty left\"></div></td>";
content = "<td id=\"park" + val.no + "\" width=\"30%\">No" + val.no + "<div id=\"" + val.no + "\" class=\"empty left\"></div></td>";
}
else {
content = "<td id=\"park" + key + "\" width=\"30%\">No" + key + "<div id=\"" + key + "\" class=\"empty\"></div></td>";
content = "<td id=\"park" + val.no + "\" width=\"30%\">No" + val.no + "<div id=\"" + val.no + "\" class=\"empty\"></div></td>";
}
}
if (pos == "r") {
@ -79,11 +81,11 @@ $(document).ready(function(){
contentType: "application/json; charset=utf-8",
success: function(resultData) {
$.each(resultData, function(key, val) {
console.log(key + " -> " + val);
if (val == "1")
$("div#" + key).removeClass("full").addClass("empty");
else if (val == "0")
$("div#" + key).removeClass("empty").addClass("full");
console.log("Parking No " + val.no + " -> " + val.status);
if (val.status == false)
$("div#" + val.no).removeClass("full").addClass("empty");
else if (val.status == true)
$("div#" + val.no).removeClass("empty").addClass("full");
});
},
error: function(jqXHR, testStatus, errorThrown) {

Loading…
Cancel
Save