Proyecto 1 2017 I

Titulo

ACCESS CONTROL DOOR WITH HTML WEB

Participantes

Laura Díaz
Juan Camilo Hurtado
Carla Sayago

Abstract

This project is focused on the control of access to a door based on a python program, using concepts applied to IoT. In this case a Beagle Bond was used which was programmed to open the door by means of python using a selenoid that was connected to the Beagle Bond which received a 1 or a 0 and activated the selonoide to open the door.

Problema

Este proyecto, partió de la idea de que en el ETM 12 es un lugar muy transcurrido por los estudiantes de ingeniería de Telecomunicaciones con el fin de buscar la ayuda del profesor; ya que allí se mantente cerrada todo el tiempo y ellos se ven obligados a levantarse de su área de trabajo para abrir la puerta, haciendo que sea incomodo y repetitivo. Por esto se planteo el proyecto para que cualquier profesor que este en esta área acceda desde su pagina web y simplemente abra la puerta desde donde este.

Diseño (Arquitectura HW)

El diseño en el cual nos basamos para hacer el proyecto fue el siguiente.

HW.jpg

Desarrollo

Funcionamiento

Partiendo de la pagina web que se debía hacer en html, el usuario que estaba previamente registrado en la base de datos del registro, ingresa a la pagina en la cual se encontrara con el login. Allí ingresa la cédula y la contraseña que hizo en el registro.
Al momento de ingresar, se envía un POST a Bucket y se esta haciendo un GET constantemente desde la Beagle. Este GET que esta haciendo la beagle se compara la hora de la captura de la ultima hora que se hizo en el POST de la hora actual; si la diferencia es de 15 segundos manda un 1, es decir, le manda un 1 a la Beagle haciendo que la puerta se abra por medio del voltaje que le llega al solenoide. Pasado este tiempo, se pone en 0 hasta que nuevamente alguien ingrese.

Es preciso aclarar, que si el usuario se mete en la opción de registro e ingresa los datos que se piden, se valida que el ID exista en la base de datos, es decir, si el ID que registro el usuario ya existe, este no se valida ya que esta guardado en la base de datos. Por consiguiente se debe ir al Login e ingresar el ID y la contraseña para ingresar.

Esquemático del montaje

A continuación se muestra el esquema completo de la parte física del proyecto.

arqui.jpg

La siguiente imagen muestra la parte física del proyecto terminado.

fullsizeoutput_3e4.jpeg

Switch de Relevo

Se uso un switch de relevo, ya que al momento de hacer la conexión del solenoide con la Beagle Bond, esta solo daba un voltaje de 3,3V. Por tal motivo no se podía conectar directamente con la Beagle porque esto haría que se dañara. Con el fin de solucionar esto se opto por este relevo que hacia que al momento de conectar el voltaje de 110V de la toma corriente a este switch, este regulara el voltaje y en vez de que sacara los 110 V daba 5V que era lo que necesitaba el solenoide para que funcionara. A continuación se adjunta la imagen del relevo que se uso.

s-l225.jpg

Posibles aplicaciones

La aplicación que se le puede dar a este dispositivo es el lograr la apertura de cualquier puerta, en diferentes espacios; esto por medio de internet a quienes estén registrados en la base de datos.

Dificultad encontrada

• No fue posible lograr la configuración del puerto ethernet en la Beaglebone, para lograrlo se debe siempre ejecutar un script.
• Para conectar la Beaglebone con bucket, es necesario tener un servidor DNS activo, fue posible conectarse con el 8.8.8.8, pero no fue posible que hiciera la traducción de IP a URL.
• La Beaglebone no soporta el nivel de voltaje que el solenoide, ya que cuando se envía un 1 al gpio que va conectado al solenoide, la beagle se desconecta del computador automáticamente, esto no sucede si se realiza la prueba del 0 y 1 con un multímetro.

Configuración

Configuración en Beaglebone

