Proyecto 3 2017 I

Titulo

BiciParqueadero

Participantes

Sebastián Candela Herrera
Juan Sebastián Romero Ulloa
Juan Felipe Gozalez perez
Santiago Vega Burgos

Abstract

The project of biciparquadero, focuses on the report of the condition of the parking lots to the users, through a smart device with the access to the internet, it is possible to access an online platform that reports the status of entry and exit of each one of The parking places where the user has a registration with a personal account for the use of the platform.

Problema

El uso de bicicletas como medio de trasporte alternativo se hace mucho más frecuente en especial en las grandes ciudades, los espacios de parqueaderos de bicicletas en estacionamientos privados y públicos está tomando gran importancia, pero ¿cómo los usuarios saben de la disponibilidad de estos parqueaderos, sin la necesidad de desplazarse hasta el lugar? O ¿Cómo los administradores de estos parqueaderos ejercen un control sobre el estado de los puestos de parqueo?

Diseño (Arquitectura HW)

Dise%C3%B1o.PNG

Desarrollo

Funcionamiento

Para el desarrollo del proyecto se estableció el montaje de 4 shitches los cuales irán conectados a una tarjeta beaglebone que reportara el estado de los puestos de parqueo a Bucket, una base de datos en la nube.
Desde un dispositivo inteligente podemos acceder a la página de inicio de inicio de BiciParquedero en donde nos ofrecerá la posibilidad de registrarnos o acceder a la cuenta del usuario, después del registro el usuario podrá acceder a la página en donde se encontrara toda la información de los puestos de parqueo tomad desde Buket, esta información se actualizara en tiempo real y se observa en la página cada vez que el usuario la cargue o refresque.

Caracterización del sensor

Un interruptor o switch es el causante del reporte del estado del puesto de parqueo, este se caracteriza por ser el responsable por el paso de flujo eléctrico, cuando se oprime corta flujo de corriente eléctrica o permite el paso de esta dependiendo de la aplicación y del tipo de sensor, en su mayoría está compuesto de dos terminales de acero inoxidable que se conectado a una fuente de corriente continua, al momento en el que el puesto de parqueo se ocupe el interrultor se activa emitiendo una seña directo a Buket cambiando el estado en la base de datos.

127619i73199CA34D22069C?v=1.0

Esquemático del montaje

IMG_20170609_182406918_HDR.jpg

Posibles aplicaciones

Este proyecto está pensado para la implementación en sitios de parqueo para toda tipo de vehículos en donde se ayude no solo a los administradores de estos lugares, teniendo una mejor organización de su infraestructura, sino a los usuarios como principales beneficiarios, ya que con este proyecto la búsqueda de parqueadero será mucho más cómoda y águila en zonas de alta concentración vehicular.

Dificultad encontrada

Al determinar el uso de un sensor se tiene que tener demasiadas consideraciones, entre ellas el tipo de vehículo para el cual el sensor va a detectar su presencia, las condiciones del terreno son importantes a tener en cuenta el tipo de sensor a elegir debido a su deterioro, por este motivo para este proyecto se propuso un switch dejando abierta la posibilidad para cualquier tipo de sensor.
La conexión de la página en HTML con la base de datos en BUCKET no permite una actualización en tiempo real de la página sin necesidad de estar refrescándola constantemente.

Configuración - paso a paso

Primero se debe realizar la siguiente configuración en la beaglebone

Configuración en Beaglebone

Para configurar la tarjeta inicialmente es necesario descargar un sistema operativo a su tarjeta de memoria SD sobre la cual lo va a correr y almacenar los cambios que se vayan a realizar para ello es recomendable visitar la siguiente pagina que contiene ejemplos de intalacion: http://elinux.org/BeagleBoardUbuntu#BeagleBone_White.2FBlack.2FGreen

Se procedera a identificar la tarjeta:
cape-headers-1000x592.png
(la tarjeta implementada es una tarjeta beaglebone black sin embargo su configuracion es similar)

Para llevar a cabo al configuracion de la tarjeta Beaglebone, es necesario configurar el internet, la tarjeta se va a comportar como un enrutador por lo tanto debemos configurar una direccion Ipv4 en la interfaz, es necesario tener el nombre correcto de la interfaz ya que no en todos los dispositivos es igual, se creó un script ejecutable en bash con las siguientes lineas de codigo:

