Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.
| Ambdós costats versió prèvia Revisió prèvia Següent revisió | Revisió prèvia | ||
|
iot_django_aproximacio_un_dashboard_sobre_raspberry_pi [2023/06/24 16:04] jordi_gual_purti |
iot_django_aproximacio_un_dashboard_sobre_raspberry_pi [2023/06/25 06:36] (actual) jordi_gual_purti |
||
|---|---|---|---|
| Línia 98: | Línia 98: | ||
| </ | </ | ||
| - | === Instal·lació de la biblioteca FusionCharts ==== | + | <WRAP info> |
| + | Cal dir que l' | ||
| + | </ | ||
| + | |||
| + | ==== Instal·lació de la biblioteca FusionCharts | ||
| Abans de continuar veient com implementar la resta de components, cal dur a terme la instal·lació de la llibreria [[https:// | Abans de continuar veient com implementar la resta de components, cal dur a terme la instal·lació de la llibreria [[https:// | ||
| Línia 105: | Línia 109: | ||
| El nivell de detall d' | El nivell de detall d' | ||
| - | === Creació del dashboard senzill === | + | ==== Creació del dashboard senzill |
| L' | L' | ||
| Línia 112: | Línia 116: | ||
| - **Formulari selecció de data**: on escollirem la data sobre la qual volem generar la gràfica de les mesures registrades, | - **Formulari selecció de data**: on escollirem la data sobre la qual volem generar la gràfica de les mesures registrades, | ||
| - **Visualització de la gràfica**: pàgina que visualitzarà les mesures que tenim registrades del sensor escollit i de la data indicada en forma de gràfica temporal. Disposa d'un botó per tornar a la pàgina principal. | - **Visualització de la gràfica**: pàgina que visualitzarà les mesures que tenim registrades del sensor escollit i de la data indicada en forma de gràfica temporal. Disposa d'un botó per tornar a la pàgina principal. | ||
| + | |||
| + | <WRAP info> | ||
| + | En aquesta documentació, | ||
| + | </ | ||
| Aquests tres components són vistes de Django que estan implementades com es pot veure en el codi font que teniu a continuació: | Aquests tres components són vistes de Django que estan implementades com es pot veure en el codi font que teniu a continuació: | ||
| Línia 155: | Línia 163: | ||
| start = str(data) + ' 00: | start = str(data) + ' 00: | ||
| end = str(data) + ' 23: | end = str(data) + ' 23: | ||
| - | |||
| - | # Codi anul·lat, era una primera versió amb un model bàsic de gràfica que | ||
| - | # no dóna proporcionalitat temporal. | ||
| - | """ | ||
| - | dataSource = {} | ||
| - | dataSource[' | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | } | ||
| - | |||
| - | dataSource[' | ||
| - | # Iterem sobre les mostres de temperatura seleccionant les del dia seleccionat i del sensor que toca. | ||
| - | for key in TemperatureSample.objects.filter(timestamp__range=(start, | ||
| - | data = {} | ||
| - | data[' | ||
| - | data[' | ||
| - | dataSource[' | ||
| - | """ | ||
| | | ||
| # Preparem l' | # Preparem l' | ||
| Línia 212: | Línia 198: | ||
| </ | </ | ||
| + | |||
| + | Les templates HTML que s' | ||
| + | |||
| + | '' | ||
| + | <code html> | ||
| + | < | ||
| + | {% if latest_sensor_list %} | ||
| + | <ul> | ||
| + | {% for s in latest_sensor_list %} | ||
| + | < | ||
| + | {% endfor %} | ||
| + | </ul> | ||
| + | {% else %} | ||
| + | <p>No hi ha sensors disponibles</ | ||
| + | {% endif %} | ||
| + | </ | ||
| + | |||
| + | '' | ||
| + | <code html> | ||
| + | < | ||
| + | <form action="/ | ||
| + | {% csrf_token %} | ||
| + | {{form.as_p}} | ||
| + | <input type=" | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | '' | ||
| + | <code html> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | {% load static %} | ||
| + | <script type=" | ||
| + | <script type=" | ||
| + | <script type=" | ||
| + | </ | ||
| + | < | ||
| + | <div id=" | ||
| + | <div id=" | ||
| + | <a href="/ | ||
| + | < | ||
| + | </a> | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Automatització de la captura de dades ==== | ||
| + | |||
| + | La captura de dades s'ha de fer partint de la base que disposem d'un sensor. El muntatge que hem fet per a la implementació d' | ||
| + | {{ : | ||
| + | |||
| + | Tenint això, cal preparar un petit programa **python** que s' | ||
| + | <code python> | ||
| + | # | ||
| + | from django.core.wsgi import get_wsgi_application | ||
| + | import os | ||
| + | |||
| + | # Establim l' | ||
| + | os.environ.setdefault(" | ||
| + | |||
| + | # Instanciem un web service WSGI per tenir-lo com a passarel·la per al nostre django. | ||
| + | application = get_wsgi_application() | ||
| + | |||
| + | from temperature.models import TemperatureSensor, | ||
| + | import glob | ||
| + | from datetime import datetime, timedelta | ||
| + | import time | ||
| + | |||
| + | # Carreguem els drivers del sensor de temperatura. | ||
| + | os.system(' | ||
| + | os.system(' | ||
| + | |||
| + | # Configurem l' | ||
| + | # el funcionament del sensor Dallas DS18B20. | ||
| + | base_dir = '/ | ||
| + | device_folder = glob.glob(base_dir + ' | ||
| + | device_file = device_folder + '/ | ||
| + | |||
| + | # Aquestes dues funcions implementen la lectura de mostres de temperatura | ||
| + | # del sensor que tenim connectat al RPI. | ||
| + | def read_temp_raw(): | ||
| + | f = open(device_file, | ||
| + | lines = f.readlines() | ||
| + | f.close() | ||
| + | return lines | ||
| + | |||
| + | def read_temp(): | ||
| + | lines = read_temp_raw() | ||
| + | while lines[0].strip()[-3: | ||
| + | time.sleep(0.2) | ||
| + | lines = read_temp_raw() | ||
| + | equals_pos = lines[1].find(' | ||
| + | if equals_pos != -1: | ||
| + | temp_string = lines[1][equals_pos+2: | ||
| + | temp_c = float(temp_string) / 1000.0 | ||
| + | return temp_c | ||
| + | |||
| + | # Cada cop que executem aquest programa, agafem una mostra de la temperatura del | ||
| + | # sensor i la guardem a la BD a través del model de dades de l' | ||
| + | ts = datetime.now() + timedelta(hours=2) | ||
| + | mostra = TemperatureSample(sensor_id=1, | ||
| + | mostra.save() | ||
| + | </ | ||
| + | |||
| + | Per automatitzar la presa de mesures de temperatura només falta configurar el servei **cron** a través d'un arxiu **crontab**. Per programar una lectura de la temperatura cada 2 minuts tindríem el seguent arxiu '' | ||
| + | < | ||
| + | */2 * | ||
| + | |||
| + | </ | ||
| + | Per introduir aquesta configuració a la planificació de tasques del servei **cron** del sistema haurem d' | ||
| + | < | ||
| + | $ crontab crontab.cfg | ||
| + | </ | ||
| + | |||
| + | ==== Algunes imatges ==== | ||
| + | |||
| + | Per tenir una idea més detallada dels resultats obtinguts es faciliten algunes imatges del muntatge del hardware i de la visualització de la gràfica com a mostra del que hem d' | ||
| + | |||
| + | '' | ||
| + | {{ : | ||
| + | |||
| + | '' | ||
| + | {{ : | ||
| + | |||
| + | '' | ||
| + | {{ : | ||
| + | |||
| + | ===== Consideracions finals ===== | ||
| + | |||
| + | Per acabar, es fan constar algunes consideracions importants que cal tenir presents sobre aquest material, tenint en compte la seva naturalesa didàctica: | ||
| + | |||
| + | * Es tracta, com hem dit, d'un material que té un objectiu didàctic. Per tant, no contempla molts dels aspectes que caldria tenir presents si es tractés d'un projecte orientat a la posada en producció real. | ||
| + | * No s'ha dedicat cap esforç a fer-lo bonic aplicant, per exemple, estils CSS. | ||
| + | * Els mecanismes de control d' | ||
| + | * No es toca la qüestió de la posada en producció del sistema. | ||
| + | |||
| + | |||
| + | Aquest projecte s'ha implementat, | ||
| + | * Tenir els sensors associats a un hardware més senzill i barat (Arduino, ESP32, etc.), amb capacitat de connexió a xarxa. | ||
| + | * Tenir la base de dades en un sistema més potent que SQLite: MySQL, PostgresQL, Oracle, etc. | ||
| + | * Tenir el servidor Django en un hardware més potent que no pas un Raspberry Pi. | ||
| + | * Establir les passarel·les adients d' | ||
| + | |||
| + | {{tag> #FpInfor #DamMp09 #DawMp07 django iot raspberry fusioncharts }} | ||
| + | |||