IoT project implemented with RabbitMQ broker
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
PurpleRose ee4327097e Update 'README.md' 4 years ago
ArduinoScript Upload files to 'ArduinoScript' 4 years ago
InfluxDB&Grafana_Compose Upload files to 'InfluxDB&Grafana_Compose' 4 years ago
MyConsumer Upload files to 'MyConsumer' 4 years ago
MyServer Upload files to 'MyServer' 4 years ago
My_Producer Upload files to 'My_Producer' 4 years ago
README.md Update 'README.md' 4 years ago

README.md

Εργασία για το εργαστήριο IoT

Το συγκεκριμένο project υλοποιεί μία μέθοδο επικοινωνίας publish/subscribe χρησιμοποιώντας τον RabbitMQ Broker. Η υλοποίηση αυτή μεταξύ άλλων προσθέτει λειτουργίες όπως, η εγγραφή των ληφθέντων τιμών σε μια βάση με σκοπό την απεικόνισή τους και την αποστολή των ίδιων τιμών σε έναν απομακρυσμένο server για την περαιτέρω επεξεργασία τους.

Αρχιτεκτονική

Η αρχιτεκτονική χωρίζεται σε 5 μεγάλα κομμάτια :

  1. Τον producer όπου παράγει και στέλνει τις τιμές του αισθητήρα.

  2. Τον RabbitMQ broker όπου αποθηκεύει προσωρινά τις τιμές που στέλνει ο producer.

  3. Τον consumer που καταναλώνει τις αποθηκευμένες απο τον broker τιμές.

  4. Την βάση και το monitoring tool , όπου αποθηκεύονται και προβάλλονται οι τιμές.

  5. Τον απομακρυσμένο server όπου αποστέλλονται οι τιμές για περαιτέρω επεξεργασία.

Πιο συγκεκριμένα η αρχιτεκτονική είναι η εξής:

Αρχικτορνική

Υλικά

  • Arduino Uno
  • TMP36Gz temp sensor
  • Raspberry Pi 3
  • Desktop PC with Docker

Στήσιμο του project

  • Κατεβάζουμε το repo απο το site του swarmlab link. Έχουμε στα χέρια μας 5 φακέλους, έναν για κάθε κομμάτι που θα πρέπει να στήσουμε.

Αrduino

Ξεκινώντας με το Arduino, θα πρέπει να το συνδέσουμε με τον υπολογιστή μας και μέσο της πλατφόρμας Arduino IDE(αν δεν υπάρχει την κατεβάζουμε και την εγκαθιστούμε link) να περάσουμε τον κώδικα που βρίσκεται στο αρχείο readTempValuesFromArduino.ino στο Arduino.

enter image description here

Πιθανό πρόβλημα κατά τη μεταφορά του κώδικα στο Arduino:

