diff --git a/.README.md.swp b/.README.md.swp deleted file mode 100644 index 068c8d1..0000000 Binary files a/.README.md.swp and /dev/null differ diff --git a/Photos/diagram1.png b/Photos/diagram1.png new file mode 100644 index 0000000..c9a61bd Binary files /dev/null and b/Photos/diagram1.png differ diff --git a/Photos/screenshot_web_ui.png b/Photos/screenshot_web_ui.png index 3bb450f..2d1bf46 100644 Binary files a/Photos/screenshot_web_ui.png and b/Photos/screenshot_web_ui.png differ diff --git a/README.md b/README.md index 316a5ed..79d9022 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,16 @@ - At folder serverNode/ there is a flask-Python REST-API to provide parking status. -- At folder sensorNode/ there is the Arduino code that sense the parking position sta--tus +- At folder sensorNode/ there is the Arduino code that sense the parking position status and send it via serial port the information if there is a car or no. -- At folder gatewayNode/ there is the application that runs on Raspberry Pi, get +- At folder gatewayNode/ there is the application that runs on Raspberry Pi, that gets the information from Arduino and post it to REST-API as JSON. - At folder webInterface/ there is an html page that provide the parking status simply get the information as JSON from REST-API. + +- At folder autonomousCar/ there is the Arduino code of autonomous Car Parking. + +- At folder autonomousCarGateway/ there is the application that runs on Raspberry Pi, +gets the information from REST WEB Server and know the first free parking. diff --git a/autonomousCar/autonomousCar.ino b/autonomousCar/autonomousCar.ino index 9e9d728..c0e76cd 100644 --- a/autonomousCar/autonomousCar.ino +++ b/autonomousCar/autonomousCar.ino @@ -127,37 +127,6 @@ void serialFlush(){ } } -/* - * Stepper Function for Servo. - * 1st Step: straight - * 2nd Step: left - * 3rd Step: straight - * 4th Step: right - */ -void next_step() -{ - if(pos == 1) - { //Servo move to right - turnServo(90, 30); - pos = 2; - } - else if(pos ==2) - { //Servo move to center - turnServo(30, 90); - pos = 3; - } - else if(pos == 3) - { //Servo move to left - turnServo(90, 150); - pos = 4; - } - else if(pos == 4) - { //Servo move to center - turnServo(150, 90); - pos = 1; - } -} - /* * Distance meter via Ultrasonic */ @@ -303,9 +272,6 @@ int Serial_Input() while (number <= 0) { // convert the incoming byte to a char and add it to the string: number = Serial.parseInt(); - //Serial.print("Value:"); - //Serial.println(number); - // clear the string for new input: serialFlush(); } // if you get a newline, print the string, then the string's value: @@ -316,29 +282,11 @@ int Serial_Input() void loop() { // Calculating the distance +<<<<<<< HEAD //distance= getDistance(); +======= + distance= getDistance(); + park(Serial_Input()); +>>>>>>> b0babf3fb5efd5a1eaec732fcec23eef4b0d8956 - // Prints the distance on the Serial Monitor - //Serial.print("Distance: "); - // Serial.println(distance); - // Read serial input: - park(Serial_Input()); - //delay(800); -// if (distance <15) { -// // Change direction to motors -// turn(225); -// } else if (distance <13){ -// turn(200); -// } else { -// // Change direction to motors -// turn(MAX_WHEEL_SPEED); -// } -// if (distance < 6){ -// motor_stop(); -// // Set Ultrasonic to next step -// next_step(); -// // Move car -// moveCar(); -// } -// delay(100); } diff --git a/gatewayNode/parking.py b/gatewayNode/parking.py index 01d0c98..853edae 100644 --- a/gatewayNode/parking.py +++ b/gatewayNode/parking.py @@ -65,7 +65,7 @@ if json_data != "" and json_data != None: # If parking status changed from previous status # server would informed about this change. data = """{"no":""" + parkingCode + ""","status":""" + parkingStatus + """, "cookie": \"""" + cookie + """\"}""" - r = s.post(url = API_ENDPOINT, data = data) + r = requests.post(url = API_ENDPOINT, data = data) # IO : node prints to output the current if parkingStatus == "0": diff --git a/project.adoc b/project.adoc index 205d9eb..e8b6c16 100644 --- a/project.adoc +++ b/project.adoc @@ -100,6 +100,14 @@ image::Photos/arduino2.jpg[300,200] της θέσης του parking για τον οποίο είναι υπεύθυνος. Με κόκκινο χαρακτηρίζεται η θέση που είναι δεσμευμένη από ένα όχημα και με μπλε η ελεύθερη θέση, όπως φαίνεται στις παραπάνω εικόνες. + +[.float-group] +-- +[.center] +.Παρουσίαση ενός σχηματικού του κυκλώματος. +image::Photos/diagram1.png[1000,800] +-- + ==== Προγραμματισμός Κόμβου Για τον προγραμματισμό του Arduino Uno χρησιμοποιήσαμε μία σειριακή σύνδεση του μικροελεγκτή με τον υπολογιστή μας ο οποίος έφερε εγκατεστημένο το IDE του Arduino στον οποίο υπήρχαν όλες οι απαραίτητες @@ -156,6 +164,15 @@ ttyACM0 που βρίσκεται στο directory (/dev/ στα linux) και } ---- +Μετά της αυθεντικοποίηση του από τον Server τότε λαμβάνει ένα μύνημα το οποίο περιέχει το Session ID το οποίο χρησιμοποιεί +για την μετέπειτα επικοινωνία με αυτόν. Η απάντηση του αιτήματος αυθεντικοποίησης έχει την παρκάτω μορφή. + +[source, JSON] +---- +{ + "cookie": "8yhuxQL0iCid++BPZFXPM959EclBhDmvvrZrqt+yv1s=" +} +---- ==== Προγραμματισμός Κόμβου Ο επικοινωνία και ο προγραμματισμός του κόμβου αυτού, που είναι βασισμένος σε ένα Raspberry Pi 1, έγινε με σύνδεση (ssh) @@ -359,18 +376,32 @@ image::Photos/screenshot_web_ui.png[1000,800] ==== Υλικά Κόμβου * 1 x Arduino Uno * 1 x Servo Motor - * 1 x Motor Driver + * 1 x Motor Driver (Shield 1.1 - L2981) * 4 x Moter για τους 4 τροχούς * 1 x Ultrasonic - * 1 x 9V Battery - * 1 x 4,8V Battery + * 1 x USB Power from Raspberry PI * 1 x Car - * 1 x Raspberry Pi ==== Υλοποίηση Microcontroller on Car Ο motor driver, το Servo motor καθώς και ο Ultrasonic αισθητήρας κουμπώνουν στον μικροελεγκτή Arduino Uno που χρησιμοποιούμε, τον οποίο τον εγκαθηστούμε πάνω στο καλούπι του οχήματος το οποίο έχει εγκατεστημένα 4 τροχούς. Οι τροχοί οδηοούνται από 4 moters -τα οποία τροφοδοτούνται από τον motor driver. +τα οποία τροφοδοτούνται από τον motor driver. Ο motor driver πέρνει εντολές από το Arduino , ενώ το Arduino περιμένει μέχρι το Rasperry να στείλει πληροφορία. +Μόλις λάβει την πληροφορία από το Rasperry, υπολογίζουμε με το υπόλοιπο & το πηλίκο της θέσης του parking με το 2, την γραμμή και την θέση που το όχημα πρέπει να παρκάρει. +Στην συνέχεια , μόλις το όχημα έχει φτάσει μπροστά από την θέση που πρέπει να παρκάρει , με τις μετρήσεις του ultrasonic ελέγχει το πόσο μπροστά ή πίσω θα πάει το όχημα. + +[source, C] +---- +row = (parkingNo / 2); +side = (parkingNo % 2); + +if (side == 0) { + row = row - 1; +} +---- + +==== Προγραμματισμός Microcontroller on Car +O προγραμματισμός του Arduino έγινε με την ίδια λογική όπως έγινε και ο προγραμματισμός του Arduino παραπάνω. + Η συνδεσμολογία έχει την διάταξη που παρουσιάζεται παρακάτω: @@ -383,12 +414,36 @@ image::Photos/diagram.png[1000,800] === Gateway Κόμβος (2~ο~ Μέρος) -Ο Gateway κόμβος του αυτόνομου οχήματος που θα έρθει στην θέση να παρκάρει μόνο του στο parking (ΙοΤ), είναι υπεύθυνος +==== Υλικά Κόμβου + * 1 x Raspberry Pi 1 + * 1 x TP-Link WiFi Adapter + * 1 x Powerbank Power + +Ο Gateway κόμβος του αυτόνομου οχήματος που θα έρθει στην θέση να παρκάρει μόνο του στο parking, είναι υπεύθυνος για την διασύνδεση του οχήματος με το διαδίκτυο. Γι' αυτό το λόγο το process που σχεδιάσαμε να τρέχει σε αυτό το σημείο -είναι υπεύθυνο για την αναζήτηση της πληροφορίας ποια είναι η πρώτη ελεύθερη για να παρκάρει το όχημα και στη συνέχεια +είναι υπεύθυνο για την αναζήτηση της πληροφορίας, ποια είναι η πρώτη ελεύθερη για να παρκάρει το όχημα και στη συνέχεια να αποστέλει τον αριθμό της θέσης στον μικροελεγκτή Arduino ο οποίος είναι υπεύθυνος να πάρει αυτή την τιμή και να κατευθύνει το όχημα. +==== Υλοποίηση Gateway on Car +Ο gateway κόμβος ξεκινά μια HTTP σύνδεση με τον κετντρικό Server, ζητώντας μέσω υπηρεσίας REST API το 1~ο~ διαθέσιμο parking. +Αφού διαβάσει την απάντησή του τότε την απόστέλει σε μορφή String στο Arduino μέσω σειριακής επικοινωνίας στο arduino. + +==== Προγραμματιμός Gateway on Car +Το process που εκτελεί αυτή την επικοινωνία μεταξύ του κεντρικου Server και το Arduino στο όχημα είναι προγραμματισμένο σε γλώσσα +προγραμματισμού Python. + +== Προβλήματα που αντιμετωπίσαμε + +* Δεν καταφέραμε να κάνουμε Deploy στο swarmlab τον κεντρικό Server μας έτσι ώστε να έχουμε +via Internet επικοινωνία. + +* Δεν καταφέραμε να τελειοποιήσουμε το αυτόνομο παρκάριμα, και την ενορχύστρωσή του με το υπόλοιπο σύστημα. Το πρόβλημα που +αντιμετωπίσαμε συγκεκριμένα ήταν ο έλεγχος των δεδομένων που από το raspberry στο Arduino και το καθαρισμό του buffer στο +Arduino. Αυτό συνεπώς δεν μας επέτρεπε στο Arduino να διαβάσουμε από την σειριακή τον ακέραιο αριθμό (θέση parking) που έστελνε +το raspberry. + + .Reminder [NOTE] diff --git a/project.html b/project.html index a376b95..7fcd114 100644 --- a/project.html +++ b/project.html @@ -628,6 +628,16 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b της θέσης του parking για τον οποίο είναι υπεύθυνος. Με κόκκινο χαρακτηρίζεται η θέση που είναι δεσμευμένη από ένα όχημα και με μπλε η ελεύθερη θέση, όπως φαίνεται στις παραπάνω εικόνες.

+
+
+
+
+1000 +
+
Figure 3. Παρουσίαση ενός σχηματικού του κυκλώματος.
+
+
+

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

@@ -715,6 +725,17 @@ ttyACM0 που βρίσκεται στο directory (/dev/ στα linux) και }
+
+

Μετά της αυθεντικοποίηση του από τον Server τότε λαμβάνει ένα μύνημα το οποίο περιέχει το Session ID το οποίο χρησιμοποιεί +για την μετέπειτα επικοινωνία με αυτόν. Η απάντηση του αιτήματος αυθεντικοποίησης έχει την παρκάτω μορφή.

+
+
+
+
{
+    "cookie": "8yhuxQL0iCid++BPZFXPM959EclBhDmvvrZrqt+yv1s="
+}
+
+

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

@@ -875,7 +896,7 @@ WEB Server στη Python όπου η εκτέλεση θα πραγματοπο
1000
-
Figure 3. Describe Infrastructure as a Service as an example.
+
Figure 4. Describe Infrastructure as a Service as an example.
@@ -988,9 +1009,9 @@ flask run --host=[IP-v4] --port=8080
-1000 +1000
-
Figure 4. Στιγμιότυπο παραδείγματος εκτέλεσης της διεπαφής χρήστη.
+
Figure 5. Στιγμιότυπο παραδείγματος εκτέλεσης της διεπαφής χρήστη.
@@ -1035,7 +1056,7 @@ flask run --host=[IP-v4] --port=8080

1 x Servo Motor

  • -

    1 x Motor Driver

    +

    1 x Motor Driver (Shield 1.1 - L2981)

  • 4 x Moter για τους 4 τροχούς

    @@ -1044,17 +1065,11 @@ flask run --host=[IP-v4] --port=8080

    1 x Ultrasonic

  • -

    1 x 9V Battery

    -
  • -
  • -

    1 x 4,8V Battery

    +

    1 x USB Power from Raspberry PI

  • 1 x Car

  • -
  • -

    1 x Raspberry Pi

    -
  • @@ -1063,7 +1078,25 @@ flask run --host=[IP-v4] --port=8080

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

    +τα οποία τροφοδοτούνται από τον motor driver. Ο motor driver πέρνει εντολές από το Arduino , ενώ το Arduino περιμένει μέχρι το Rasperry να στείλει πληροφορία. +Μόλις λάβει την πληροφορία από το Rasperry, υπολογίζουμε με το υπόλοιπο & το πηλίκο της θέσης του parking με το 2, την γραμμή και την θέση που το όχημα πρέπει να παρκάρει. +Στην συνέχεια , μόλις το όχημα έχει φτάσει μπροστά από την θέση που πρέπει να παρκάρει , με τις μετρήσεις του ultrasonic ελέγχει το πόσο μπροστά ή πίσω θα πάει το όχημα.

    +
    +
    +
    +
    row = (parkingNo / 2);
    +side = (parkingNo % 2);
    +
    +if (side == 0) {
    +	row = row - 1;
    +}
    +
    +
    + +
    +

    2.1.3. Προγραμματισμός Microcontroller on Car

    +
    +

    O προγραμματισμός του Arduino έγινε με την ίδια λογική όπως έγινε και ο προγραμματισμός του Arduino παραπάνω.

    Η συνδεσμολογία έχει την διάταξη που παρουσιάζεται παρακάτω:

    @@ -1074,7 +1107,7 @@ flask run --host=[IP-v4] --port=8080
    1000
    -
    Figure 5. Συνδεσμολογία moter, motor driver, arduino, ultrasonic sensor και servo motor.
    +
    Figure 6. Συνδεσμολογία moter, motor driver, arduino, ultrasonic sensor και servo motor.
    @@ -1082,13 +1115,63 @@ flask run --host=[IP-v4] --port=8080

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

    +
    +

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

    +
    +
      +
    • +

      1 x Raspberry Pi 1

      +
    • +
    • +

      1 x TP-Link WiFi Adapter

      +
    • +
    • +

      1 x Powerbank Power

      +
    • +
    +
    -

    Ο Gateway κόμβος του αυτόνομου οχήματος που θα έρθει στην θέση να παρκάρει μόνο του στο parking (ΙοΤ), είναι υπεύθυνος +

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

    +
    +
    +

    2.2.2. Υλοποίηση Gateway on Car

    +
    +

    Ο gateway κόμβος ξεκινά μια HTTP σύνδεση με τον κετντρικό Server, ζητώντας μέσω υπηρεσίας REST API το 1ο διαθέσιμο parking. +Αφού διαβάσει την απάντησή του τότε την απόστέλει σε μορφή String στο Arduino μέσω σειριακής επικοινωνίας στο arduino.

    +
    +
    +
    +

    2.2.3. Προγραμματιμός Gateway on Car

    +
    +

    Το process που εκτελεί αυτή την επικοινωνία μεταξύ του κεντρικου Server και το Arduino στο όχημα είναι προγραμματισμένο σε γλώσσα +προγραμματισμού Python.

    +
    +
    +
    + + +
    +

    3. Προβλήματα που αντιμετωπίσαμε

    +
    +
    +
      +
    • +

      Δεν καταφέραμε να κάνουμε Deploy στο swarmlab τον κεντρικό Server μας έτσι ώστε να έχουμε +via Internet επικοινωνία.

      +
    • +
    • +

      Δεν καταφέραμε να τελειοποιήσουμε το αυτόνομο παρκάριμα, και την ενορχύστρωσή του με το υπόλοιπο σύστημα. Το πρόβλημα που +αντιμετωπίσαμε συγκεκριμένα ήταν ο έλεγχος των δεδομένων που από το raspberry στο Arduino και το καθαρισμό του buffer στο +Arduino. Αυτό συνεπώς δεν μας επέτρεπε στο Arduino να διαβάσουμε από την σειριακή τον ακέραιο αριθμό (θέση parking) που έστελνε +το raspberry.

      +
    • +
    +
    @@ -1105,10 +1188,9 @@ SLOW SUCCESS BUILDS CHARACTER, FAST SUCCESS BUILDS EGO. - diff --git a/serverNode/__pycache__/serv.cpython-37.pyc b/serverNode/__pycache__/serv.cpython-37.pyc index 04c4797..9f5a208 100644 Binary files a/serverNode/__pycache__/serv.cpython-37.pyc and b/serverNode/__pycache__/serv.cpython-37.pyc differ diff --git a/serverNode/serv.py b/serverNode/serv.py index 93230b7..51b65ec 100644 --- a/serverNode/serv.py +++ b/serverNode/serv.py @@ -20,18 +20,36 @@ CORS(app) # Session list sessions = [] +# Chart values +chart = [] + # creating an API object api = Api(app) -# Initialize the database Connection -mydb = mysql.connector.connect( - host = "127.0.0.1",#"q2gen47hi68k1yrb.chr7pe7iynqr.eu-west-1.rds.amazonaws.com", - user = "root",#"zsgmj50h7zgz9ioq", - password = "rootP",#"omk5l1hrwsgvlcez", - database = "PARKING"#"g0s9cnmdkziq6fsp" -) -myCursor = mydb.cursor() +# Initialize the database Connection (Classified) +class mySqlConnect: + def __init__(self): + self.con = con = mysql.connector.connect( + host = "127.0.0.1",#"q2gen47hi68k1yrb.chr7pe7iynqr.eu-west-1.rds.amazonaws.com", + user = "root",#"zsgmj50h7zgz9ioq", + password = "rootP",#"omk5l1hrwsgvlcez", + database = "PARKING"#"g0s9cnmdkziq6fsp" + ) + + self.cur = self.con.cursor(); + + def __del__(self): + self.cur.close() + self.con.close() + + @property + def cursor(self): + return self.cur + + @property + def connection(self): + return self.con # ================================== # Define our functions. @@ -40,6 +58,8 @@ myCursor = mydb.cursor() def getParkings(): parks = [] + sql = mySqlConnect() + myCursor = sql.cur myCursor.execute("SELECT * FROM PARKING") myRes = myCursor.fetchall() @@ -53,6 +73,9 @@ def getParkings(): # Define a function that get if a user with exiting credencials # username and password is authenticated. def isMember(username, password): + mysql = mySqlConnect() + myCursor = mysql.cur + myCursor.execute("SELECT * FROM USERS") myRes = myCursor.fetchall() @@ -75,6 +98,31 @@ def isAuthenticated(data): except KeyError as e: return False +# For the chart Data. +def updateChart(): + parks = getParkings() + all_parks = len(parks) + + full = 0 + + for p in parks: + if p['status'] == False: + full+=1 + + j = 1 + if len(chart) < 16 : + chart.append(full) + print (chart) + elif len(chart) == 16: + for i in chart: + chart[j] = i + j+=1 + + if j == 16: + break + chart[0] = full + return True + # ================================================================== # making a class for a particular resource @@ -89,7 +137,7 @@ class Parking(Resource): try: parks = getParkings() except (mysql.connector.errors.DatabaseError, mysql.connector.errors.InterfaceError) as e: - mydb.reconnect(attempts=1, delay=0) + print ("An error") return parks, 200 @@ -132,20 +180,28 @@ class ParkingStatus(Resource): toUpdate = False try: + mysql = mySqlConnect() + myCursor = mysql.cur + con = mysql.con + if not thereIs: # Make a new insert entry for a new Parking Code. values = (int(data['no']), int(data['status'])) myCursor.execute("INSERT INTO PARKING (PARKING_CODE, PARKING_STATUS) VALUES (%s, %s)", values) - mydb.commit() + con.commit() parks = getParkings() + + updateChart() elif toUpdate: # Make an Update status for Parking Code that availability changed. values = (int(data['status']), int(data['no'])) myCursor.execute("UPDATE PARKING SET PARKING_STATUS=%s WHERE PARKING_CODE=%s", values) - mydb.commit() + con.commit() parks = getParkings() + + updateChart() except (mysql.connector.errors.DatabaseError, mysql.connector.errors.InterfaceError) as e: - mydb.reconnect(attempts=1, delay=0) + print ("An error") return currentParking, 201 else: @@ -173,13 +229,27 @@ class Authenticate(Resource): else: return "Error authentication", 403 except (mysql.connector.errors.DatabaseError, mysql.connector.errors.InterfaceError) as e: - mydb.reconnect(attempts=1, delay=0) + print ("An error") + +# Chart +class Chart(Resource): + def get(self): + result = dict() + + j = 1 + for i in chart: + result[j] = i + j += 1 + + print (result) + return result, 200 # ================================================================== # matches the defined resources to their corresponding urls to REST APIs api.add_resource(Parking, '/') api.add_resource(ParkingStatus, '/parkingStatus') api.add_resource(Authenticate, '/authenticate') +api.add_resource(Chart, '/chart') # ================================================================== # ===========================MAIN CLASS============================= diff --git a/webInterface/parking.html b/webInterface/parking.html index d7e80a7..7990e86 100644 --- a/webInterface/parking.html +++ b/webInterface/parking.html @@ -21,6 +21,7 @@ $(document).ready(function(){ alert(server_protocol + "://" + server_ip + " " + server_port + ". Started!!!") $("#msg").empty(); if (server_ip !== "" && server_ip !== null && server_port !== "" && server_port !== null && server_protocol !== "" && server_protocol != null) { + all_parks = 0; $("#msg").html("ok!"); $("#approve").prop("disabled", true); @@ -66,6 +67,8 @@ $(document).ready(function(){ row++; pos = "r"; } + + all_parks = all_parks + 1; }); }, error: function(jqXHR, testStatus, errorThrown) { @@ -73,6 +76,34 @@ $(document).ready(function(){ timeout: 120000, }); + + jQuery.ajax({ + url: server_protocol + "://" + server_ip + ":" + server_port + "/chart", + type: "GET", + + contentType: "application/json; charset=utf-8", + success: function(resultData) { + min = 0; + max = all_parks; + chart = ""; + $("div#tab3").html(chart); + }, + error: function(jqXHR, testStatus, errorThrown) { + }, + + timeout: 120000, + }); setInterval(function () { jQuery.ajax({ url: server_protocol + "://" + server_ip + ":" + server_port + "/", @@ -132,6 +163,10 @@ $(document).ready(function(){
    +

    Διάγραμμα Χώρου Στάθμευσης

    +
    +
    +

    Parking Diagram