• Ya se contaba con el OS ubuntu, y python instalado en la beaglebone.
• Se creó en PC un .sh, para realizar la configuración del puerto ethernet de la beagle, y así tener conexión a internet. Este script debe ejecutarse siempre antes de abrir la beaglebone.

sudo ip addr enx1cba8ca2ed6a  192.168.7.1/30 dev enx1cba8ca2ed6a
sudo iptables -A FORDWARD -o wlo1 -i enx1cba8ca2ed6a -s 192.168.0.0/30 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -t nat -F POSTROUTING
sudo iptables -t nat -A POSTROUTING -o wlo1 -j MASQUERADE
sudo iptables-save | sudo tee /etc/iptables.sav

Se comprueba que la beaglebone esté bien conectada haciendo ping al puerto
ping 192.168.7.2.

Si hay conectividad a la beagle, se accede a ella por medio de:
ssh 192.168.7.2 -l ubuntu 
contraseña: temppwd

Se añade el servidor DNS para traducir las IP a URL, en la plantilla /etc/resolv.conf se añade el DNS:
 8.8.8.8 
sudo nano /etc/resolv.conf

Se verifica la conexión a la red con un ping a google.
ping www.google.com

Se crea un archivo .sh en el cual se le asigna el valor de que se enviará a la beagle

GPIO

Para la configuración de los puertos que va a manejar la Beagle, se selecciono el GPIO 65 del P8. Se uso la Beagle Bond que se muestra a continuación:

gpio12.jpg

Luego de haber seleccionado el puerto, se crearon dos archivos ejecutables .sh; el puerto1.sh y el puerto0.sh, los cuales se crearon con el fin de mandar un 1 para abrir la puerta.
La siguiente imagen muestra el ejecutable del puerto1.sh

echo "temppwd" | sudo -S ls /root
sudo chmod 777 /sys/class
sudo chmod 777 /sys/class/gpio
sudo chmod 777 /sys/class/gpio/export
sudo chmod 777 /sys/class/gpio/gpio65
sudo chmod 777 /sys/class/gpio/gpio65/direction
sudo chmod 777 /sys/class/gpio/gpio65/value
echo 65 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio65/direction
echo 1 > /sys/class/gpio/gpio65/value
cat /sys/class/gpio/gpio65/value

Hay que resaltar que antes de la configuración del puerto, se tuvo que dar permisos 777 desde el sudo a cada carpeta que se muestra en la imagen, es decir, para sys, class, gpio, export, direction y value; para así tener todos los permisos y que no existiera ningún inconveniente para acceder al puerto y al mismo tiempo ejecutarse en la Beagle. Como se observa, se hace un "echo 1", aquí es cuando este comando activa la beagle.

Así mismo se realizo la configuración para el puertoo.sh La siguiente imagen muestra este código, la diferencia es que el "echo" es 0.

echo "temppwd" | sudo -S ls /root
sudo chmod 777 /sys/class
sudo chmod 777 /sys/class/gpio
sudo chmod 777 /sys/class/gpio/export
sudo chmod 777 /sys/class/gpio/gpio65
sudo chmod 777 /sys/class/gpio/gpio65/direction
sudo chmod 777 /sys/class/gpio/gpio65/value
echo 65 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio65/direction
echo 0 > /sys/class/gpio/gpio65/value
cat /sys/class/gpio/gpio65/value

GET

Se crea un archivo en la beaglebone llamado get.