[can't open device "/dev/ttyUSB0": Perm. denied (Linux permissions)]

Λύση: Ανοίγουμε το τερματικό του συστήματός μας και πληκτρολογούμε:

sudo chmod ugo+w /dev/ttyUSB0

Την ίδια εντολή πρέπει να τρέξουμε και στο raspberry όταν θα το συνδέσουμε με το Αrduino.

Σύνδεση του αισθητήρα με το Arduino

Όπως φαίνεται και πιο πάνω στην εικόνα της αρχιτεκτονικής, ο αισθητήρας έχει τρία πόδια (Vcc, Gnd , values). Συνδέουμε λοιπόν το μεσαίο πόδι του αισθητήρα με την αναλογική υποδοχή Α0 (όπως φαίνεται και στον κώδικα) για να μπορούμε να παίρνουμε τις τιμές του, το αριστερό του πόδι στη τάση (Vcc) και το δεξί του πόδι στη γείωση (Gnd). (1) Με βάση τον κώδικα για το Arduino μπορούμε να αλλάξουμε το pin για τις τιμές του αισθητήρα απο Α0 σε όποια αναλογική επαφή θέλουμε και αντίστοιχα αλλάζουμε και το pin στο κώδικα. (2) Αντίστοιχα μπορούμε να αλλάξουμε τη τιμή στη συνάρτηση delay με σκοπό την πιο συχνή ή την πιο αραιή δειγματοληψία. (3) Πατάμε το κουμπί για compile και αν δεν υπάρχουν λάθοι στο κώδικα... (4) Πατάμε το κουμπί για upload στο Arduino.

Raspberry

Producer

Υλοποιούμε τα βήματα σχετικά με το Raspberry που βρίσκονται εδώ προκειμένου να έχουμε πρόσβαση στη συσκευή.

enter image description here Εφόσον είμαστε μέσα στη συσκευή μεταφέρουμε τα αρχεία που κατεβάσαμε απο το repo και βρίσκονται μέσα στο φάκελο MyProducer (producer.js, package.json). Στη συνέχεια τρέχουμε την εντολή:

npm install

Για να μας κατεβάσει στη συσκευή όλα τα dependencies που χρειάζεται το script producer.js για να τρέξει σωστά. Και τέλος τρέχουμε την εντολή:

sudo chmod ugo+w /dev/ttyUSB0

Για να μπορεί να στείλει το Arduino δεδομένα μέσο της σειριακής επαφής. Αν δεν υπάρχει η ttyUSB0 επαφή για επικοινωνία στο Raspberry τότε τρέχουμε:

ls /dev/tty*

Για να δούμε όλες τις επαφές του Raspberry και σε ποιά είναι συνδεδεμένο το Arduino. Επαναλαμβάνουμε την εντολη αλλαγής δικαιωμάτων με τη κατάλληλη επαφή.

Docker

Για να μπορέσουν οι υπόλοιπες υπηρεσίες να τρέχουν θα χρειαστεί να εγκαταστήσουμε το Docker και το Docker Compose στον τοπικό μας υπολογιστή link.

Consumer

Κατευθυνόμαστε στο φάκελο MyConsumer και ανοίγουμε ένα τερματικό. Στη συνέχεια τρέχουμε την εντολή:

docker build -t myconsumer .

Η συγκεκριμένη εντολή θα δημιουργήσει ένα docker image το οποίο περιέχει ότι χρειάζεται το script consumer.js για να τρέξει. Στη συνέχεια μπορούμε να τρέξουμε την εντολή:

docker run -it -p 5673:5673 myconsumer

Για να σηκώσουμε έναν container απο το συγκεκριμένο image για την υπηρεσία του consumer.

Όπως φαίνεται απο την εντολή run κάνουμε expose τη πόρτα 5673 απο τον υπολογιστή μας στην πόρτα 5673 του container.

Τέλος ελέγχουμε αν ο container τρέχει με την εντολή:

docker ps

Server

Την ίδια διαδικασία ακολουθούμε και για την υπηρεσία του server. Κατευθυνόμαστε στο φάκελο MyServer και ανοίγουμε ένα τερματικό. Στη συνέχεια τρέχουμε την εντολή:

docker build -t atticaregionserver .

Η συγκεκριμένη εντολή θα δημιουργήσει ένα docker image το οποίο περιέχει ότι χρειάζεται το script server.js για να τρέξει. Στη συνέχεια μπορούμε να τρέξουμε την εντολή:

docker run -it -p 4000:4000 atticaregionserver

Για να σηκώσουμε έναν container απο το συγκεκριμένο image για την υπηρεσία του server.

Όπως φαίνεται απο την εντολή run κάνουμε expose τη πόρτα 4000 απο τον υπολογιστή μας στην πόρτα 4000 του container.

Τέλος ελέγχουμε αν ο container τρέχει με την εντολή:

docker ps

RabbitMQ

Η επόμενη υπηρεσία που θα χρειαστούμε είναι ο RabbitMQ broker. Απο όλες τις λειτουργίες του RabbitMQ (fanout κτλπ) εμείς θα χρησιμοποιήσουμε την Direct exchange.

enter image description here Ξεκινόντας θα πρέπει να κατεβάσουμε το έτοιμο RabbitMQ image απο το docker hub και να το τρέξουμε με την εντολή:

docker run -d -p 15672:15672 -p 5672:5672 --name rabbitmq rabbitmq:3-management

Το docker θα κατεβάσει το image και θα το τρέξει κάνοντας expose τις πόρτες που του είπαμε (default ports).

Η πόρτα 15672 είναι για τον manager και η πόρτα 5672 είναι για τον broker.

Μπορούμε στη συνέχεια να μεταβούμε στη πόρτα του manager(localhost:15672) για να κάνουμε περαιτέρω ρυθμίσεις αν το επιθυμούμε. Θα μας ζητήσει κάποια στοιχεία, πληκτρολογούμε για username και password : guest Και είμαστε πλεον μέσα στον manager.

enter image description here

Μπορούμε απο εδώ να κάνουμε overview την διαδικασία του produce και consume βλέποντας τα γραφήματα, τις ταχύτητες consume και produce στο tab Queues , τα connection που έχουμε και τα channels. Επιπλέον μπορούμε αν θέλουμε να φτιάξουμε έναν δικό μας χρήστη στο tab Admin. H διαδικασία είναι η εξής:

  1. Μεταβένουμε στο tab Admin.

  2. Στο drop down menu Add a User βάζουμε τα στοιχεία που επιθυμούμε , στην επιλογή Tag επιλέγουμε Admin και πατάμε το κουμπί Add User.

  3. Στη συνέχεια επιλέγουμε τον χρήστη που φτιάξαμε και το panel Set permission, στην επιλογή Virtual Host επιλέγουμε "/" ώστε να γίνει admin ο χρήστης και πατάμε το κουμπί Set permission.

Grafana & InfluxDB

Σε αυτό το σημείο εκτός απο τα images του Grafana και της InfluxDB θα χρειαστούμε και ένα δίκτυο προκειμένου να μπορεί να δει αυτόματα το Grafana τη βάση. Η δομή που θέλουμε να πετύχουμε είναι η παρακάτω:

enter image description here Για να πετύχουμε την παραπάνω δομή δημιουργούμε ένα docker network με την εντολή:

docker network create influxDB_Grafana_network

Μπορούμε να δούμε τα διαθέσιμα networks με την εντολή:

docker network ls

Επιπλέον θα χρειαστούμε δύο volumes για να μη χάνονται τα δεδομένα της βάσης και του Grafana κάθε φορά που πέφτουν οι containers. Φτιάχνουμε τα δύο volumes με τις εντολές:

docker volume create grafana_volume
docker volume create influxdb_volume

Μπορούμε να δούμε τα διαθέσιμα networks με την εντολή:

docker volume ls

Επόμενο βήμα είναι να μεταβούμε στο φάκελο InfluxDB&Grafana compose και να τρέξουμε την εντολή:

 docker-compose up -d

Η συγκεκριμένη εντολή θα υλοποιήσει τα περιεχόμενα του docker-compose.yml αρχείου.

enter image description here Όπως φαίνεται και στο παραπάνω αρχείο με το yml file σηκώνονται δυο containers(InfluxDB,Grafana) οι οποίοι χρησιμοποιούν το κοινό bridge network και τα volumes.

Εφόσον σηκωθούν οι containers με την εντολή:

docker exec -it influxdb_container sh

Μπορούμε να πάρουμε shell μέσα στον container της InfluxDB. Αμέσως μετά πληκτρολογούμε influx για να μεταβούμε στο shell της InfluxDB. enter image description here Στη συνέχεια φτιάχνουμε τη βάση μας με την εντολή:

create database values_from_sensor

Έπειτα μπορούμε να δούμε τη βάση που φτιάξαμε με την εντολή:

show databases

Grafana(set up)

Το επόμενο βήμα είναι να μεταβούμε στο application του Granafa που τρέχει στη πόρτα 3000. Πληκτρολογούμε στον browser μας localhost:3000. Tα αρχικά στοιχεία για username και password είναι admin.

Τώρα πρέπει να ορίσουμε την πηγή δεδομένων (data source) όπου στη περίπτωση μας είναι η InfluxDB.

enter image description here

enter image description here

enter image description here

Συμπληρώνουμε τα στοιχεία της βάσης:

enter image description here

Τέλος πατάμε Save and Test

Δημιουργεία Dashboard

enter image description here

enter image description here

Επιλέγουμε το data source που φτιάξαμε και έπειτα το measurement που θέλουμε να προβάλουμε.

Επιπλέον ρυθμίσεις για καλύτερη προβολή των τιμών απο το tab Panel δεξία της οθόνης.

enter image description here

enter image description here

enter image description here

Kώδικας

Απο τα αρχεία του κώδικα θα παρουσιαστούν τα πιο σημαντικά σημεία του με σκοπό την κατανόηση του τρόπου λειτουργίας (όχι δηλώσεις μεταβλητών κτλπ).

producer.js

enter image description here

  1. Εισαγωγή δύο απαραίτητων module για την λειτουργία του producer.

  2. Έναρξη επικοινωνίας με το Arduino μέσο της σειριακής πόρτας (σε ρυθμό 9600).

  3. Αρχικοποίηση των ρυθμίσεων του RabbitMQ ώστε να ξέρω που θα στείλω τα δεδομένα μου (που να γίνει το send to queue).

enter image description here

  1. Ορισμός ονόματος queue

  2. Δημιουργία connection, channel και queue για το RabbitMQ

  3. Ανάγνωση της σειριακής θύρας

  4. Δημιουργεία ενός κενού javascript object με σκοπό να το γεμίσουμε με το όνομα του αισθητήρα και της τιμή που διαβάστηκε απο την σειριακή πόρτα (εφαρμογή της μεθόδου slice για να κόψουμε το "\r" απο τα δεδομένα που διαβάζονται στην σειριακή πόρτα).

  5. Μετατροπή του javascript object σε JSON αποστολή του στη queue (JSON γιατί είναι απαιτούμενο του RabbitMQ).

  6. Εφαρμογή της συνάρτησης.

consumer.js

enter image description here

  1. Εισαγωγή 4 απαραίτητων module για την λειτουργία του consumer.

  2. Aρχικοποίηση των ρυθμίσεων για την υπηρεσία του mail.

  3. Αρχικοποίηση των επιλογών για την υπηρεσία του mail.

  4. Αρχικοποίηση της σύνδεσης με τον εξωτερικό server που θα σταλούν τα δεδομένα για περαιτέρω επεξεργασία.

Αποστολή του event "join_Temp_room" σε σκοπό την εισαγωγή στο room που επεξεργάζονται οι θερμοκρασίες.

Αν η εισαγωγή στο room ήταν επιτυχής ή αποτυχής γίνεται εκτύπωση του αντίστοιχου μηνύματος.

enter image description here

  1. Αρχικοποίηση των ρυθμίσεων της βάσης με σκοπό να μπορώ να γράψω και να διαβάσω απο αυτή. Οι τιμές που καταγράφονται στη βάση έχουν το measurement temp , είναι τύπου float και περιγράφονται απο το tag sensor (θα μπορούσε το tag να έχει πολλές τιμές π.χ. building1 , floor2 , room55 με σκοπό να προσδιορίσουμε ακριβώς τη θέση της προερχόμενης τιμής).

  2. Αρχικοποίηση των ρυθμίσεων του RabbitMQ ώστε να ξέρω απο που θα πάρω τα δεδομένα μου (που να γίνει το consume from queue).

enter image description here

  1. Ανάθεση του ονόματος της queue και του ονόματος του αισθητήρα.

  2. Δημιουργία connection, channel και queue για το RabbitMQ.

  3. Consume και μετατροπή του JSON σε javascript object για την επεξεργασία του.

  4. Έλεγχος του ονόματος του αισθητήρα με σκοπό να αποφύγω να πάρω τιμή άλλου μεγέθους (π.χ. υγρασία).

  5. Acknowledge του μυνήματος που έκανα consume με σκοπό να σβηστεί απο την queue.

  6. Αποστολή της τιμής μαζί με το όνομα του αισθητήρα στη βάση.

  7. Μετατροπή του javascript object σε JSON και αποστολή του στον εξωτερικό server για επεξεργασία.

  8. Εκτύπωση μηνύματος αν το όνομα του αισθητήρα δεν είναι το ήδη ορισμένο.

enter image description here

  1. (6) ανά 5 λεπτά γίνεται ένα query στη βάση και επιστρέφει όλες τις τιμές των τελευταίων 5 λεπτών.

  2. Αποθήκευση τιμών σε ένα array.

  3. Προσπέλαση όλου του array.

  4. Έλεγχος των τιμών ανά ζευγάρια των δύο και υπολογισμός αν υπάρχει ποσοστιαία αύξηση ή μείωση αντίστοιχα μεταξύ των τιμών. Αν υπάρχει , τροποποιείται σε αντίστοιχη μορφή το κείμενο του mail.

  5. Αποστολή του mail ειδοποίησης.

  6. Ορισμός χρονόμετρου.

server.js

enter image description here

  1. Εισαγωγή 4 απαραίτητων module για την λειτουργία του server.

  2. Αρχικοποίηση του server και του socket.

  3. Array διαθέσιμων room.

enter image description here

  1. Έναρξη server.

  2. Αναμονή για συνδέσεις.

  3. Ενεργοποίηση του event "join_Temp_room".

  4. Έλεγχος αν το δωμάτιο που έστειλε ο consumer είναι υπαρκτό (αν είναι γινεται η εισαγωγή του consumer στο συγκεκριμένο δωμάτιο).

  5. Ενεργοποίηση του event "handleData".

  6. Μετατροπή του JSON σε javascript object.

  7. Εγγραγή των δεδομένων που έλαβε ο server στο αρχείο tempValues.txt για την περεταίρω επεξεργασία.

Ενδεικτικό τρέξιμο

Αναμονή για δεδομένα απο τον producer

enter image description here

Αύξηση θερμοκρασίας πάνω απο 40%

enter image description here

Ειδοποίηση χρήστη

enter image description here

Πηγές

https://git.swarmlab.io:3000/zeus/iot-swarm-example/raw/branch/master/docs/README.adoc#_server_site http://docs.swarmlab.io/SwarmLab-HowTos/labs/IoT/SensorNode2Server.adoc.html https://www.influxdata.com/blog/getting-started-with-node-influx/ https://www.rabbitmq.com/tutorials/tutorial-one-javascript.html https://node-influx.github.io/class/src/index.js~InfluxDB.html https://www.thedevstop.com/metric-visualization-with-node-influxdb-and-grafana/ https://github.com/vicanso/influxdb-nodejs https://www.w3schools.com/nodejs/nodejs_email.asp https://docs.influxdata.com/influxdb/v1.8/query_language/explore-data/ https://github.com/influxdata/influxdb/issues/4209