#!bin/bash

sudo ifconfig enx1cba8ca2ed6a 192.168.7.1/30 broadcast 192.168.7.3
sudo route add default gw 192.168.7.1
ping 192.168.7.1 -c 4
sudo iptables -A FORWARD -o wlp3s0 -i enx1cba8ca2ed6a -s 192.168.0.0/24 -m conn$
sudo iptables -t nat -F POSTROUTING
sudo iptables -t nat -A POSTROUTING -o wlp3s0 -j MASQUERADE
sudo iptables-save | sudo tee /etc/iptables.sav
route del default gw 192.168.7.1

En el cual se añaden rutas estaticas, cabe aclarar que es necesario tener acceso root al sistema operativo implementado en la tarjeta.

En segunda instancia se accedera a la beaglebone implementando el siguiente comando en la pantalla de comandos: sudo screen /dev/ttyUSB0 115200 luego ingresar el usuario y contraseña designados para acceder al sistema operativo de la tarjeta. Luego desde la pantalla de comandos de la tarjeta Beaglebone se debe implementar el siguiente codigo que terminará de implementar la configuracion de internet:

sudo /etc/init.d/networking stop
sudo ip route add default via 192.168.7.1
sudo /etc/init.d/networking restart
ping 8.8.8.8 -c 4

Debe crearse un script igualmente en bash y se debera ejecutar para finalizar la configuracion en internet de la tarjeta.

Configuración en PC

Para poder realizar todas las configuraciones necesarias se necesitan de ciertas librerias

import commands
import time
import MySQLdb
import requests
import sys
import json
from wtforms import Form, BooleanField, StringField, PasswordField, validators
from flask import Flask, request, render_template, redirect, flash, url_for

Es necesario tener instalado MySQL para crear las bases de datos que se van a usar para almacenar todos los datos recopilados.
Para poder realizar este proyecto se hizo necesario el uso de dos tablas, una para guardar los registros de nuevos usuarios en una base de datos, y otra para el control de ingreso y salida de las bicicletas a el parqueadero.

Para poder crear una base de datos en MySQL desde python se ha de usar el siguiente código.

import commands
import MySQLdb
db=MySQLdb.connect("localhost","root","12345","TEST_DB3")
cursor=db.cursor()
cursor.execute("DROP TABLE IF EXIST BICI2")
sql="""CREATE TABLE BICI2 (PUESTO INT PRIMARY KEY,LLEGADA CHAR(20) NOT NULL,ESTADO CHAR(20) NOT NULL )"""
cursor.execute("SELECT * FROM REGISTER")
try:
        cursor.execute(sql)
        db.commit()
except:
        db.rollback()

La parte de conexión define el usuario, su contraseña y la base de datos donde se va a crear la tabla, lo siguiente seria la operación de insertado de valores en esta.

Primero se crea una clase de registro, donde el usuario va a digitar su nombre de usuario, su correo, su contraseña y debe aceptar los términos y servicios.

class RegistrationForm(Form):
    username = StringField('UserName', [validators.Length(min=4, max=25)])
    email = StringField('Email Address', [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()])

Existe una clase de Ingreso donde se autentifica un usuario ya registrado

class LoginForm(Form):
        email = StringField('Email Address')
        password = PasswordField('New Password')

Existen varias funciones en el programa, la primera es la de register, donde se almacena en una base de datos los datos que los nuevos usuarios ingresan, los guarda en la base de datos de MYSQL para posteriomente extraerlos y hacer una comprobacionde datos, si la contraseña corresponde con el email registrado.

def register():
        form = RegistrationForm(request.form)
        if request.method == 'POST' and form.validate():
                db=MySQLdb.connect("localhost","root","12345","TEST_DB3")
                cursor=db.cursor()
                try:
                         cursor.execute("INSERT INTO REGISTER(USERNAME,EMAIL,PASSWORD,TOS)VALUES(%s,%s,%s,'1')",(form.username.data,form.email.data,form.password.data))
                        db.commit()
                        sql = "SELECT * FROM REGISTER"
                        cursor = db.cursor()
                        cursor.execute(sql)
                        db.commit()
                        i=0;
                        a=0;
                        z=0;
                        while ( a < 100  ):
                                results = cursor.fetchone()
                                print(results)
                                i=results.count(form.email.data)
                                a=a+1;
                                if ( i == 1 ):
                                        z=z+1;
                except:
                        db.rollback()

                flash('You are registered')
                if ( z > 1 ):
                        print("repetido")
                        bandera=0;
                        flash('You are registered')
                        return render_template('registererror.html', form=form)

                else:
                        print("no repetido")
                        return redirect(url_for('login'))

        return render_template('register.html', form=form)