8.1 En este programa se realiza el get a bucket para lograr obtener las capturas guardadas, y se le asignan a una variable.
8.2 Esta variable tendrá todos los valores de todas las capturas que se encuentren en bucket, por lo tanto se crea otra variable a la cual se le asigna la posición cero de la primera variable, teniendo así la última captura.
8.3 Se obtiene que la hora de la captura va de la posición 166 a la 170 y de allí se tiene la fecha de la última persona que inició sesión.
8.4 Se busca la hora actual.
8.5 Se sacan las posiciones de ambas horas en las que está la hora, los minutos, los segundos, el día y el mes; y son asignados a diferentes variables.
8.6 Se comparan los segundos, y la diferencia debe ser menor a 15 segundos para conocer que se hiciera la solicitud los últimos 15 segundos; luego se valida que los minutos, horas, días y meses fueran iguales para conocer si fue realizado 15 segundos exactos antes.
8.7 Todo esto dentro de un ciclo infinito, para que el procedimiento se haga cada 15 segundos.

Para ver lo que tiene el get se ejecuta el siguiente comando dentro de la Beagle:

more get.sh

Apareciendo toda la información que tiene este ejecutable. A continuación el código del GET.
import requests
import datetime
import time
import json
from time import sleep
import sys, os

while(1):
    r = requests.get('http://bucket.usantotomas.edu.co:8080/api/sensors/58ff89137be12b532d5053ce/captures?userToken=doj34f5aal6g1vackbau0b1lgd')
    sleep(3)
    n=json.loads(r.text)
    fechaget=str(n)[155:174]
    fecha=datetime.date.today()
    fechaactual=(fecha.strftime("%Y-%m-%d") +' ' + time.strftime("%H:%M:%S")
)
    print fechaactual
    fah=int(fechaactual[11:13])
    fam=int(fechaactual[14:16])
    fas=int(fechaactual[17:19])
    famo=int(fechaactual[5:7])
    fad=int(fechaactual[8:10])
    fgh=int(fechaget[11:13])
    fgm=int(fechaget[14:16])
    fgs=int(fechaget[17:19])
    fgmo=int(fechaget[5:7])
    fgd=int(fechaget[8:10])
    print fechaget

    if (fas-fgs) <= 15:
        if (fam-fgm) == 0:
            if (fah-fgh) == 0:
                if (famo-fgmo) == 0:
                    if (fad-fgd) == 0:
                        print "Abriendoo"
                        os.system('./puerto1.sh')
                else:
                    print "Pasaron mas de 5 segundos"
                    os.system('./puerto0.sh')
            else:
                print "Pasaron mas de 5 segundos"
                os.system('./puerto0.sh')
        else:
            print "Pasaron mas de 5 segundos"
            os.system('./puerto0.sh')
    else:
        print "Pasaron mas de 5 segundos"
        os.system('./puerto0.sh')

Configuración en Bucket

• Para iniciar sesión en bucket se hizo con el correo electrónico de la universidad, y la contraseña que estaba predefinida para el usuario.
• Cuando se inició sesión se creó una solución llamada Acceso, la cual cuenta con un dispositivo llamado Beaglebone, con un sensor denominado API, y allí llegan las capturas.

pantallazo.jpg

Configuración en PC

En una carpeta llamada Flask, se tiene una carpeta con los html del Login y Register, y a su vez se tiene un el programa en el cual se encuentran cuatro funciones y dos clases, las dos primeras funciones definen las bases de datos de MySQL, para REGISTRO y ACCESO, respectivamente; las dos primeras clases validan los datos ingresados en la página del flask de registro y login; en la siguiente función se realiza el registro del usuario en la base de datos, lo cual incluye la verificación, y si el ID(cédula del profesor) ya existe en la base de datos, no será posible registrarse en el sistema; la última función será para el login, se guarda en la base de datos el ID de quien inicia sesión y la hora a la que se hizo, y se realiza el post con estos mismos datos, para hacer el post se utiliza: '{"sensorId":ID del sensor (se obitene en bucket), "captureTypeName": nombre del tipo de dato, "value": ID, "captureDate":fecha actual del OS}'".

Código fuente

