scieee AI-readable full text Open interactive document viewer

Desarrollo e implementacion en Django deuna plataforma en la nube para la gestion ymonitorizacion de maquinas de analiticaclinica

Pellicer Collado, Luis

Abstract

El objetivo fundamental de este TFG es desarrollar una plataforma de gestión y monitiorización remota de máquinas de análisis clínico. Dicha plataforma consistirá principalmente en la elaboración de una infraestructura en la nube que de soporte al almacenamiento de los experimentos realizados en dichas máquinas a través de u API que se comunique con las aplicaciones que administran los equipos, así como el desarrollo de una aplicación web que permita un fácil acceso a los datos experimentales generados por estos dispositivos.

Full text

ESCUELA DE INGENIERIA DE TELECOMUNICACION Y ELECTRONIC A • TRABAJO FIN DE GRADO "Desarrollo e implementacion en Django de una plataforma en la nube para la gestion y monitorizacion de maquinas de analitica clinica" Titulacion: Grado en Ingenieria en Tecnologias de la Telecomunicacion Mencion: Telematica Autor: D. Luis Pellicer Collado Tutor: Dr. D. Alfonso Medina Escuela Fecha: Julio 2016 G OAD Of LAS PALMAS DE GRAN CA ARIA ESCUELA DE INGENIERIA DE TELECOMUNICACION Y ELECTRONICA • TRABAJO FIN DE GRADO "Desarrollo e implemcntacion en Django de una plataforma en la nube para la gestion y monitorizacion de maquinas de analitica clinica" HOJA DE FIR,MAS Alumno/a Flo.: O. Lui ' P('l\i c<. 'r Co ll ado Fecha: Julio 2016 T utor/a Fd o. : D r. D. A lf olls ~ 1 ( 'd i nH E. c ll ciH ESCUELA DE INGENIERIA DE TELECOMUNICACION Y ELECTRONIC A • TRABAJO FIN DE GRADO "Desarrollo e implementacion en Django de una plataforma en la nube para la gestion y monitorizacion de maquinas de anaHtica cHnica" HOJA DE EVALUACION Calificacion: --------------------------- Presidente Vocal Secretario / a Fdo.: Fdo.: Fdo.: Fecha: Junio 2016 E      Amazon Resource Name (ARN). @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions 0664 for 'ParClavesAWS.pem' are too open. It is required that your private key files are NOT accessible by others. This private key will be ignored. bad permissions: ignore key: ParClavesAWS.pem Permission denied (publickey). chmod 400 ParClavesAWS.pem ssh -i "ParClavesAWS.pem" [email protected]       SELECT * FROM "autores_autor" INNER JOIN "autor_libro" ON ("autores_autor"."id" = "autores_libro"."autor_id") INNER JOIN "autores_libro_librerias" ON ("autores_libro"."id" = "autores_libro_librerias"."libro_id") INNER JOIN "autores_libreria" ON ("autores_libro_librerias"."libreria_id" = "autores_libreria"."id") WHERE "autores_libreria"."nombre" = "La Cultura" Autor.objects.filter(libros__libreria__nombre = "La Cultura") biosensor www-data /biosensor. virtualenv /biosensor/biosensor_env/ cd /biosensor/biosensor_env/ source bin/activate pip install django django-admin.py startproject biosensor biosensor ├── biosensor │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py        biosensor_api biosensor_app cd biosensor django-admin.py startapp biosensor_api django-admin.py startapp biosensor_app biosensor_api biosensor_app INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'biosensor_app', 'biosensor_api', ] python manage.py runserver python manage.py migrate python manage.py createsuperuser ROOT_URLCONF = 'biosensor.urls' LANGUAGE_CODE = 'es-es' pip install djangorestframework INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'biosensor_app', 'biosensor_api', 'rest_framework', ] REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 10 } urlpatterns = [ url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) ] class Experimento(models.Model): usuario = models.ForeignKey('auth.User', related_name='experimento') nombre = models.CharField(max_length=50) descripcion = models.CharField(blank=True,max_length=300) laser_encendido = models.BooleanField(default=False) bomba_peristaltica_sentido = models.CharField(max_length=10) bomba_peristaltica_velocidad = models.IntegerField() bomba_impulsional_ch1 = models.IntegerField() bomba_impulsional_ch2 = models.IntegerField() selector_viales_ch1 = models.IntegerField() selector_viales_ch2 = models.IntegerField() valvula_inyeccion_ch1 = models.IntegerField() valvula_inyeccion_ch2 = models.IntegerField() timestamp = models.DateTimeField(auto_now_add=True,auto_now=False) class MuestraCurvaAngular(models.Model): usuario = models.ForeignKey('auth.User', related_name='muestra_ca') experimento = models.ForeignKey('Experimento', on_delete=models.CASCADE, related_name='muestra_ca') numero = models.IntegerField() angulo = models.DecimalField(max_digits=8, decimal_places=6) ch1 = models.DecimalField(max_digits=8, decimal_places=6) ch2 = models.DecimalField(max_digits=8, decimal_places=6) class MuestraCineticaQuimica(models.Model): usuario = models.ForeignKey('auth.User', related_name='muestra_ccq') experimento = models.ForeignKey('Experimento', on_delete=models.CASCADE, related_name='muestra_ccq') numero = models.IntegerField() tiempo = models.DecimalField(max_digits=10, decimal_places=6) ch1 = models.DecimalField(max_digits=8, decimal_places=6) ch2 = models.DecimalField(max_digits=8, decimal_places=6) class MuestraCAViewSet(viewsets.ModelViewSet): queryset = MuestraCurvaAngular.objects.all() serializer_class = MuestraCASerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly) class MuestraCCQViewSet(viewsets.ModelViewSet): queryset = MuestraCineticaQuimica.objects.all() serializer_class = MuestraCCQSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly) class ExperimentoViewSet(viewsets.ModelViewSet): queryset = Experimento.objects.all() serializer_class = ExperimentoSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly) class MuestraCASerializer(serializers.ModelSerializer): usuario = serializers.ReadOnlyField(source='usuario.username') class Meta: model = MuestraCurvaAngular fields = ( 'id', 'numero', 'experimento', 'usuario', 'numero', 'angulo', 'ch1', 'ch2',) class MuestraCCQSerializer(serializers.ModelSerializer): usuario = serializers.ReadOnlyField(source='usuario.username') class Meta: model = MuestraCineticaQuimica fields = ( 'id', 'numero', 'experimento', 'usuario', 'numero', 'tiempo', 'ch1', 'ch2',) class ExperimentoSerializer(serializers.ModelSerializer): usuario = serializers.ReadOnlyField(source='usuario.username') class Meta: model = Experimento fields = ( 'id', 'nombre', 'usuario', 'descripcion', 'laser_encendido', 'bomba_peristaltica_sentido', 'bomba_peristaltica_velocidad', 'bomba_impulsional_ch1', 'bomba_impulsional_ch2', 'selector_viales_ch1', 'selector_viales_ch2', 'valvula_inyeccion_ch1', 'valvula_inyeccion_ch2',) bootstrap/ ├── css/ │ ├── bootstrap.css │ ├── bootstrap.css.map │ ├── bootstrap.min.css │ ├── bootstrap.min.css.map │ ├── bootstrap-theme.css │ ├── bootstrap-theme.css.map │ ├── bootstrap-theme.min.css │ └── bootstrap-theme.min.css.map ├── js/ │ ├── bootstrap.js │ └── bootstrap.min.js └── fonts/ ├── glyphicons-halflings-regular.eot ├── glyphicons-halflings-regular.svg ├── glyphicons-halflings-regular.ttf ├── glyphicons-halflings-regular.woff └── glyphicons-halflings-regular.woff2           <script src="{% static 'js/loader.js' %}"></script>  graficas.html drawCurveA() drawCurveCQ() var data = new google.visualization.DataTable(); var chart = new google.visualization.ChartWrapper(...); var control = new google.visualization.ControlWrapper(...); var dashboard = new google.visualization.Dashboard(document.querySelector('#dashboard_div')); data DataTable, data chart control  <div id="chart_div_ccq" style="width=100%; height=100%;"></div> { "numero": 1, "experimento": 1, "angulo": "58.000000", "ch1": "80.965714", "ch2": "83.305714" } #!/bin/bash tail -n +6 Jul25-m01.dat | tr ',' '.' >> TIME.txt USER="biosensor" PASS="passfalsa" EXPERIMENTO="1" MUESTRA=1 while read TIEMPO CH1 CH2 do curl --request POST \ --url 'http://biosensor.io/api/muestras-ccq/' \ --user $USER:$PASS \ --header 'Content-Type: application/json' \ --data '{"numero":'$((MUESTRA++))',"experimento":'$EXPERIMENTO',"tiempo":"'$TIEMPO'","ch1":"'$C H1'","ch2":"'${CH2//$'\r'}'"}' done < TIME.txt rm TIME.txt #!/bin/bash tail -n +6 Jul31-c01.dat | tr ',' '.' >> ANG.txt USER="biosensor" PASS="passfalsa" EXPERIMENTO="1" MUESTRA=1 while read ANGULO CH1 CH2 do curl --request POST \ --url 'http://biosensor.io/api/muestras-ca/' \ --user $USER:$PASS \ --header 'Content-Type: application/json' \ --data '{"numero":'$((MUESTRA++))',"experimento":'$EXPERIMENTO',"angulo":"'$ANGULO'","ch1":"'$C H1'","ch2":"'${CH2//$'\r'}'"}' done < ANG.txt rm ANG.txt 𝐻 = 𝐶𝑡∙74,88 ∙ 𝐻𝑛+ 𝐶𝑡∙96,72 ∙ 𝐻𝑒 - 𝐻 - 𝐻𝑛 - 𝐻𝑒 - 𝐶𝑡 𝐶𝑡 𝐻 = 0,6 ∙ 74,88 ∙300 + 𝐶𝑡∙96,72 ∙ 0 = 13.478,40 € 𝑅 = 0,07 ∙ 𝑃 ∙ 𝐶𝑛 - - 𝐶𝑛 𝑅 = 0,07 ∙13.637,56 ∙ 1 = 957,04 € 𝑉 = 0,006 ∙ 𝑃 ∙ 𝐶𝑣 - 𝑃 - 𝐶𝑣 𝑉 = 0,006 ∙14.690,00 ∙ 1 = 88,14 € def perform_create(self, serializer): serializer.save(usuario=self.request.user) class UserViewSet(viewsets.ReadOnlyModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer @api_view(['GET']) def api_root(request, format=None): return Response({ 'users': reverse('user-list', request=request, format=format) }) from rest_framework import serializers from biosensor_api.models import Experimento, MuestraCurvaAngular,MuestraCineticaQuimica from django.contrib.auth.models import User from rest_framework.reverse import reverse class MuestraCASerializer(serializers.ModelSerializer): usuario = serializers.ReadOnlyField(source='usuario.username') class Meta: model = MuestraCurvaAngular fields = ( 'id', 'numero', 'experimento', 'usuario', 'numero', 'angulo', 'ch1', 'ch2',) class MuestraCCQSerializer(serializers.ModelSerializer): usuario = serializers.ReadOnlyField(source='usuario.username') class Meta: model = MuestraCineticaQuimica fields = ( 'id', 'numero', 'experimento', 'usuario', 'numero', 'tiempo', 'ch1', 'ch2',) class ExperimentoSerializer(serializers.ModelSerializer): usuario = serializers.ReadOnlyField(source='usuario.username') class Meta: model = Experimento fields = ( 'id', 'nombre', 'usuario', 'descripcion', 'laser_encendido', 'bomba_peristaltica_sentido', 'bomba_peristaltica_velocidad', 'bomba_impulsional_ch1', 'bomba_impulsional_ch2', 'selector_viales_ch1', 'selector_viales_ch2', 'valvula_inyeccion_ch1', 'valvula_inyeccion_ch2',) class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('id', 'username') from rest_framework import permissions class IsOwnerOrReadOnly(permissions.BasePermission): def has_object_permission(self, request, view, obj): if request.method in permissions.SAFE_METHODS: return True return obj.usuario == request.user from __future__ import unicode_literals from django.db import models from biosensor_app.models import Experimento, MuestraCurvaAngular, MuestraCineticaQuimica from __future__ import unicode_literals from django.apps import AppConfig class BiosensorApiConfig(AppConfig): name = 'biosensor_api' from django.conf.urls import url from biosensor_app import views urlpatterns = [ url(r'^$', views.home, name='home'), url(r'^experimento/(?P<id_experimento>[0-9]+)/$', views.experimento, name="experimento"), ] # -*- coding: utf-8 -*- from django.shortcuts import render from django.contrib.auth.decorators import login_required from biosensor_app.forms import LoginForm from models import Experimento, MuestraCurvaAngular, MuestraCineticaQuimica @login_required(login_url="login/") def home(request): experimentos = Experimento.objects.filter(usuario=request.user).order_by('- timestamp')[:20] contexto = { "experimentos": experimentos, } if experimentos: seleccionado = experimentos[0] muestras_ca = seleccionado.muestra_ca.all() muestras_ccq = seleccionado.muestra_ccq.all() contexto = {"experimentos": experimentos, "seleccionado": seleccionado, "muestras_ca": muestras_ca, "muestras_ccq": muestras_ccq } return render(request, "dash.html", contexto) @login_required(login_url="login/") def experimento(request, id_experimento): experimentos = Experimento.objects.filter(usuario=request.user).order_by('- timestamp')[:20] seleccionado = experimentos.get(id=id_experimento) muestras_ca = seleccionado.muestra_ca.all() muestras_ccq = seleccionado.muestra_ccq.all() contexto = { "experimentos": experimentos, "seleccionado": seleccionado, "muestras_ca": muestras_ca, "muestras_ccq": muestras_ccq } return render(request, "dash.html", contexto) from __future__ import unicode_literals from django.db import models class Experimento(models.Model): usuario = models.ForeignKey('auth.User', related_name='experimento') nombre = models.CharField(max_length=50) descripcion = models.CharField(blank=True,max_length=300) laser_encendido = models.BooleanField(default=False) bomba_peristaltica_sentido = models.CharField(max_length=10) bomba_peristaltica_velocidad = models.IntegerField() bomba_impulsional_ch1 = models.IntegerField() bomba_impulsional_ch2 = models.IntegerField() selector_viales_ch1 = models.IntegerField() selector_viales_ch2 = models.IntegerField() valvula_inyeccion_ch1 = models.IntegerField() valvula_inyeccion_ch2 = models.IntegerField() timestamp = models.DateTimeField(auto_now_add=True,auto_now=False) def __unicode__(self): return self.nombre class MuestraCurvaAngular(models.Model): usuario = models.ForeignKey('auth.User', related_name='muestra_ca') experimento = models.ForeignKey('Experimento', on_delete=models.CASCADE, related_name='muestra_ca') numero = models.IntegerField() angulo = models.DecimalField(max_digits=8, decimal_places=6) ch1 = models.DecimalField(max_digits=8, decimal_places=6) ch2 = models.DecimalField(max_digits=8, decimal_places=6) def __unicode__(self): return str(self.numero) class MuestraCineticaQuimica(models.Model): usuario = models.ForeignKey('auth.User', related_name='muestra_ccq') experimento = models.ForeignKey('Experimento', on_delete=models.CASCADE, related_name='muestra_ccq') numero = models.IntegerField() tiempo = models.DecimalField(max_digits=10, decimal_places=6) ch1 = models.DecimalField(max_digits=8, decimal_places=6) ch2 = models.DecimalField(max_digits=8, decimal_places=6) def __unicode__(self): return str(self.numero) from django.contrib.auth.forms import AuthenticationForm from django import forms class LoginForm(AuthenticationForm): username = forms.CharField(label="Username", max_length=30, widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'username'})) password = forms.CharField(label="Password", max_length=30, widget=forms.TextInput(attrs={'type': 'password', 'class': 'form-control', 'name': 'password'})) from __future__ import unicode_literals from django.apps import AppConfig class BiosensorAppConfig(AppConfig): name = 'biosensor_app' from django.contrib import admin from biosensor_api.models import Experimento, MuestraCurvaAngular, MuestraCineticaQuimica admin.site.register(Experimento) admin.site.register(MuestraCurvaAngular) admin.site.register(MuestraCineticaQuimica) {% load staticfiles %} <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="author" content="Luis Pellicer Collado"> <title>Biosensor </title> <link rel="icon" type="image/png" href="{% static 'img/biosensor_logo.png' %}"> <link href ="{% static 'css/bootstrap.min.css' %}" rel="stylesheet"> <link href="{% static 'css/dashboard.css' %}" rel="stylesheet"> </head> <body> {% include 'navbar.html' %} {% block content %} {% endblock %} <script src ="{% static 'js/jquery.min.js' %}"> </script> <script src ="{% static 'js/bootstrap.min.js' %}"> </script> <script src ="{% static 'js/ie-emulation-modes-warning.js' %}"> </script> <script src ="{% static 'js/loader.js' %}"> </script> {% block javascript %} {% endblock %} </body> </html> {% extends 'base.html' %} {% block content %} <div class="container"> <div class="row"> <div class="col-md-4 col-md-offset-4" style="top: 90px"> <div class="login-panel panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">Iniciar sesión...</h3> </div> <div class="panel-body"> <form method="post" action="{% url 'django.contrib.auth.views.login' %}"> {% csrf_token %} <p class="bs-component"> <table> <tr> <td>Usuario: </td> <td>{{ form.username }}</td> </tr> <tr> <td>Contraseña: </td> <td>{{ form.password }}</td> </tr> </table> </p> <p class="bs-component"> <center> <input class="btn btn-primary" type="submit" value="login" /> </center> </p> <input type="hidden" name="next" value="{{ next }}" /> </form> {% if form.errors %} <center> <p style="color:red;">Usuario o contraseña incorrectos</p> </center> {% endif %} {% if next %} {% if user.is_authenticated %} <p>Tu usuario no está logueado. Por favor, vuelve a iniciar sesión.</p> {% else %} {% endif %} {% endif %} </div> </div> </div> </div> </div> {% endblock %} {% block javascript %} <script> {% if not user.is_authenticated %} $("ul.nav.navbar-nav.navbar-right").css("display","none"); {% endif %} </script> {% endblock %} <nav class="navbar navbar-inverse navbar-fixed-top"> <div class="container-fluid"> <div class="navbar-header"> {% if request.user.is_authenticated %} <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" datatarget="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> {% endif %} <a class="navbar-brand" href="#">Biosensor.io</a> </div> <div id="navbar" class="navbar-collapse collapse"> <ul class="nav navbar-nav navbar-right"> <li> <a href="#"> <span class="glyphicon glyphicon-user"></span> {% if request.user.is_authenticated %} {{ user }} {% endif %} </a> </li> <li> <a href="/logout"> <span class="glyphicon glyphicon-log-out"></span> Salir </a> </li> {% for experimento in experimentos|slice:":5" %} <li class="nav hidden-sm hidden-md hidden-lg{% if seleccionado.id == experimento.id %} active{% endif %}"> <a href="/experimento/{{experimento.id}}">{{ experimento.nombre }}</a> </li> {% endfor %} </ul> </ul> </div> </div>undefined</nav> <ul class="nav nav-sidebar"> {% for experimento in experimentos %} <li{% if seleccionado.id == experimento.id %} class="active"{% endif %}> <a href="/experimento/{{experimento.id}}">{{ experimento.nombre }}</a> </li> {% endfor %} </ul> <tbody> <tr> <td>Bomba peristáltica</td> <td>Velocidad: <b>{{ seleccionado.bomba_peristaltica_velocidad }}%</b> <br>Sentido de giro: <b>{{ seleccionado.bomba_peristaltica_sentido }}</b> </td> </tr> <td>Bombas impulsionales</td> <td>Canal 1: <b>{{ seleccionado.bomba_impulsional_ch1 }}</b> μL <br> Canal 2: <b>{{ seleccionado.bomba_impulsional_ch2 }}</b> μL </td> </tr> <tr> <td>Selectores de viales</td> <td>Canal 1: Vial <b>{{ seleccionado.selector_viales_ch1 }}</b> <br> Canal 2: Vial <b>{{ seleccionado.selector_viales_ch2 }}</b> </td> </tr> <tr> <td>Válvulas de inyección</td> <td>Canal 1: Posición <b>{{ seleccionado.valvula_inyeccion_ch1 }}</b> <br>Canal 2: Posición <b>{{ seleccionado.valvula_inyeccion_ch2 }}</b> </td> </tr> <tr> <td>Láser</td> <td> <b>{{ seleccionado.laser|yesno:"Encendido,Apagado" }} <b> </td> </tr> </tbody> {% include 'base.html' %} <!DOCTYPE html> <html lang="en"> <body> {% include 'navbar.html' %} <div class="container-fluid"> <div class="row-fluid"> <div class="col-sm-3 col-md-2 sidebar" role="navigation"> <h3 class="sub-header">Experimentos</h3> {% include 'lista-experimentos.html' %} </div> <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main"> <h2 class="sub-header">Resultados</h2> <div class="container-fluid"> {% include 'graficas.html' %} </div> <h2 class="sub-header">Detalles</h2> <p>{{ seleccionado.descripcion }}</p> <div class="table-responsive"> <table class="table table-striped"> <thead> <tr> <th> <h3>Componente</h3> </th> <th> <h3>Configuracion</h3> </th> </tr> </thead> {% include 'configuracion-experimento.html' %} </table> </div> </div> </div> </div> </body> </html> Fichero graficas.html <div class="row"> <div class="col-sm-6"> <div id="chart_div_ca" style="width=100%; height=100%;"></div> <div id="control_div_ca"></div> </div> <div class="col-sm-6"> <div id="chart_div_ccq" style="width=100%; height=100%;"></div> <div id="control_div_ccq"></div> </div> </div> <script type="text/javascript"> function drawCurveA() { var data = new google.visualization.DataTable(); data.addColumn('number', 'X'); data.addColumn('number', 'Canal 1'); data.addColumn('number', 'Canal 2'); data.addRows([ {% for muestra_ca in muestras_ca %} [{{ muestra_ca.angulo }}, {{ muestra_ca.ch1 }}, {{ muestra_ca.ch2 }}], {% endfor %} ]); var chart = new google.visualization.ChartWrapper({ chartType: 'LineChart', containerId: 'chart_div_ca', options: { title: 'Curva Angular', titleTextStyle: { color: 'black', fontName: 'sans-serif', fontSize: '18', bold:'false' }, height: 400, hAxis: { title: 'Ángulo', format: 'decimal', gridlines: {color: '#EEE', count: 10}