también verifica si hay un usuario ya registrado o con información errónea y no lo deja continuar el proceso de registro hasta que todos los datos estén en correcta forma.

Luego esta la función de Login la cual deja ingresar a la pagina del parqueadero a los usuarios que ya estén correctamente registrados de no ser así, estos no pueden ingresar.

@app.route('/login', methods=['GET', 'POST'])
def login():
        form = LoginForm(request.form)
        if request.method == 'POST' and form.validate():
                db=MySQLdb.connect("localhost","root","12345","TEST_DB3")
                cursor=db.cursor()
                try:
                        sql = "SELECT * FROM REGISTER"
                        cursor = db.cursor()
                        cursor.execute(sql)
                        i1=0;
                        a1=0;
                        z1=1;
                        poliutre=1;
                        rows=[]
                        for row in cursor:
                                rows.append(row)
                                print(row)

                        while ( a1 < 100 ):
                                results1 = cursor.fetchone()
                                i1=results1.count(form.email.data)
                                a1=a1+1;
                                if ( i1 == 1 ):
                                        z1=z1+1;
                                        print(results1[1])
                                        print(form.email.data)
                                        if( results1[1] == form.email.data ):
                                                if (results1[2]==form.password.data):
                                                        poliutre=2;
                                                        print(poliutre)
                except:
                        db.rollback()

                print(poliutre)
                data = cursor.fetchall()
                if ( z1 > 1 ):
                        print("EMAIL REGISTRADO")
                        if ( poliutre > 1 ):
                                print("pagina bici")
                                return render_template('db.html',data=data)  #pagina bici
                        else:
                                return render_template('loginerror.html', form=form)

                else:
                        return render_template('error.html', form=form) #email no registrado
                        print("NO REGISTRADO")

        return render_template('login.html', form=form)

Finalmente esta la clase dB la cual es la pagina oficial del parqueadero, esta muestra una tabla con las posiciones su ocupancia y la hora de ingreso al parqueadero.

@app.route('/db', methods=['GET', 'POST'])
def db():

        db=MySQLdb.connect("localhost","root","12345","TEST_DB3")
        cursor= db.cursor()
        cursor.execute("SELECT * FROM BICI2")
        rows= []
        a=requests.get('https://bucket.usantotomas.edu.co:8443/api/sensors/5909ecec7be12b09d0148a66/captures?userToken=?24afosdsv0lgq07a3546huapf8') 
        y = json.loads(a.text)
        bo=str(y)[43:44]
        hora=time.strftime("%H:%M:%S")
        print hora
        print "primer sensor"
        print bo
        a1=requests.get('https://bucket.usantotomas.edu.co:8443/api/sensors/5939bc7c7be12b4cfb811188/captures?userToken=?24afosdsv0lgq07a3546huapf8') 
        y1 = json.loads(a1.text)
        bo1=str(y1)[43:44]
        print "segundo sensor"
        print bo1
        a2=requests.get('https://bucket.usantotomas.edu.co:8443/api/sensors/5939bcbc7be12b4cfb811189/captures?userToken=?24afosdsv0lgq07a3546huapf8') 
        y2 = json.loads(a.text)
        bo2=str(y2)[43:44]
        print "tercer sensor"
        print bo2
        a3=requests.get('https://bucket.usantotomas.edu.co:8443/api/sensors/5939bcc47be12b4cfb81118a/captures?userToken=?24afosdsv0lgq07a3546huapf8') 
        y3 = json.loads(a.text)
        bo3=str(y3)[43:44]
        print "cuarto sensor"
        print bo3
        for row in cursor:
                rows.append(row)
                print(row)
        data=cursor.fetchall()
        cursor.execute("INSERT INTO BICI2 VALUES(1,%s,%s) ON DUPLICATE KEY UPDATE LLEGADA = VALUES(LLEGADA), ESTADO = VALUES(ESTADO);",(hora,bo))
        cursor.execute("INSERT INTO BICI2 VALUES(2,%s,%s) ON DUPLICATE KEY UPDATE LLEGADA = VALUES(LLEGADA), ESTADO = VALUES(ESTADO);",(hora,bo1))
        cursor.execute("INSERT INTO BICI2 VALUES(3,%s,%s) ON DUPLICATE KEY UPDATE LLEGADA = VALUES(LLEGADA), ESTADO = VALUES(ESTADO);",(hora,bo2))
        cursor.execute("INSERT INTO BICI2 VALUES(4,%s,%s) ON DUPLICATE KEY UPDATE LLEGADA = VALUES(LLEGADA), ESTADO = VALUES(ESTADO);",(hora,bo3))
        db.commit()
        return render_template('db.html',data=data)

