Tengo un reloj Q50, al que se inserta una tarjeta SIM, que sirve para que los niños puedan comunicarse por teléfono con los padres y los padres puedan llamar al niño además de geolocalizarle. IoT en estado puro.
El caso es que las aplicaciones existentes para geolocalizar son de pago o no funcionan, por ello me propuse crear mi propia aplicación para estos relojes, pero en vez de ser una APP de móvil, sería una aplicación donde se recogería el estado actual.
Estos relojes se configuran inicialmente a través de mensajes SMS. Para configurar el servidor a donde se conectará el reloj, se debe enviar un mensaje SMS al número de teléfono de la SIM del reloj con el siguiente contenido:
pw,<clave>,ip,<host>,<puerto>#
Donde:
- clave: es la clave que tiene el móvil, por defecto es 123456
- host: es la dirección IP o host del servidor
- puerto: es el puerto TCP donde escucha el servidor
Cuando el reloj se conecte al servidor, los comandos que se utilizan se basan en un protocolo que no he encontrado el nombre, pero que es común a muchos relojes y dispositivos GPS. Se puede descargar de mi web, pero originalmente lo encontré aquí.
Como el objetivo es recuperar la posición GPS, sólo me centraré en los comandos Link remains, Location data reporting y Location order.
Link remains
El reloj envía cada 5 minutos un comando al servidor con el formato: [CS*YYYYYYYYYY*LEN*LK,A,B,C]
- CS: El un código de dos caracteres que identifica al fabricante. En mi caso es 3G.
- YYYYYYYYYY : Es el identificador del dispositivo.
- LEN: Es el tamaño del mensaje/comando como 4 dígitos hexadecimales.
- LK: Es el propio comando.
- C: Indica el nivel porcentual de batería del reloj.
El servidor debe responder con otro comando con el formato :
[CS*YYYYYYYYYY*LEN*LK], que es lo mismo que ha enviado el reloj, pero sin los parámetros A, B y C.
Este comando sirve como heartbeat para que tanto el servidor sepa que el reloj está activo como que el reloj sepa que el servidor está activo. Si este último caso no se cumple, entonces el reloj intentará conectarse cada 5 minutos al servidor.
Location order
El reloj no está continuamente enviando la posición GPS porque acabaría con la batería muy rápido, por ello lo que se lanza es un comando desde el servidor al reloj para que informe de la posición GPS varias veces por minuto durante unos minutos. El formato del comando es: [CS*YYYYYYYYYY*LEN*CR]
El reloj informará con el mismo comando para indicar que lo ha recibido y que activará el GPS.
Location data reporting
Una vez activado el anterior comando, el reloj empieza a enviar cada pocos segundos la posición GPS con el siguiente formato: [CS*YYYYYYYYYY*LEN*UD,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P] o [CS*YYYYYYYYYY*LEN*UD2,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P]
Los parámetros que importan para la geolocalización son:
- C: Indica si hay una posición GPS válida (A) o inválida (V).
- D: Latitud.
- E: Indica si es norte (N) o sur (S).
- F: Longitud.
- G: Indica si es este (E) u oeste (W).
Los otros parámetros se pueden consultar en el apéndice del documento que he publicado más arriba sobre el protocolo.
He creado un programa en python 3 que crea un socket servidor y utiliza una BBDD sqlite para recibir los mensajes del protocolo del reloj, además de poder procesar los comandos:
- ACTIVA: Activación de la geolocalización del reloj indicado por parámetro.
- LISTA: Listado de relojes que hay registrados en la BBDD.
- INFO: Información sobre el estado de un reloj pasado por parámetro.
Idealmente se necesita un servidor escuchando por internet, pero funcionaría utilizando ngrok si tienes un servidor local detrás de un router.
El programa, cuando se arranca, crea un socket de escucha y el reloj o un usuario/aplicación se podrá conectar a este. Cuando el reloj se enciende y se conecta a nuestro servicio, el programa muestra lo siguiente:
Donde se puede observar que el reloj envía un mensaje de link remains y otro de cuál es su configuración actual (pero este no está implementado).
Ahora si nos conectamos al servicio, podemos ver la lista de relojes que se han conectado a nuestro sistema simplemente enviando el comando LISTA:
En el reloj en concreto podemos activar la geolocalización, enviando el comando ACTIVA:
El programa mostrará lo siguiente:
Y nosotros ahora podremos consultar la información de ese reloj con el comando INFO:
Donde se muestra el identificador, la fecha de el último mensaje link remains, el porcentaje de la batería, la fecha de la última geolocalización y la latitud y longitud de esta.
Con todo esto se puede realizar un aplicación web que, o bien lea de la base de datos de sqlite si está en el mismo servidor, o bien que se conecte al servicio remotamente para enviar los comandos descritos. La aplicación web podría recuperar la lista de relojes, mostrarla y que el usuario elija el que desee, a continuación se mostraría la última actividad del reloj y en un mapa la última geolocalización (si existiese), dándole la opción de activarla para tener datos más recientes.
Como tarea pendiente queda implementar la seguridad en el acceso al servicio.