import MySQLdb
import datetime
import time
import os
import sys
import requests
from time import sleep
from wtforms import Form, BooleanField, StringField, PasswordField, validators
from flask import Flask, request, render_template, redirect, flash, url_for
#5
app = Flask(__name__)
app.secret_key = 'secret key to use flash'
#8
def RegistroUsuario(IDusuario, Nusuario, PUsuario):
        db = MySQLdb.connect("localhost","root","123456","TEST_DB" )
        cursor = db.cursor()
        sql="""INSERT INTO REGISTRO(ID, NOMBRE, CONTRASENA) VALUES (%s,%s,%s)"""
        cursor.execute(sql,(int(IDusuario), Nusuario, PUsuario))
        db.commit()
#15
def RegistroDB(Dater,IDdb):
    db = MySQLdb.connect("localhost","root","123456","TEST_DB" )
    cursor = db.cursor()
    sql="""INSERT INTO ACCESO(FECHA ,ID) VALUES(%s,%s)"""
    cursor.execute(sql, (Dater , int(IDdb)))
        db.commit()
#22
class RegistrationForm(Form):
    username = StringField('Username', [validators.Length(min=4, max=25)])
    ID = StringField('ID', [validators.Length(min=6, max=35)])
    password = PasswordField('New Password', [
        validators.DataRequired(),
        validators.EqualTo('confirm', message='Passwords must match')
    ])
    confirm = PasswordField('Repeat Password')
    accept_tos = BooleanField('I accept the TOS', [validators.DataRequired()])

class LoginForm(Form):
    ID = StringField('ID',[validators.Length(min=6, max=11)])
    password = PasswordField('Password')
#38
@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegistrationForm(request.form)
    if request.method == 'POST' and form.validate():
        db = MySQLdb.connect("localhost","root","123456","TEST_DB" )
            cursor = db.cursor()
        sql = """SELECT * FROM REGISTRO"""
            cursor.execute(sql)
            data = cursor.fetchall()
            existe = False
            for row in data :
                print(row[0])
                if(str(row[0]) == form.ID.data):
                           print("El ID ya existe en la base de datos, usted ya esta resgitrado")
                        existe = True
            if(existe==False):
                    RegistroUsuario(form.ID.data,form.username.data,form.password.data)
                    print("Gracias por registrarse")
        return redirect(url_for('login'))
    return render_template('register.html', form=form)
#49
@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm(request.form)
    db = MySQLdb.connect("localhost","root","123456","TEST_DB" )
    cursor = db.cursor()
    if request.method == 'POST' and form.validate():
        db = MySQLdb.connect("localhost","root","123456","TEST_DB" )
            cursor = db.cursor()
            sql = """SELECT * FROM REGISTRO"""
        cursor.execute(sql)
            data = cursor.fetchall ()
            existe = False
        exist = False
            for row in data :
                if(str(row[0]) == form.ID.data):
                            existe = True
            if(str(row[1]) == form.password.data):
                exist = True
            if(existe==False):
                    print("El ID es incorrecto")
        else:
            if(exist==False):
                print("La contrasena es incorrecta") #60
            else:
                print("Abriendo")
                fecha = datetime.date.today()
                    fechaactual=(fecha.strftime("%Y-%m-%d") +' ' + time.strftime("%H:%M:%S"))
                print(fechaactual)
                RegistroDB(fecha, form.ID.data)
                headers = { 'Content-Type': 'application/json', }
                            data = '{"sensorId":"58ff89137be12b532d5053ce", "captureTypeName": "open door", "value":' + '"' + form.ID.data + '"'+ ', "captureDate":' + '"'+ fechaactual+'"'+"}'"
                requests.post('https://bucket.usantotomas.edu.co:8443/api/sensors/58ff89137be12b532d5053ce/captures?userToken=doj34f5aal6g1vackbau0b1lgd',headers=headers, data=data)
        return redirect(url_for('register'))
    return render_template('login.html', form=form)
#59
if __name__ == '__main__':
    app.run(debug = True)
sudo apt-get install python3.1
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License