En el main encontramos

if __name__ == '__main__':
        app.run(debug = True)

Configuración en Bucket

Para realizar la configuración en bucket se tuvo que crear una cuenta en bucket con nuestro correo institucional y con una clave dada por el maestro. Luego de esto se siguieron los siguientes pasos:

El código ejecuta en la beagleBone, que nos permitía enviar los datos a Bucket fue el siguiente, el donde se tenia que importar las librerías:

import Adafruit_BBIO.GPIO as GPIO
import requests
import os
import sys
import commands
from time import sleep
Además se tuvo que introducir que pines se iban a programar, ya que sin estos no sabríamos que Pin de la Beagle era el que debíamos programar:
source
GPIO.setup("P8_14", GPIO.IN)                         #PIN 1
GPIO.setup("P8_18", GPIO.IN)                        #PIN 2
GPIO.setup("P8_12", GPIO.IN)                        #PIN 3
GPIO.setup("P8_16", GPIO.IN)                        #PIN 4
Configuracion de la lógica del programa, 
i=0
while (i == 0):
    if GPIO.input("P8_14"):                  #CONDICIÓN SI EL PIN ESTA ACTIVO
            print("HIGH")
                #headers= { 'Content-Type': 'application/json', }
        #data= {"sensorId":"5909ecec7be12b09d0148a66","captureTypeName":"cms","value":"10","captureDate":"2017-06-02 16:00:30"}

        headers = { 'Content-Type': 'application/json', }
        data = '{"sensorId":"5909ecec7be12b09d0148a66", "captureTypeName": "bool", "value":"1", "captureDate":"2017-02-10 1:00:30"}'   #DATOS A ENVIAR
        requests.post('https://bucket.usantotomas.edu.co:8443/api/sensors/5909ecec7be12b09d0148a66/captures?userToken=24afosdsv0lgq07a3546huapf8',headers=headers, data=data) # IMPRESIÓN EN BUCKET
        #sleep(5)
    else:                     #CONDICION SI EL PIN ESTA INACTIVO        
                headers = { 'Content-Type': 'application/json', }
                data = '{"sensorId":"5909ecec7be12b09d0148a66", "captureTypeName": "bool", "value":"0", "captureDate":"2017-02-10 1:00:30"}'
                requests.post('https://bucket.usantotomas.edu.co:8443/api/sensors/5909ecec7be12b09d0148a66/captures?userToken=24afosdsv0lgq07a3546huapf8',headers=headers, data=data)        
        #sleep(5)
               print("LOW")                     
    if GPIO.input("P8_18"):                #Condición del segundo PIN
        print("HIGH1")
        headers = { 'Content-Type': 'application/json', }
        data = '{"sensorId":5939bc7c7be12b4cfb811188", "captureTypeName": "bool", "value":"1", "captureDate":"2017-02-10 1:00:30"}'    
        requests.post('https://bucket.usantotomas.edu.co:8443/api/sensors/5939bc7c7be12b4cfb811188/captures?userToken=24afosdsv0lgq07a3546huapf8',headers=headers, data=data)
    else:
        print("LOW1")
        headers = { 'Content-Type': 'application/json', }
        data = '{"sensorId":"5939bc7c7be12b4cfb811188", "captureTypeName": "bool", "value":"0", "captureDate":"2017-02-10 1:00:30"}'
        requests.post('https://bucket.usantotomas.edu.co:8443/api/sensors/5939bc7c7be12b4cfb811188/captures?userToken=24afosdsv0lgq07a3546huapf8',headers=headers, data=data)

    if GPIO.input("P8_12"): #Condicion del TERCER PIN

        print("HIGH2")
        headers = { 'Content-Type': 'application/json', }
        data = '{"sensorId":"5939bcbc7be12b4cfb811189", "captureTypeName": "bool", "value":"1", "captureDate":"2017-02-10 1:00:30"}'
        requests.post('https://bucket.usantotomas.edu.co:8443/api/sensors/5909ecec7be12b09d0148a66/captures?userToken=24afosdsv0lgq07a3546huapf8',headers=headers, data=data)
    else:
        print("LOW2")
        headers = { 'Content-Type': 'application/json', }
        data = '{"sensorId":"5939bcbc7be12b4cfb811189", "captureTypeName": "bool", "value":"0", "captureDate":"2017-02-10 1:00:30"}'
        requests.post('https://bucket.usantotomas.edu.co:8443/api/sensors/5909ecec7be12b09d0148a66/captures?userToken=24afosdsv0lgq07a3546huapf8',headers=headers, data=data)

    if GPIO.input("P8_16"):                    #Condicion del CUARTO PIN
        print("HIGH3")
        headers = { 'Content-Type': 'application/json', }
        data = '{"sensorId":"5939bcc47be12b4cfb81118a", "captureTypeName": "bool", "value":"1", "captureDate":"2017-02-10 1:00:30"}'
        requests.post('https://bucket.usantotomas.edu.co:8443/api/sensors/5909ecec7be12b09d0148a66/captures?userToken=24afosdsv0lgq07a3546huapf8',headers=headers, data=data)
    else:
        print("LOW3")
        headers = { 'Content-Type': 'application/json', }
        data = '{"sensorId":"5939bcc47be12b4cfb81118a", "captureTypeName": "bool", "value":"0", "captureDate":"2017-02-10 1:00:30"}'
        requests.post('https://bucket.usantotomas.edu.co:8443/api/sensors/5909ecec7be12b09d0148a66/captures?userToken=24afosdsv0lgq07a3546huapf8',headers=headers, data=data)

