Como grabar posiciones GPS a una base de datos Postgresql usando una Raspberry Pi y Python

raspberryGpsPostgresqlPython.jpg

Hoy en día podemos rastrear la posición GPS con varios dispositivos como teléfonos inteligentes, dispositivos portátiles y dispositivos de mano, pero ¿cómo podemos almacenar posiciones GPS masivas de una manera efectiva para el posterior procesamiento, análisis y comparación con la información de otro dispositivo? Hemos creado un procedimiento completo para habilitar un módulo GPS como dispositivo serial en una Raspberry Pi, luego leer la información del GPS y enviarla a una base de datos Postgresql. El tutorial tiene varios pasos desde la instalación del software, scripts para monitorear los datos almacenados.

Video

Conexión modulo GPS

Este es el arreglo de pines para el UBlox Neo 6M:

  • VCC 3.3V (Pin 1) 

  • RX TXD/GPIO 14 (Pin 8) 

  • TX RXD/GPIO 15 (Pin 10) 

  • GND Ground (Pin 6)

A continuación mostramos los pines de la Raspberry:

GPIO-Pinout-Diagram-2.png

Pasos

En una session en la Raspberry:

Conectar al wifi

Activar (Enable) ssh on Preferences/Rasbberry Pi Configuration/Interfaces/SSH 

Revisar el IP interno en el Terminal:

ifconfig

Conectar a través de Putty (en Windows):

Host Name: pi@192.168.1.XX Port:22

Establecer (Enable) UART:

En prompt: sudo raspi-config

En 5. Interfacing Options / P6 Serial:

Would you like a login ... ? = No

Would you like the serial ... ? = Yes

Finish and Reboot

Verificar que el gps mande información al serial:

cat /dev/serial0

Instalar postgres:

sudo apt-get update

sudo apt install postgresql

Ver si la base de datos esta funcionando:

sudo service postgresql status

Crear usuario y tabla por defecto:

sudo -u postgres createuser --superuser pi

Crear usuario:

postgres@raspberrypi:~$ createuser --interactive -P

Enter name of role to add: hatari

Enter password for new role: labs

Enter it again: labs

Shall the new role be a superuser? (y/n) y

Crear base de datos:

createdb -O hatari gpsposition

Revisar bases de datos y crear tabla:

psql gpsposition -U hatari -h localhost

\l

\c gpsposition

CREATE TABLE datecoords (

    id              serial primary key,

    easting         numeric,           

    northing        numeric,          

    elevation       numeric,          

    date            timestamp

);

\d datecoords

Instalar sqlalchemy, psycopg2 and pynmea:

pip3 install sqlalchemy

pip3 install psycopg2

pip3 install pynmea2

Crear un folder para los códigos:

mkdir gpsScripts

cd gpsScripts

Crear un código para leer y almacenar los datos GPS:

nano gpsPosition.py

Correr el código (por 30 segundos):

python3 gpsPosition.py

Crtl+Z

Revisar si los registros están en la base de datos:

psql gpsposition -U hatari -h localhost

SELECT * FROM datecoords;

\q

Correr el código en el "background”:

chmod +x gpsPosition.py 

nohup /home/pi/gpsScripts/gpsPosition.py > output.log &

Revisar si el código esta corriendo:

ps ax | grep gpsPosition.py

También puede revisar la base de datos:

date

psql gpsposition -U hatari -h localhost

select * from datecoords order by date desc limit 10;

Código

Este es el código en Python que lee la información serial, interpreta la sentencia NMEA y la almacena en la base de datos:

#!/usr/bin/env python3
import io, time, os, serial
import pynmea2
from datetime import datetime,date, timedelta
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, Float, Date
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

db_string = "postgres://hatari:labs@localhost:5432/gpsposition"
db = create_engine(db_string)
base = declarative_base()
Session = sessionmaker(db)
session = Session()

class Coords(base):
    __tablename__ = 'datecoords'
    id = Column(Integer,
    primary_key=True)
    easting = Column(Float)
    northing = Column(Float)
    elevation = Column(Float)
    date = Column(Date)

ser = serial.Serial('/dev/serial0', 9600, timeout=5.0)
sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser))

while True:
    try:
        line = sio.readline()
        if line[:6]=="$GPGGA":
            msg = pynmea2.parse(line)
            print(msg.latitude,msg.longitude,msg.altitude)
            gpsTime = datetime.combine(date.today(), msg.timestamp)
            gpsRead = Coords(easting=msg.latitude, northing=msg.longitude, elevation=msg.altitude,date= gpsTime + timedelta(hours=1))
            session.add(gpsRead)
            session.commit()
    except serial.SerialException as e:
        print('Device error: {}'.format(e))
        break
    except pynmea2.ParseError as e:
        print('Parse error: {}'.format(e))
        continue

 

Suscríbete a nuestro boletín electrónico

Suscríbase a nuestro boletín gratuito para recibir noticias, datos interesantes y fechas de nuestros cursos en recursos hídricos.

 

Posted on April 22, 2020 and filed under Hidroinformática.