Para extraer los datos que se enviaban a la BeagleBone, se tuvo que crear un script en

import requests
import sys
import json
import commands

Para empezar a realizar el get de cada uno de los datos que se encontraba en bucket, se tuvo que crear un sensor ID, por cada entrada que sensor que le llegaba a ala beagle

i=0
while (i ==0):  #Ciclo infinito

#El ID del primer sensor es 5909ecec7be12b09d0148a6
#El token dado por el profesor 24afosdsv0lgq07a3546huapf8
    a=requests.get('https://bucket.usantotomas.edu.co:8443/api/sensors/5909ecec7be12b09d0148a66/captures?userToken=?24afosdsv0lgq07a3546huapf8')   
#p= a.text
    y = json.loads(a.text)  #Con este codigo podiamos retirar lo que habia en la pagina en texto
#print y[0]
    bo=str(y)[43:44]   #Del texto se extrae el valor que envio la Beagle unicamente
    print "primer sensor"
    print bo
    #p.find(1)
    #print(a.text)

    #
    a1=requests.get('https://bucket.usantotomas.edu.co:8443/api/sensors/5939bc7c7be12b4cfb811188/captures?userToken=?24afosdsv0lgq07a3546huapf8')    #Segundo sensor 
#p= a.text
        y1 = json.loads(a1.text)
#print y[0]
        bo1=str(y1)[43:44]
        print "segundo sensor"
        print bo1
        #p.find(1)
        #print(a.text)

    #
    a2=requests.get('https://bucket.usantotomas.edu.co:8443/api/sensors/5939bcbc7be12b4cfb811189/captures?userToken=?24afosdsv0lgq07a3546huapf8') #Tercer sensor 

#p= a.text
        y2 = json.loads(a.text)
#print y[0]
        bo2=str(y2)[43:44]
        print "tercer sensor"
        print bo2
        #p.find(1)
        #print(a.text)

    #
    a3=requests.get('https://bucket.usantotomas.edu.co:8443/api/sensors/5939bcc47be12b4cfb81118a/captures?userToken=?24afosdsv0lgq07a3546huapf8')  #Cuarto sensor 
#p= a.text
        y3 = json.loads(a.text)
#print y[0]
        bo3=str(y3)[43:44]
        print "cuarto sensor"
        print bo3
        #p.find(1)
        #print(a.text)

Código fuente - Scripts en la Beaglebone

sudo apt-get install python3.1
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License