Compare commits

..

21 commits

Author SHA1 Message Date
f
d1e44141f6 usar tabs 2022-03-03 16:09:31 -03:00
f
d2f30d8fe7 si no hay archivos que enviar esperar al próximo intervalo 2022-03-03 15:13:39 -03:00
f
9fef227f5e get_stack solo trae el último archivo de la cola
las funciones hacen una sola cosa
2022-03-03 15:09:52 -03:00
f
b8d45a0adf no crear los directorios si ya existen 2022-03-03 15:09:06 -03:00
f
2feee6f70b mover los archivos fallados a otro directorio
de lo contrario detienen el envío porque el stack siempre devuelve el fallado
2022-03-03 15:08:32 -03:00
f
4411d7ee0c probar la conexión sólo cuando hay un archivo para enviar 2022-03-03 15:06:00 -03:00
f
6105e5948e el id de transaccion es el mismo del archivo 2022-03-03 14:53:01 -03:00
f
623dccb301 solo el estado 200 indica que está todo bien 2022-03-03 14:49:39 -03:00
f
0b77d81c2b detener el loop si se lo pedimos amablemente 2022-03-03 14:47:52 -03:00
f
f148b14b92 no declarar variables que se usan una vez 2022-03-03 14:37:09 -03:00
f
a921e1fd5d usar el archivo de error configurado
además no hace falta borrarlo
2022-03-03 14:35:39 -03:00
f
676b3628bb usar el log configurado 2022-03-03 14:33:24 -03:00
f
46541ea34d fracciones gringas 2022-03-03 14:31:55 -03:00
f
303e35b075 chequear si hay un lock primero 2022-03-03 14:29:58 -03:00
f
8df59231a5 poder configurar el linter de json 2022-03-03 14:28:11 -03:00
f
ee4dc72a0a no hardcodear el directorio de instalación 2022-03-03 14:25:27 -03:00
f
0f0a743123 no expandir directorios vacíos 2022-03-03 14:25:16 -03:00
f
3bd1b4cf48 cambia local 2022-03-03 14:18:32 -03:00
f
253992520b no hace falta salir 2022-03-03 14:17:10 -03:00
f
c29f1dc07e crear el directorio de archivos corruptos 2022-03-03 14:16:39 -03:00
f
dd48575a1b no hardcodear el directorio de instalación 2022-03-03 14:11:32 -03:00
43 changed files with 583 additions and 38546 deletions

View file

@ -1,68 +0,0 @@
#include <OneWire.h>
#include <DallasTemperature.h>
// Pin donde se conecta el bus 1-Wire
const int pinDatosDQ = 2;
// Instancia a las clases OneWire y DallasTemperature
OneWire oneWireObjeto(pinDatosDQ);
DallasTemperature sensorDS18B20(&oneWireObjeto);
// Dispositivo
const int devID = 1;
char devIDstr[5];
int inQuery;
float getData() {
sensorDS18B20.requestTemperatures();
return (sensorDS18B20.getTempCByIndex(0));
}
void setup() {
Serial.begin(9600);
sensorDS18B20.begin();
}
void loop() {
if ( Serial.available() > 0) {
inQuery = Serial.read();
if ( inQuery == devID) {
Serial.write(itoa(devID, devIDstr, 10));
Serial.write(" ");
Serial.write("T");
Serial.write(" ");
char lecturaStr[6]; // Buffer big enough for 7-character float
dtostrf(getData(), 2, 4, lecturaStr); // Leave room for too large numbers!
Serial.write(lecturaStr);
Serial.write(" ");
Serial.write("C");
Serial.write(" ");
Serial.write("99");
}
}
}

View file

@ -1,29 +0,0 @@
int inData;
void setup() {
Serial.begin(14400);
}
void loop() {
if ( Serial.available() > 0) {
inData = Serial.read();
switch (inData) {
case 0x01:
Serial.write("id:temperatura");
Serial.write(" ");
Serial.write("tp:temp");
Serial.write(" ");
Serial.write("vl:29");
Serial.write(" ");
Serial.write("un:C");
Serial.write(" ");
Serial.write("er:99");
Serial.write(" ");
Serial.write('\n');
break;
}
}
}

View file

@ -1 +0,0 @@

View file

@ -1,50 +0,0 @@
// Dispositivo
const int devID = 2;
char devIDstr[5];
int inQuery;
int getData() {
int sensorValue = analogRead(A7);
return (map(sensorValue, 0, 700, 100, 0));
}
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.write("\n");
delay(1000);
if ( Serial.available() > 0) {
inQuery = Serial.read();
if ( inQuery == devID) {
Serial.write(itoa(devID, devIDstr, 10));
Serial.write(" ");
Serial.write("Tur");
Serial.write(" ");
//char lecturaStr[6]; // Buffer big enough for 7-character float
//dtostrf(getData(), 2, 4, lecturaStr); // Leave room for too large numbers!
char lecturaStr[5]; // Buffer big enough for 7-character float
dtostrf(getData(), 3, 2, lecturaStr); // Leave room for too large numbers!
Serial.write(lecturaStr);
Serial.write(" ");
Serial.write("TSS");
Serial.write(" ");
Serial.write("99");
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 KiB

BIN
README.img/image 01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

678
README.md
View file

@ -1,366 +1,342 @@
# Adquisidor
# Sistema Modular para la Captura de Datos y Muestras Ambientales [TOC]
**nombre clave: 'nodemecu'** Protocolo de comunicaciones en serie inspirado en el protocolo **1-Wire** para el control de dispositivos adquisidores.
El Sistema Modular para la Captura de Datos y Muestras Ambientales ('nodemecu') es un desarrollo conjunto de **Herramientas para el Buen Vivir A.C.** (México), la cooperativa de desarrollo digital **SUTTY** (Argentina), **BarraDev infraestructuras y telemetría** (Argentina) y la **Cooperativa de Producción Tecnológica, Gráfica y Audiovisual LTDA** (Argentina) con el apoyo económico de **Witness** (USA), como parte del acompañamiento realizado al Frente de Pueblos en Defensa de la Tierra y el Agua de Puebla, Morelos y Tlaxcala en el marco del proyecto de fortalecimiento **“Coral”**. ## Especificaciones
'**nodemecu**' consiste en un sistema electrónico autónomo sumergible con sensores que en tiempo real escanean las condiciones ambientales y envían esa información hacia un servidor web que almacena y despliega los datos de Temperatura, PH, Conductividad y Turbidez. Ante la detección de algún indicador de posible contaminación en el agua captura una muestra líquida de manera automatizada y sin intervención humana. Se comparte un único bus de trasporte de tramas entre dispositivos:
La intención del proyecto es brindar una herramienta accequible y de bajo costo a las comunidades y organizaciones en defensa del territorio, que necesiten fortalecer su estrategia jurídica con datos y cifras que comprueben la contaminación del medio ambiente. - Un dispositivo controlador arbitra el uso y disposición del medio, ademas de enviar órdenes a los dispositivos adquisidores y recibir respuestas.
- Los dispositivos adquisidores vuelcan tramas al medio como respuesta a peticiones del controlador. Estos dispositivos nunca deben ocupar el bus de forma arbitraria.
El sistema, tanto en su hardware como software, ha sido diseñado de manera modular, de tal manera que permite la fácil implementación de otros sensores y sistemas de captura o comportamiento a partir de los diseños originales, todos los cuales serán publicados bajo licencias de software y hardware libre y puestos a disposición de las comunidades que lo necesiten. ## Enlace de datos
Durante los últimos 6 meses se ha trabajado intensamente en el desarrollo del software que permite el registro, transmisión, almacenamiento y despliegue de datos, el control de los sensores, el diseño de placa de montaje de los componentes y en los exteriores del sistema. Actualmente estamos iniciando la etapa de prototipado, que consiste en la construcción real del sistema, para en caso de cumplir con las espectativas de diseño, inicie su replicación y masificación. ### Interfaz física
Para culminar esta etapa final antes de la implementación real en campo, hemos comprometido el apoyo del **Instituto de Desarrollo e Innovación Tecnológica de la Universidad Iberoamericana de Puebla** (IDIT - IBERO), quienes nos brindarán acompañamiento y asesoría. El transporte de datos se realiza por un medio compartido, un único bus conectado a las interfaces Tx y Rx de todos los dispisitivos.
## Instalación
### Requisitos
- Raspberry (cualquier versión).
- Sistema operativo 'Raspberry Pi OS Lite.
- Instalador 'Raspberry Pi Imager'
- Una tarjeta MicroSD Clase 10 de al menos 4GB.
### Instalación del sistema operativo ![](/home/sergio/BarraDEV/Proyectos/Plataforma de monitoreo/Adquisidor/README.img/image 01.png)
**Paso 1**
Descargar la ultima versión de 'Raspberry Pi OS Lite':
https://www.raspberrypi.com/software/operating-systems/ ### Protocolo de solicutd y respuesta (PESR)
**Paso 2** La comunicación entre dispositivos es por envío y recepción de dos tipos de tramas bajo un protocolo común:
Descargar el instalador 'Raspberry Pi Imager': - Solicitud (Controlador).
- Respuesta (Adquisidor).
https://downloads.raspberrypi.org/imager/imager_latest.exe Las tramas se componen de 18 bytes:
**Paso 3** - Prefijo de sincronización (2 bytes).
- Cabecera (5 bytes).
- Payload (10 bytes).
- Fin de trama (1 byte).
Insertar la tarjeta MicroSD en la computadora. **Nota:** Si bien se contabilizan los bytes de sincronización, estos no son parte de la trama en si mismos.
**Paso 4** Las tramas poseen campos comunes para todas las operaciones y dispositivos: prefijo, cabecera y fin de trama. Quedando el campo payload para la estructura de datos y los datos.
Abrir 'Raspberry Pi Imager': #### Estructura de trama genérica
- **CHOOSE OS**: Seleccionar la imagen 'Raspberry Pi OS Lite' descargada el paso 1. | Campo | Tipo de dato | Valor | Dato | Descripción |
- **CHOOSE STORAGE**: Seleccionar la tarjeta MicroSD. | ----- | ------------ | ----- | --------- | ------------------------------------------------------------ |
- **WRITE**: Comienza a grabar el sistema operativo en la tarjeta. | | | | | **PREFIJO** |
| 0 | BYTE | 0xAA | Prefijo 1 | Inicio de sincronización. |
| 1 | BYTE | 0xCC | Prefijo 2 | Fin de sincronización. |
| | | | | **CABECERA** |
| 0 | BYTE | | DevID | Id del dispositivo **al que** consulta/responde.<br>Para el controlador siempre es 0x00 (ver **IDs de dispositivos**). |
| 1 | BYTE | | SrcID | Id del dispositivo **que** consulta/responde.<br/>Para el controlador siempre es 0x00 (ver **IDs de dispositivos**). |
| 2 | BYTE | | ReqID | Número de pedido. |
| 3 | BYTE | | Cmd | Número de comando (ver **Tabla de comandos**). |
| 4 | BYTE | | CodErr | Código de error (ver **Error codes**) |
| | | | | **PAYLOAD** |
| 5 | | | Gap[0] | Datos que se tranportan. En caso de campos vacios<br>o de valor *null* se completa con 0x00. |
| ... | | | Gap[..] | |
| 14 | | | Gap[9] | Datos que se tranportan. En caso de campos vacios<br/>o de valor *null* se completa con 0x00. |
| | | | | **FIN TRAMA** |
| 15 | BYTE | | Cks | Campo de verificación de trama por suma simple. |
**Paso 5**
Una vez que finaliza la grabación extraer la tarjeta MicroSD y colocarla en la Raspberry.
### Instalación de 'nodemecu' ## Ciclo de control y respuesta
**Paso 1** El sistema se compone por un dispositivo *controlador* cuya ID de dispositivo siempre es `0x00`, los dispositivos *adquisidores* deben tener una ID de dispositivo única e irrepetible.
Abra una terminal e instale 'git'. El controlador recorre de forma cíclica los adquisidores solicitando los datos asociados a los sensores.
### Asignación de ID
Todo el sistema se completa como un array de adquisidores, donde el puerto de conexión determina la ID de dispositivo.
| Salida digital Controlador | Adquisidor | ID |
| -------------------------- | ---------- | ---- |
| DO1 | 1 | 0x01 |
| DO2 | 2 | 0x02 |
| DO3 | 3 | 0x03 |
| DO4 | 4 | 0x04 |
El adquisidor recibe (según la salida digital del controlador) una ID que siempre es la misma para el mismo puerto, al intercambiar los adquisidores de puerto se asume un cambio de ID para el adquisidor.
### Adquisidores
Los adquisidores pueden manejar varios sensores, en muchos casos un mismo integrado puede censar múltiples variables, como por ejemplo presión y temperatura. Por lo tanto cada adquisidor al ser consultado va a responder tantas veces como sensores tenga.
``` ```
$ sudo apt update && apt install git // Dispositivo adquisidor
int STOTAL=4; // Total de sensores
float SEN01; //Información devuelta por el sensor
float SEN02;
float SEN03;
float SEN04;
byte STYPE01; // Tipo, ej. Temperatura
byte STYPE02;
byte STYPE03;
byte STYPE04;
``` ```
**Paso 2** Ver tabla de **tipos de sensores**.
Clonar el repositorio 'nodemecu'. ### Solicitud de sensores
1. El controlador envía una **trama de solicitud** con el comando **CON** (ver **tabla de comandos**) y una **ID de dispositivo**.
2. El adquisidor recibe la petición y responde con un comando **ACK**.
3. El controlador responde el **ACK** con un comando **GET**.
4. El adquisidor envía una trama por cada sensor según la **trama de respuesta** con la siguiente información:
- Comando de respuesta **ACK**.
- Total de sensores.
- Valor recogido por el sensor.
- Tipo de sensor.
- Código de error **0x00**.
5. El adquisidor responde con un comando **FIN** con el último envío de datos, entonces el controlador continua con el siguiente adquisidor.
### Manejo de errores
- Cuando el adquisidor no esta listo para recoger datos de los sensores responde con un **FIN** y un código de error **0x01**. El controlador continúa con el siguiente adquisidor.
- Cuando el adquisidor detecta fallos en un sensor o no recibe datos de éste, se responde con un **ACK** , un código de error **0x02** y un valor **ZERO** de recogida para dicho sensor.
### Tiempos de espera
- El controlador espera un máximo de 500 milisegundos antes de pasar al siguiente adquisidor.
## Máquina de estados
### Adquisidor
El adquisidor funciona de forma independiente del controlador en relación a los métodos de medición y las operaciones automatizadas asociadas a dicho proceso de medición: El controlador solicita datos, el adquisidor los provee.
Es importante tener en cuenta que el rol del controlador **no** es realizar mediciones, ni automatizar procesos.
Por lo tanto, el adquisidor se cimienta bajo la estructura lógica de una máquina de estados transductora. Este modelo permite definir un esquema de estados de forma genérica:
- Recepción de datos.
- Procesamiento de datos.
- Ejecución de tareas
- Salida de datos
La máquina de estados deja la libre incorporación de funciones y sub programas que son ejecutados en el estado deseado según la información recibida bajo el protocolo de comunicación PSR.
## Tramas
### Trama de solicitud
Es la trama enviada por el controlador, se establece el comando y se espera respuesta.
| Campo | Tipo de dato | Valor | Dato | Descripción |
| ----- | ------------ | ----- | ------- | ------------------------------------------------------------ |
| 0 | BYTE | | DstID | Id del dispositivo **al que** consulta/responde.<br>Para el controlador siempre es 0x00 (ver **IDs de dispositivos**). |
| 1 | BYTE | 0x00 | SrcID | Id del dispositivo **que** consulta/responde.<br/>Para el controlador siempre es 0x00 (ver **IDs de dispositivos**). |
| 2 | BYTE | | ReqID | Número de pedido. |
| 3 | BYTE | | Cmd | Número de comando (ver **Tabla de comandos**). |
| 4 | BYTE | | CodErr | Código de error (ver **Error codes**) |
| 5 | | | Gap[0] | Datos que se tranportan. En caso de campos vacios<br>o de valor *null* se completa con 0x00. |
| ... | | | Gap[..] | |
| 14 | | | Gap[9] | Datos que se tranportan. En caso de campos vacios<br/>o de valor *null* se completa con 0x00. |
| 15 | BYTE | | Cks | Campo de verificación de trama por suma simple. |
### Trama de respuesta
| Campo | Tipo de dato | Valor | Dato | Descripción |
| ----- | ------------ | ----- | ------- | ------------------------------------------------------------ |
| 0 | BYTE | | DevID | Id del dispositivo **al que** consulta/responde.<br>Para el controlador siempre es 0x00 (ver **IDs de dispositivos**). |
| 1 | BYTE | 0x00 | SrcID | Id del dispositivo **que** consulta/responde.<br/>Para el controlador siempre es 0x00 (ver **IDs de dispositivos**). |
| 2 | BYTE | | TranID | Identificador de transacción. |
| 3 | BYTE | | Cmd | Número de comando (ver **Tabla de comandos**). |
| 4 | BYTE | | CodErr | Código de error (ver **Error codes**). |
| 5 | BYTE | | Stotal | Cantidad de sensores. |
| 6 | BYTE | | Snum | Numero de sensor con el que contesta. |
| 7 | BYTE | | Stype | Tipo de sensor. |
| 8~11 | BYTE | | Value | Valor recogido por el sensor (punto flotante). |
| ... | | | Gap[..] | |
| 14 | | | Gap[3] | Datos que se tranportan. En caso de campos vacios<br/>o de valor *null* se completa con 0x00. |
| 15 | BYTE | | Cks | Campo de verificación de trama por suma simple. |
## Tablas
### Tabla de comandos
| Comando | Decimal | Hexadecimal | Descripción |
| ------- | ------- | ----------- | ------------------------------------------------------------ |
| CON | 170 | 0xAA | Evalúa si hay un dispositivo conectado. |
| ACK | 171 | 0xAB | Como respuesta a un `CON`, se evalúa disponibilidad del dispositivo. |
| GET | 172 | 0xAC | Solicitud de entrega de datos al adquisidor. |
| POST | 173 | 0xAD | Envío de datos al adquisidor. |
| RESET | 174 | 0xAE | Reinicio de adquisidor. |
| FIN | 175 | 0xAF | Fin de entrega de datos. |
| | | | **RESERVADOS** |
| | | | **COMANDOS NO DEFINIDOS** |
| | 190~200 | | Comandos personalizados. |
### Códigos de error
| Código | Decimal | Hexadecimal | Descripción |
| ------- | ------- | ----------- | ------------------------------------------------ |
| Success | 0 | 0x00 | Nada que informar. |
| Espera | 1 | 0x01 | El dispositivo no esta listo para enviar datos. |
| Fallo | 2 | 0x02 | No se puede acceder a la información del sensor. |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
#### Tabla de sensores
| Código | Sensor | |
| ------ | -------------------------- | ---- |
| 0x01 | Temperatura en cetígrados. | |
| 0x02 | Humedad relativa. | |
| 0x03 | Presión. | |
| | | |
## Esquemas de conexión
### Controlador
Raspberry PI 4 GPIO pin out.
| Pin | Tipo | Descripción |
| ---- | ------- | ------------------------------- |
| 4 | Vin 5V | Alimentación. |
| 6 | GND | Retorno alimentación. |
| 8 | UART TX | Bus de datos compartido con RX. |
| 10 | UART RX | Bus de datos compartido con TX. |
| 12 | GPIO18 | Asignador de ID 0x01 |
| 16 | GPIO23 | Asignador de ID 0x02 |
| 18 | GPIO24 | Asignador de ID 0x03 |
| 22 | GPIO25 | Asignador de ID 0x04 |
![](/home/sergio/BarraDEV/Proyectos/Controlador adquisidor/README.img/esquema-pines-gpio.png)
### Adquisidor
Arduino nano v2.3
| Pin | Tipo | Descripción |
| ---- | ------- | ------------------------------- |
| 1 | UART TX | Bus de datos compartido con RX. |
| 2 | UART RX | Bus de datos compartido con TX. |
| 5 | D2 | Receptor ID |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
## API
### JSON
``` ```
$ git clone https://gitea.nulo.in/Nodemecu/nodemecu.git {
"transaction_uuid" : "",
"controller_id": "id raspberry";
"timestamp" : "terminadas todas las lecturas",
"error_code" : "value",
"coordinates" : {
"lat": 1,
"lng": 1
},
"battery_status" : "value",
"sample": "si hay muestra para retirar",
"storage": "uso del almacenamiento",
"arduinos": [
{
"id": 1,
"sensores": [
{
"timestamp": 20211017,
"type": "temperatura",
"value": 30,
"unit": "C",
"error": 200
},
{
"timestamp": 20211017,
"type": "humedad",
"value": 100,
"unit": "%"
},
{
"timestamp": 20211017,
"type": "presion",
"value": 70,
"unit": "Hpa"
}
]
},
{
"id": 2,
"sensores": []
}
]
}
``` ```
Resultado. ### URL
``` ```
Clonando en 'nodemecu'... https://ectomobile.sutty.nl/transactions
remote: Enumerating objects: 179, done.
remote: Counting objects: 100% (179/179), done.
remote: Compressing objects: 100% (176/176), done.
remote: Total 179 (delta 97), reused 0 (delta 0), pack-reused 0
Recibiendo objetos: 100% (179/179), 394.81 KiB | 933.00 KiB/s, listo.
Resolviendo deltas: 100% (97/97), listo.
```
**Paso 3**
Ingresar al directorio 'nodemecu'.
```
$ cd nodemecu
```
Lanzar script de instalación.
```
$ sudo ./instalador
```
Resultado.
```
...
Created symlink /etc/systemd/system/multi-user.target.wants/nodemecu.service → /lib/systemd/system/nodemecu.service.
4. Configurar
- Ejecute 'sudo nodemecu configurar' para comenzar.
-Ejecute 'sudo nodemecu modo sensores' para obtener datos desde sensores.
- Ejecute 'sudo nodemecu captura iniciar' para comenzar a tomar datos de sensores o datos de prueba.
- Ejecute 'sudo systemctl start nodemecu.service' para iniciar el envío de datos.
```
### Configurar dispositivo
El 'CLI' es la interfaz de comandos para administrar 'nodemecu', debemos utilizarla para los primeros pasos luego de la instalación del programa:
- Determinar el nombre del dispositivo.
- Determinar la URL del servidor donde se enviarán los datos.
- Intervalo de toma de mediciones.
**Paso 1: Configuración**
Ejecute el asistente de configuración y complete las preguntas.
```
$ sudo nodemecu configurar
```
Resultado.
```
Complete los cambios a continuación:
Nombre del dispositivo.
nombre: calle falsa 123
nombre: calle_falsa_123
Servidor de entrega de datos.
servidor (ej. https://url.del/servidor): https://servidor.de.envio
Servidor https://servidor.de.envio
Intervalo de toma de muestras, entre 1 y 60 minutos.
intervalo: 5
Intervalo seteado en 5
Creando juego de llaves
Generating public/private ecdsa key pair.
Your identification has been saved in /opt/nodemecu/llaves/calle_falsa_123.pem.
Your public key has been saved in /opt/nodemecu/llaves/calle_falsa_123.pem.pub.
The key fingerprint is:
SHA256:7ZSKlfxybO/ssa63EeGVRDzMjcNKCOI4Kfx++V7o9vg root@raspberrypi
The key's randomart image is:
+---[ECDSA 256]---+
| . .. . *oo |
| . + . . ..O..|
| o + . ...oo |
| o . . o o.o |
| . S + o |
| . + B . |
| . + + B o |
| . o.* o.+ |
| o=oE*O. |
+----[SHA256]-----+
El modo de operación por defecto es 'test' y se envían datos simulados, cambie a 'sensores' con el comando 'sudo nodemecu modo sensores'
```
**Paso 2: Modo de operación**
Determine si los datos a registrar son simulados u obtenidos de sensores físicos, 'nodemecu' por defecto esta configurado para trabajar con datos simulados, si lo prefiere así entonces salte este paso, de lo contrario cambie el modo de operación.
Cambio de modo de operación.
```
$ sudo nodemecu modo sensores
```
**Paso 3: Captura o toma de datos**
Al ser instalado 'nodemecu' no realiza ningún tipo de captura de datos, para ello debe activar la captura.
Activar captura.
```
$ sudo nodemecu captura iniciar
```
Resultado.
```
Iniciando la captura de datos en modo 'sensores'
Desea continuar? Presione 'enter' para continuar o 'ctrl-c' para cancelar...
Se tomarán datos cada 5 minutos.
```
**Paso 4: Envío de datos**
Nodemecu utiliza el administrador de servicios 'systemd' para gestionar el programa que se encarga de enviar al servidor los datos registrados, se debe activar e iniciar el servicio para comience el envío de datos.
Activar servicio con el arranque del sistema, si no realiza este paso deberá hacer el inicio manual cada vez que se arranque el sistema.
```
$ sudo systemctl enable nodemecu.service
```
Resultado.
```
Created symlink /etc/systemd/system/multi-user.target.wants/nodemecu.service → /lib/systemd/system/nodemecu.service.
```
Iniciar el envío de datos.
```
$ sudo systemctl start nodemecu.service
```
Ver estado del servicio.
```
$ sudo systemctl status nodemecu.service
```
Resultado (se sale con 'q').
```
● nodemecu.service - Procesador de pila y transmisor de datos Nodemecu.
Loaded: loaded (/lib/systemd/system/nodemecu.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2022-03-11 16:25:57 -03; 39s ago
Main PID: 18283 (registrador)
Tasks: 2 (limit: 2181)
CGroup: /system.slice/nodemecu.service
├─18283 /bin/bash /opt/nodemecu/registrador
└─18567 ping -c 1 fsf.org
...
```
## Comandos nodemecu
Lista de comandos de ' nodemecu CLI'
#### Establecer o cambiar nombre del dispositivo.
Establece o cambia el nombre definido para el dispositivo, se recomienda usar solo caracteres alfanuméricos y sin espacios.
```
$ sudo nodemecu nombre nombre_del_dispositivo
```
#### Servidor de entrega de datos
Establece o modifica el servidor de entrega de datos.
```
$ sudo nodemecu servidor https://url_o_ip_del.servidor
```
#### Modo de operación
Cambia al modo de operación con respecto a la captura de datos:
- 'test' genera y registra datos simulados.
- 'sensores' toma datos realoes de los sensores.
Para generar datos simulados.
```
$ sudo nodemecu modo test
```
Para tomar datos de sensores.
```
$ sudo nodemecu modo sensores
```
#### Toma de datos
Permite detener la toma o captura de datos ya sean simulados o de sensores.
Para iniciar la captura.
```
$ sudo nodemecu captura iniciar
```
Para detener la captura
```
$ sudo nodemecu captura detener
```
#### Intervalo de toma de datos
Cada cuanto tiempo se toman datos, sean simulados o de sensores. Indique en minutos (1~60).
Configurar intervalo, en el ejemplo se configura para que tome datos cada 1 minuto.
```
$ sudo nodemecu intervalo 1
```
#### Llaves
Cada registro va firmado para validar la autenticidad y que no haya sido modificado el envío al servidor, para ello se utilizan llaves digitales, la creación de estas llaves esta automatizada cuando se ejecuta el comando `$ sudo nodemecu configurar `. Puede generar en cualquier momento una nueva llave, se recomienda esta acción si modifica el nombre del dispositivo.
Generación de llave.
```
$ sudo nodemecu cllave
```
#### Envío de datos
El envío de datos es una operación separada de la captura, el segundo toma datos y los guarda en el dispositivo, el primero envía esos datos a un servidor para procesar y mostrar la información.
Iniciar el envío de datos.
```
$ sudo systemctl start nodemecu.service
```
Detener el envío de datos.
```
$ sudo systemctl stop nodemecu.service
```
Activar el envío de datos con el arranque del sistema.
```
$ sudo systemctl enable nodemecu.service
```
Desactivar el envío de datos con el arranque del sistema.
```
$ sudo systemctl disable nodemecu.service
```
Ver el estado del servicio de envío de datos.
```
$ sudo systemctl status nodemecu.service
``` ```
@ -369,55 +345,3 @@ $ sudo systemctl status nodemecu.service

74
bin/nodemecu Normal file
View file

@ -0,0 +1,74 @@
#!/bin/bash
if [ $UID -ne 0 ]; then
echo "Ejecute 'sudo $0'"
exit
fi
# LECTURA FICHERO DE CONFIGURACION
config=/etc/nodemecu.conf
source $config
[ -z $1 ] && exit
com=$1
case $com in
start)
if [ -z $interval ]; then
echo "Asegurese de haber establecido 'intervalo' de regitro y envio de datos."
exit 1
fi
if [ -z $name ]; then
echo "Asegurese de haber establecido el 'nombre' de dispositivo."
exit 1
fi
echo "El modo de operación es '$mode', puede cambiar el modo con el comando:"
echo "'nomecu modo MODE' donde 'MODE' puede ser 'test' para generar y enviar datos simulados o 'sensores' para enviar datos tomados de los sensores."
echo ""
read -p "Desea continuar? Presione 'enter' para continuar o 'ctrl-c' para cancelar..."
echo "*/$interval * * * * /opt/nodemecu/data_gen.sh" > /tmp/nodemecu.crontab
crontab -u root /tmp/nodemecu.crontab
echo ""
echo "Se enviarán datos cada $interval minutos."
echo ""
exit
;;
stop)
crontab -u root -r
echo "Se detuvo la toma y envio de datos."
echo ""
;;
intervalo)
if [[ $1 == intervalo && $2 -ge 1 && $2 -le 60 ]]; then
sed -i 's/interval=[0-9]*/interval='$2'/' $config
echo "intervalo seteado en $2"
exit
else
echo "Establezca un valor entre 1 y 60."
exit 1
fi
;;
nombre)
parametros=$*
nombre=$(echo $parametros | sed 's/nombre //g' | sed 's/ /_/g')
if [[ "$nombre" =~ ^[a-zA-Z0-9_]+$ ]];then
sed -i 's/name=[a-z A-Z 0-9]*/name='"$nombre"'/' $config
else
echo "El nombre solo puede contener carateres alfanumericos."
fi
;;
monitor)
$install_dir/monitor.sh
;;
*)
exit
;;
esac

View file

@ -6,7 +6,7 @@ import sys
ser = serial.Serial( ser = serial.Serial(
port='/dev/serial0', #Replace ttyS0 with ttyAM0 for Pi1,Pi2,Pi0 port='/dev/serial0', #Replace ttyS0 with ttyAM0 for Pi1,Pi2,Pi0
baudrate = 9600, baudrate = 14400,
parity=serial.PARITY_NONE, parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE, stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS, bytesize=serial.EIGHTBITS,
@ -22,7 +22,7 @@ ser.flush()
while True: while True:
if ser.in_waiting > 0: if ser.in_waiting > 0:
line = ser.readline().decode('utf-8', errors='replace').rstrip() line = ser.readline().decode('utf-8', errors='replace').rstrip()
#time.sleep(0.1) time.sleep(0.5)
print(line) print(line)
ser.flush() ser.flush()
break break

53
data_gen.sh Executable file
View file

@ -0,0 +1,53 @@
#!/bin/bash
source /etc/nodemecu.conf
case $mode in
test)
lecturas="id:dummy_plug-01 ts:$(date +%s) tp:temp vl:$(( $RANDOM % 20 + 15 )) un:C er:99 AD_SENSOR ts:$(date +%s) tp:hum vl:$(( $RANDOM % 50 + 35 )) un:percent er:99 AD_ARDUINO id:dummy_plug-02 ts:$(date +%s) tp:temp vl:$(( $RANDOM % 20 + 15 )) un:C er:99 AD_SENSOR ts:$(date +%s) tp:hum vl:$(( $RANDOM % 50 + 35 )) un:percent er:99 AD_ARDUINO id:dummy_plug-03 ts:$(date +%s) tp:temp vl:$(( $RANDOM % 20 + 15 )) un:C er:99 AD_SENSOR ts:$(date +%s) tp:hum vl:$(( $RANDOM % 50 + 35 )) un:percent er:99 AD_ARDUINO id:dummy_plug-04 ts:$(date +%s) tp:temp vl:$(( $RANDOM % 20 + 15 )) un:C er:99 AD_SENSOR ts:$(date +%s) tp:hum vl:$(( $RANDOM % 50 + 35 )) un:percent er:99 END"
;;
esac
for i in $lecturas;do
case $i in
id*)
sensores="$sensores { $(echo \"id\":\"$(echo $i | cut -d ":" -f 2)\", \"sensores\": [ )"
;;
ts*)
sensores="$sensores { $(echo \"timestamp\": $(echo $i | cut -d ":" -f 2),)"
;;
tp*)
sensores="$sensores $(echo \"type\": \"$(echo $i | cut -d ":" -f 2)\",)"
;;
vl*)
sensores="$sensores $(echo \"value\": $(echo $i | cut -d ":" -f 2),)"
;;
un*)
sensores="$sensores $(echo \"unit\": \"$(echo $i | cut -d ":" -f 2)\",)"
;;
er*)
sensores="$sensores $(echo \"error\": $(echo $i | cut -d ":" -f 2) })"
;;
AD_SENSOR)
sensores="$sensores,"
;;
AD_ARDUINO)
sensores="$sensores]},"
;;
END)
sensores="$sensores]}"
;;
esac
done
counter=$(cat $install_dir/counter)
uuid="$(uuidgen)"
timestamp="$(date +%s)"
json="{\"transaction_uuid\":\"$uuid\",\"controller_id\":\"$name\",\"timestamp\":\"$timestamp\",\"error_code\":\"10\",\"coordinates\":{\"lat\":1,\"lng\":1},\"battery_status\":\"98\",\"sample\":\"0\",\"storage\":\"uso del almacenamiento\",\"arduinos\":[$sensores]}"
touch $install_dir/lock
file=$(date +%Y%m%d%H%M%S)-$uuid
for ((i=1 ; i <=3 ; i++));do
if echo $json | $json_linter >/dev/null 2>&1 ;then
echo $json > $install_dir/stack/$file && rm $install_dir/lock && echo $((counter+1)) > $install_dir/counter && break
else
echo "$(date +%Y-%m-%d-%H:%M:%S) - No se pudo obtener información." >> $log && sleep 1
fi
done

View file

@ -1,37 +0,0 @@
## Impresión PCB
Fichero `impresion_v1.pdf` se utiliza como referencia para el montaje de componentes.
Fichero `impresion_v1-invertido.pdf` es para imprimir y trasladar a placa PCB.
## Lista de materiales
| Insumo | Cantidad | Unidad | Total | Tienda | Imagen | Costo |
| ------------------------------------------------------------ | -------- | ------ | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ | ----- |
| Socket DIP 30 (para Arduino Nano) | 4 | 69 | 276 | [enlace](https://articulo.mercadolibre.com.mx/MLM-927042088-10-base-socket-zocalo-28-pines-dip-ancha-dip28-_JM#position=13&search_layout=grid&type=item&tracking_id=50e3fda3-211b-4ca5-a739-4e8d0bc14b13) | ![](https://http2.mlstatic.com/D_NQ_NP_635359-MLA46668173367_072021-O.jpg) | |
| Arduino Nano | 4 | 159 | 636 | [enlace](https://articulo.mercadolibre.com.mx/MLM-603372065-arduino-nano-v30-cable-usb-_JM) | ![](https://www.hwlibre.com/wp-content/uploads/2020/04/arduino-nano.jpg) | |
| Raspberry Pi 4 2GB | 1 | 1550 | 1550 | [enlace](https://www.geekfactory.mx/tienda/tarjetas/raspberry-pi/raspberry-pi-4-2-gb-ram-modelo-b/) | ![](https://www.newark.com/productimages/standard/en_US/02AH3161-40.jpg) | |
| Resistencia 10k 1%tolerancia | 1 | 1 | 1 | [enlace](https://www.steren.com.mx/resistencia-de-pelicula-de-carbon-de-10-kohms-a-1-2-watt-con-5-de-tolerancia.html) | ![](https://http2.mlstatic.com/D_NQ_NP_930651-MLA43848144650_102020-W.jpg) | |
| Resistencia 4k7 1%tolerancia | 1 | 20 | 20 | | ![](https://http2.mlstatic.com/D_NQ_NP_930651-MLA43848144650_102020-W.jpg) | |
| Resistencia 3k 1%tolerancia | 1 | 1 | 1 | | ![](https://http2.mlstatic.com/D_NQ_NP_930651-MLA43848144650_102020-W.jpg) | |
| Resistencia 1k5 1%tolerancia | 1 | 20 | 20 | | ![](https://http2.mlstatic.com/D_NQ_NP_930651-MLA43848144650_102020-W.jpg) | |
| Diodo Schottky 5v o más | 4 | 20 | 80 | | ![](https://uelectronics.com/wp-content/uploads/AR0195-SCHOTTKY-DIODO-1N5819-2.jpg) | |
| Fusible chico | 1 | 4 | 4 | [enlace](https://www.steren.com.mx/fusible-europeo-de-5-a-250-vca.html) | | |
| Porta fusible chico (30mm para placa) | 2 | 5 | 10 | [enlace](https://www.steren.com.mx/porta-fusible-abrazadera-europeo.html) | ![](https://http2.mlstatic.com/D_NQ_NP_967294-MLA48427348531_122021-O.webp) | |
| Botón pulsador | 2 | 45 | 90 | [enlace](https://articulo.mercadolibre.com.mx/MLM-768086213-20-piezas-de-push-button-4-pines-6x6x43mm-_JM#position=8&search_layout=grid&type=item&tracking_id=e91406ce-8426-460f-a0c3-6a5dd90c3014) | ![](https://www.electronicshub.org/wp-content/uploads/2018/02/Raspberry-Pi-Push-Button-Interface-Push-Button.jpg) | |
| Sonda digital de temperatura DS18B20 | 1 | 110 | 110 | [enlace](https://articulo.mercadolibre.com.mx/MLM-847988031-par-2-pzas-ds18b20-sensor-de-temperatura-sumergible-arduino-_JM#position=3&search_layout=grid&type=item&tracking_id=c8613538-bb28-4918-8ae8-fe46ff44ac58) | ![](https://http2.mlstatic.com/D_NQ_NP_760282-MLA31134211758_062019-O.webp) | |
| Sensor de turbidez SEN0189 | 1 | 415 | 415 | [enlace](https://www.geekfactory.mx/tienda/sensores/sensor-de-turbidez-analogico-gravity-dfrobot/) | ![](https://http2.mlstatic.com/D_NQ_NP_635928-MLM26497853219_122017-O.webp) | |
| Kit sensor de pH | 1 | 5240 | 5240 | [enlace](https://atlas-scientific.com/kits/ph-kit/) | [enlace](https://atlas-scientific.com/kits/ph-kit/) | |
| Kit sensor de conductividad | 1 | 6120 | 6120 | [enlace](https://atlas-scientific.com/kits/mini-conductivity-k-1-0-kit/) | [enlace](https://atlas-scientific.com/kits/mini-conductivity-k-1-0-kit/) | |
| Bomba de agua sumergible para arduino | 1 | 62 | 62 | [enlace](https://articulo.mercadolibre.com.mx/MLM-683758574-mini-bomba-de-agua-sumergible-36v-arduino-pic-_JM) | | |
| Conector de dos vías para cable hembra + 'Conector de dos vías para plaqueta macho recto | 6 | 45 | 270 | [enlace](https://articulo.mercadolibre.com.mx/MLM-905787098-2-juegos-conector-hembra-cable-y-macho-jst-125-mm-2-pin-_JM#position=3&search_layout=grid&type=item&tracking_id=c47d066e-77b4-474e-b220-2fee12dc0c5a) | | |
| Conector de tres vías para cable hembra+ 'Conector de tres vías para plaqueta hembra recto | 2 | 50 | 100 | [enlace](https://articulo.mercadolibre.com.mx/MLM-734108508-conector-jst-xh-macho-y-hembra-de-3-pines-_JM#position=14&search_layout=grid&type=item&tracking_id=d3ec06ea-1846-4284-99eb-7a0d8ef6ee26) | ![](https://www.electrogeekshop.com/wp-content/uploads/2020/06/conector-housing-hembra-paso-1-molex-3-vias-pack-x-25-D_NQ_NP_886142-MLA40809868011_022020-Q.jpg) | |
| celda de litio 18650 (si viene con la chapita de nickel les va a facilitar mucho al momento de soldar) | 56 | 20 | 1120 | [enlace](https://articulo.mercadolibre.com.mx/MLM-826413561-10-piezas-bateria-recargable-18650-ventilador-linterna-t2218-_JM?matt_tool=54306600&matt_word=&matt_source=google&matt_campaign_id=15697272376&matt_ad_group_id=128898863662&matt_match_type=&matt_network=g&matt_device=c&matt_creative=571860447281&matt_keyword=&matt_ad_position=&matt_ad_type=pla&matt_merchant_id=141916252&matt_product_id=MLM826413561&matt_product_partition_id=1429154252846&matt_target_id=pla-1429154252846&gclid=CjwKCAjwxOCRBhA8EiwA0X8hi6BBz86IZwYvJHgGO2gteos_GSVdfXCAoE5pvF6kMe783gNXFrFNWxoCyjUQAvD_BwE) | ![](https://http2.mlstatic.com/D_NQ_NP_711964-MLA48944801614_012022-O.webp) | |
| módulo de carga TP4056 con protección de descarga | 1 | 14 | 14 | [enlace](https://www.geekfactory.mx/tienda/modulos/cargadores/modulo-tp4056-cargador-bateria/) | ![](https://http2.mlstatic.com/D_NQ_NP_600051-MLA45728093114_042021-O.webp) | |
| fuente DC-DC boost (step-up que pueda tomar 3v y subirlo a 5.5v) | 1 | 33 | 33 | [enlace](https://www.geekfactory.mx/tienda/modulos/reguladores/convertidor-dc-dc-step-up-boost/) | ![](https://http2.mlstatic.com/D_NQ_NP_660917-MLA45233216458_032021-O.webp) | |
| Placa PCB | 1 | 32 | 32 | [enlace](https://www.geekfactory.mx/tienda/protoboards/placa-fenolica-una-cara-10-x-15-cm/) | | |
| Cables Protoboard | 1 | 52 | 52 | [enlace](https://articulo.mercadolibre.com.mx/MLM-602661891-cables-dupont-jumpers-para-protoboard-20cm-40piezas-_JM?quantity=1&variation_id=18583022758) | | |
| Tira header macho | 4 | 9 | 36 | [enlace](https://www.geekfactory.mx/tienda/componentes/conectores/header-macho/) | | |
| Tira poste hembra | 4 | 10 | 40 | [enlace](https://www.geekfactory.mx/tienda/componentes/conectores/header-hembra-tira-de-pines-sencilla/) | | |

Binary file not shown.

Binary file not shown.

View file

@ -1,210 +0,0 @@
EESchema-LIBRARY Version 2.4
#encoding utf-8
#
# Connector_Generic_Conn_01x03
#
DEF Connector_Generic_Conn_01x03 J 0 40 Y N 1 F N
F0 "J" 0 200 50 H V C CNN
F1 "Connector_Generic_Conn_01x03" 0 -200 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
Connector*:*_1x??_*
$ENDFPLIST
DRAW
S -50 -95 0 -105 1 1 6 N
S -50 5 0 -5 1 1 6 N
S -50 105 0 95 1 1 6 N
S -50 150 50 -150 1 1 10 f
X Pin_1 1 -200 100 150 R 50 50 1 1 P
X Pin_2 2 -200 0 150 R 50 50 1 1 P
X Pin_3 3 -200 -100 150 R 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Connector_Raspberry_Pi_2_3
#
DEF Connector_Raspberry_Pi_2_3 J 0 40 Y Y 1 F N
F0 "J" -700 1250 50 H V L BNN
F1 "Connector_Raspberry_Pi_2_3" 400 -1250 50 H V L TNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
PinHeader*2x20*P2.54mm*Vertical*
PinSocket*2x20*P2.54mm*Vertical*
$ENDFPLIST
DRAW
S -700 1200 700 -1200 0 1 10 f
S -665 -690 -700 -710 1 1 0 N
S -665 -590 -700 -610 1 1 0 N
S -665 -490 -700 -510 1 1 0 N
S -665 -390 -700 -410 1 1 0 N
S -665 -290 -700 -310 1 1 0 N
S -665 -190 -700 -210 1 1 0 N
S -665 10 -700 -10 1 1 0 N
S -665 110 -700 90 1 1 0 N
S -665 210 -700 190 1 1 0 N
S -665 410 -700 390 1 1 0 N
S -665 510 -700 490 1 1 0 N
S -665 610 -700 590 1 1 0 N
S -665 810 -700 790 1 1 0 N
S -665 910 -700 890 1 1 0 N
S -410 -1165 -390 -1200 1 1 0 N
S -310 -1165 -290 -1200 1 1 0 N
S -210 -1165 -190 -1200 1 1 0 N
S -210 1200 -190 1165 1 1 0 N
S -110 -1165 -90 -1200 1 1 0 N
S -110 1200 -90 1165 1 1 0 N
S -10 -1165 10 -1200 1 1 0 N
S 90 -1165 110 -1200 1 1 0 N
S 90 1200 110 1165 1 1 0 N
S 190 -1165 210 -1200 1 1 0 N
S 190 1200 210 1165 1 1 0 N
S 290 -1165 310 -1200 1 1 0 N
S 700 -790 665 -810 1 1 0 N
S 700 -690 665 -710 1 1 0 N
S 700 -490 665 -510 1 1 0 N
S 700 -390 665 -410 1 1 0 N
S 700 -290 665 -310 1 1 0 N
S 700 -190 665 -210 1 1 0 N
S 700 -90 665 -110 1 1 0 N
S 700 110 665 90 1 1 0 N
S 700 210 665 190 1 1 0 N
S 700 310 665 290 1 1 0 N
S 700 510 665 490 1 1 0 N
S 700 610 665 590 1 1 0 N
S 700 810 665 790 1 1 0 N
S 700 910 665 890 1 1 0 N
X 3V3 1 100 1300 100 D 50 50 1 1 W
X GPIO15/RXD 10 -800 800 100 R 50 50 1 1 B
X GPIO17 11 -800 500 100 R 50 50 1 1 B
X GPIO18/PWM0 12 -800 400 100 R 50 50 1 1 B
X GPIO27 13 -800 -700 100 R 50 50 1 1 B
X GND 14 -200 -1300 100 U 50 50 1 1 W
X GPIO22 15 -800 -200 100 R 50 50 1 1 B
X GPIO23 16 -800 -300 100 R 50 50 1 1 B
X 3V3 17 200 1300 100 D 50 50 1 1 W
X GPIO24 18 -800 -400 100 R 50 50 1 1 B
X MOSI0/GPIO10 19 800 -400 100 L 50 50 1 1 B
X 5V 2 -200 1300 100 D 50 50 1 1 W
X GND 20 -100 -1300 100 U 50 50 1 1 W
X MISO0/GPIO9 21 800 -300 100 L 50 50 1 1 B
X GPIO25 22 -800 -500 100 R 50 50 1 1 B
X SCLK0/GPIO11 23 800 -500 100 L 50 50 1 1 B
X ~CE0~/GPIO8 24 800 -200 100 L 50 50 1 1 B
X GND 25 0 -1300 100 U 50 50 1 1 W
X ~CE1~/GPIO7 26 800 -100 100 L 50 50 1 1 B
X ID_SD/GPIO0 27 800 900 100 L 50 50 1 1 B
X ID_SC/GPIO1 28 800 800 100 L 50 50 1 1 B
X GCLK1/GPIO5 29 800 200 100 L 50 50 1 1 B
X SDA/GPIO2 3 800 600 100 L 50 50 1 1 B
X GND 30 100 -1300 100 U 50 50 1 1 W
X GCLK2/GPIO6 31 800 100 100 L 50 50 1 1 B
X PWM0/GPIO12 32 800 -700 100 L 50 50 1 1 B
X PWM1/GPIO13 33 800 -800 100 L 50 50 1 1 B
X GND 34 200 -1300 100 U 50 50 1 1 W
X GPIO19/MISO1 35 -800 200 100 R 50 50 1 1 B
X GPIO16 36 -800 600 100 R 50 50 1 1 B
X GPIO26 37 -800 -600 100 R 50 50 1 1 B
X GPIO20/MOSI1 38 -800 100 100 R 50 50 1 1 B
X GND 39 300 -1300 100 U 50 50 1 1 W
X 5V 4 -100 1300 100 D 50 50 1 1 W
X GPIO21/SCLK1 40 -800 0 100 R 50 50 1 1 B
X SCL/GPIO3 5 800 500 100 L 50 50 1 1 B
X GND 6 -400 -1300 100 U 50 50 1 1 W
X GCLK0/GPIO4 7 800 300 100 L 50 50 1 1 B
X GPIO14/TXD 8 -800 900 100 R 50 50 1 1 B
X GND 9 -300 -1300 100 U 50 50 1 1 W
ENDDRAW
ENDDEF
#
# Device_D_Schottky
#
DEF Device_D_Schottky D 0 40 N N 1 F N
F0 "D" 0 100 50 H V C CNN
F1 "Device_D_Schottky" 0 -100 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
TO-???*
*_Diode_*
*SingleDiode*
D_*
$ENDFPLIST
DRAW
P 2 0 1 0 50 0 -50 0 N
P 4 0 1 8 50 50 50 -50 -50 0 50 50 N
P 6 0 1 8 -75 25 -75 50 -50 50 -50 -50 -25 -50 -25 -25 N
X K 1 -150 0 100 R 50 50 1 1 P
X A 2 150 0 100 L 50 50 1 1 P
ENDDRAW
ENDDEF
#
# Device_R_US
#
DEF Device_R_US R 0 0 N Y 1 F N
F0 "R" 100 0 50 V V C CNN
F1 "Device_R_US" -100 0 50 V V C CNN
F2 "" 40 -10 50 V I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
R_*
$ENDFPLIST
DRAW
P 2 0 1 0 0 -90 0 -100 N
P 2 0 1 0 0 90 0 100 N
P 5 0 1 0 0 -30 40 -45 0 -60 -40 -75 0 -90 N
P 5 0 1 0 0 30 40 15 0 0 -40 -15 0 -30 N
P 5 0 1 0 0 90 40 75 0 60 -40 45 0 30 N
X ~ 1 0 150 50 D 50 50 1 1 P
X ~ 2 0 -150 50 U 50 50 1 1 P
ENDDRAW
ENDDEF
#
# MCU_Module_Arduino_Nano_v3.x
#
DEF MCU_Module_Arduino_Nano_v3.x A 0 20 Y Y 1 F N
F0 "A" -400 925 50 H V L BNN
F1 "MCU_Module_Arduino_Nano_v3.x" 200 -950 50 H V L TNN
F2 "Module:Arduino_Nano" 0 0 50 H I C CIN
F3 "" 0 0 50 H I C CNN
ALIAS Arduino_Nano_v3.x
$FPLIST
Arduino*Nano*
$ENDFPLIST
DRAW
S -400 900 400 -900 0 1 10 f
X D1/TX 1 -500 500 100 R 50 50 1 1 B
X D7 10 -500 -100 100 R 50 50 1 1 B
X D8 11 -500 -200 100 R 50 50 1 1 B
X D9 12 -500 -300 100 R 50 50 1 1 B
X D10 13 -500 -400 100 R 50 50 1 1 B
X D11 14 -500 -500 100 R 50 50 1 1 B
X D12 15 -500 -600 100 R 50 50 1 1 B
X D13 16 -500 -700 100 R 50 50 1 1 B
X 3V3 17 100 1000 100 D 50 50 1 1 w
X AREF 18 500 200 100 L 50 50 1 1 I
X A0 19 500 0 100 L 50 50 1 1 B
X D0/RX 2 -500 600 100 R 50 50 1 1 B
X A1 20 500 -100 100 L 50 50 1 1 B
X A2 21 500 -200 100 L 50 50 1 1 B
X A3 22 500 -300 100 L 50 50 1 1 B
X A4 23 500 -400 100 L 50 50 1 1 B
X A5 24 500 -500 100 L 50 50 1 1 B
X A6 25 500 -600 100 L 50 50 1 1 B
X A7 26 500 -700 100 L 50 50 1 1 B
X +5V 27 200 1000 100 D 50 50 1 1 w
X ~RESET 28 500 600 100 L 50 50 1 1 I
X GND 29 100 -1000 100 U 50 50 1 1 W
X ~RESET 3 500 500 100 L 50 50 1 1 I
X VIN 30 -100 1000 100 D 50 50 1 1 W
X GND 4 0 -1000 100 U 50 50 1 1 W
X D2 5 -500 400 100 R 50 50 1 1 B
X D3 6 -500 300 100 R 50 50 1 1 B
X D4 7 -500 200 100 R 50 50 1 1 B
X D5 8 -500 100 100 R 50 50 1 1 B
X D6 9 -500 0 100 R 50 50 1 1 B
ENDDRAW
ENDDEF
#
#End Library

View file

@ -1 +0,0 @@
(kicad_pcb (version 4) (host kicad "dummy file") )

View file

@ -1,33 +0,0 @@
update=22/05/2015 07:44:53
version=1
last_client=kicad
[general]
version=1
RootSch=
BoardNm=
[pcbnew]
version=1
LastNetListRead=
UseCmpFile=1
PadDrill=0.600000000000
PadDrillOvalY=0.600000000000
PadSizeH=1.500000000000
PadSizeV=1.500000000000
PcbTextSizeV=1.500000000000
PcbTextSizeH=1.500000000000
PcbTextThickness=0.300000000000
ModuleTextSizeV=1.000000000000
ModuleTextSizeH=1.000000000000
ModuleTextSizeThickness=0.150000000000
SolderMaskClearance=0.000000000000
SolderMaskMinWidth=0.000000000000
DrawSegmentWidth=0.200000000000
BoardOutlineThickness=0.100000000000
ModuleOutlineThickness=0.150000000000
[cvpcb]
version=1
NetIExt=net
[eeschema]
version=1
LibDir=
[eeschema/libraries]

View file

@ -1,309 +0,0 @@
EESchema Schematic File Version 4
EELAYER 30 0
EELAYER END
$Descr A4 11693 8268
encoding utf-8
Sheet 1 1
Title ""
Date ""
Rev ""
Comp ""
Comment1 ""
Comment2 ""
Comment3 ""
Comment4 ""
$EndDescr
$Comp
L MCU_Module:Arduino_Nano_v3.x A?
U 1 1 61B28541
P 8250 3400
F 0 "A?" V 8296 2356 50 0000 R CNN
F 1 "Arduino_Nano_v3.x" V 8205 2356 50 0000 R CNN
F 2 "Module:Arduino_Nano" H 8250 3400 50 0001 C CIN
F 3 "http://www.mouser.com/pdfdocs/Gravitech_Arduino_Nano3_0.pdf" H 8250 3400 50 0001 C CNN
1 8250 3400
0 -1 -1 0
$EndComp
$Comp
L MCU_Module:Arduino_Nano_v3.x A?
U 1 1 61B2C7A5
P 8250 5150
F 0 "A?" V 8296 4106 50 0000 R CNN
F 1 "Arduino_Nano_v3.x" V 8205 4106 50 0000 R CNN
F 2 "Module:Arduino_Nano" H 8250 5150 50 0001 C CIN
F 3 "http://www.mouser.com/pdfdocs/Gravitech_Arduino_Nano3_0.pdf" H 8250 5150 50 0001 C CNN
1 8250 5150
0 -1 -1 0
$EndComp
$Comp
L Connector:Raspberry_Pi_2_3 J?
U 1 1 61B30B81
P 2000 2700
F 0 "J?" H 2000 4181 50 0000 C CNN
F 1 "Raspberry_Pi_2_3" H 2000 4090 50 0000 C CNN
F 2 "" H 2000 2700 50 0001 C CNN
F 3 "https://www.raspberrypi.org/documentation/hardware/raspberrypi/schematics/rpi_SCH_3bplus_1p0_reduced.pdf" H 2000 2700 50 0001 C CNN
1 2000 2700
-1 0 0 -1
$EndComp
Wire Bus Line
6450 3900 7650 3900
Wire Bus Line
7650 5650 6450 5650
Wire Bus Line
6450 5650 6450 3900
Connection ~ 6450 3900
$Comp
L MCU_Module:Arduino_Nano_v3.x A?
U 1 1 61B25B94
P 8250 1900
F 0 "A?" V 8296 856 50 0000 R CNN
F 1 "Arduino_Nano_v3.x" V 8205 856 50 0000 R CNN
F 2 "Module:Arduino_Nano" H 8250 1900 50 0001 C CIN
F 3 "http://www.mouser.com/pdfdocs/Gravitech_Arduino_Nano3_0.pdf" H 8250 1900 50 0001 C CNN
1 8250 1900
0 -1 -1 0
$EndComp
Wire Bus Line
7650 2400 7650 2550
Wire Bus Line
7650 2550 6450 2550
Wire Bus Line
6450 2550 6450 3900
$Comp
L Device:R_US R1
U 1 1 61B549F6
P 3000 950
F 0 "R1" V 2795 950 50 0000 C CNN
F 1 "10k" V 2886 950 50 0000 C CNN
F 2 "" V 3040 940 50 0001 C CNN
F 3 "~" H 3000 950 50 0001 C CNN
1 3000 950
0 1 1 0
$EndComp
Wire Bus Line
1800 1400 1800 950
Wire Bus Line
1800 950 2850 950
Wire Bus Line
3150 950 3150 1900
Wire Bus Line
3150 1900 2800 1900
$Comp
L Device:D_Schottky D1
U 1 1 61B5BDFA
P 5550 2650
F 0 "D1" H 5550 2434 50 0000 C CNN
F 1 "D_Schottky" H 5550 2525 50 0000 C CNN
F 2 "" H 5550 2650 50 0001 C CNN
F 3 "~" H 5550 2650 50 0001 C CNN
1 5550 2650
-1 0 0 1
$EndComp
Wire Bus Line
7750 2400 7750 2650
$Comp
L Device:D_Schottky D2
U 1 1 61B67CB8
P 5600 4200
F 0 "D2" H 5600 3984 50 0000 C CNN
F 1 "D_Schottky" H 5600 4075 50 0000 C CNN
F 2 "" H 5600 4200 50 0001 C CNN
F 3 "~" H 5600 4200 50 0001 C CNN
1 5600 4200
-1 0 0 1
$EndComp
Wire Bus Line
7750 3900 7750 4200
Wire Bus Line
7750 4200 5750 4200
$Comp
L Device:D_Schottky D3
U 1 1 61B6C950
P 5650 5900
F 0 "D3" H 5650 5684 50 0000 C CNN
F 1 "D_Schottky" H 5650 5775 50 0000 C CNN
F 2 "" H 5650 5900 50 0001 C CNN
F 3 "~" H 5650 5900 50 0001 C CNN
1 5650 5900
-1 0 0 1
$EndComp
Wire Bus Line
7750 5650 7750 5900
Wire Bus Line
7750 5900 5800 5900
Wire Bus Line
2800 1800 6450 1800
Wire Bus Line
6450 1800 6450 2550
Connection ~ 6450 2550
$Comp
L Device:R_US R3
U 1 1 61B8E6C4
P 4600 2950
F 0 "R3" V 4395 2950 50 0000 C CNN
F 1 "1k5" V 4486 2950 50 0000 C CNN
F 2 "" V 4640 2940 50 0001 C CNN
F 3 "~" H 4600 2950 50 0001 C CNN
1 4600 2950
0 1 1 0
$EndComp
Wire Bus Line
4200 2950 4300 2950
Wire Bus Line
4300 2950 4300 1900
Wire Bus Line
4300 1900 3150 1900
Connection ~ 4300 2950
Wire Bus Line
4300 2950 4450 2950
Connection ~ 3150 1900
Wire Bus Line
4750 2950 5050 2950
Wire Bus Line
5450 4200 5050 4200
Wire Bus Line
5050 4200 5050 2950
Connection ~ 5050 2950
Wire Bus Line
5050 2950 5400 2950
Wire Bus Line
5500 5900 5050 5900
Wire Bus Line
5050 5900 5050 4200
Connection ~ 5050 4200
Wire Bus Line
2400 4000 3900 4000
Wire Bus Line
3900 4000 3900 2950
$Comp
L Device:R_US R2
U 1 1 61B8D59A
P 4050 2950
F 0 "R2" V 3845 2950 50 0000 C CNN
F 1 "3k" V 3936 2950 50 0000 C CNN
F 2 "" V 4090 2940 50 0001 C CNN
F 3 "~" H 4050 2950 50 0001 C CNN
1 4050 2950
0 1 1 0
$EndComp
Wire Bus Line
2200 1400 6700 1400
Wire Bus Line
6700 1400 6700 2000
Wire Bus Line
6700 2000 7250 2000
Wire Bus Line
6700 2000 6700 3500
Wire Bus Line
6700 3500 7250 3500
Connection ~ 6700 2000
Wire Bus Line
6700 3500 6700 5250
Wire Bus Line
6700 5250 7250 5250
Connection ~ 6700 3500
Text Label 8100 1250 0 50 ~ 0
TEMPERATURA
$Comp
L Connector_Generic:Conn_01x03 J1
U 1 1 61BB5F6D
P 10200 750
F 0 "J1" V 10164 562 50 0000 R CNN
F 1 "Conn_01x03" V 10073 562 50 0000 R CNN
F 2 "" H 10200 750 50 0001 C CNN
F 3 "~" H 10200 750 50 0001 C CNN
1 10200 750
0 -1 -1 0
$EndComp
Wire Bus Line
6700 1400 6700 1000
Wire Bus Line
10100 1000 10100 950
Connection ~ 6700 1400
$Comp
L Device:R_US R4
U 1 1 61BBED66
P 10100 1400
F 0 "R4" H 10032 1354 50 0000 R CNN
F 1 "4k7" H 10032 1445 50 0000 R CNN
F 2 "" V 10140 1390 50 0001 C CNN
F 3 "~" H 10100 1400 50 0001 C CNN
1 10100 1400
1 0 0 1
$EndComp
Wire Bus Line
10100 1000 10100 1250
Connection ~ 10100 1000
Wire Bus Line
7850 2400 7850 2600
Wire Bus Line
7850 2600 10100 2600
Wire Bus Line
10100 1600 10200 1600
Wire Bus Line
9250 1900 10300 1900
$Comp
L Connector_Generic:Conn_01x03 J?
U 1 1 61BD4811
P 10500 2400
F 0 "J?" V 10464 2212 50 0000 R CNN
F 1 "Conn_01x03" V 10373 2212 50 0000 R CNN
F 2 "" H 10500 2400 50 0001 C CNN
F 3 "~" H 10500 2400 50 0001 C CNN
1 10500 2400
0 -1 -1 0
$EndComp
Wire Bus Line
6700 1000 10100 1000
Wire Bus Line
7250 3200 7250 2750
Wire Bus Line
7250 2750 10400 2750
Wire Bus Line
10400 2750 10400 2600
Wire Bus Line
5400 2950 5400 2650
Wire Bus Line
5700 2650 7750 2650
Wire Bus Line
8950 2900 10500 2900
Wire Bus Line
10500 2900 10500 2600
Text Label 9500 3100 0 50 ~ 0
TURBIDEZ
Text Label 9200 4550 0 50 ~ 0
?????
Wire Bus Line
3900 4000 3900 6050
Wire Bus Line
3900 6050 10300 6050
Connection ~ 3900 4000
Wire Bus Line
10300 6050 10300 5150
Wire Bus Line
9250 3300 10600 3300
Wire Bus Line
10600 3300 10600 2600
Wire Bus Line
9250 3400 10300 3400
Connection ~ 10300 3400
Wire Bus Line
10300 3400 10300 1900
Wire Bus Line
9250 5150 10300 5150
Connection ~ 10300 5150
Wire Bus Line
10300 5150 10300 3400
Connection ~ 10100 1600
Wire Bus Line
10100 1600 10100 1550
Wire Bus Line
10200 1600 10200 950
Wire Bus Line
10100 1600 10100 2600
Wire Bus Line
9250 1800 10300 1800
Wire Bus Line
10300 1800 10300 950
$EndSCHEMATC

View file

@ -1,4 +0,0 @@
EESchema Schematic File Version 2
EELAYER 25 0
EELAYER END
$EndSCHEMATC

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

3
functions Normal file
View file

@ -0,0 +1,3 @@
get_stack () {
ls $install_dir/stack | tail -1
}

44
install.sh Executable file
View file

@ -0,0 +1,44 @@
#!/bin/bash
files="data_gen.sh monitor.sh register.sh uninstall.sh monitor.web bin functions counter"
config=nodemecu.conf.sample
source $config
echo -e "1. Instalando dependencias"
#sudo apt update && sudo apt install -y jq uuid-runtime dnsmasq dnsutils
sudo pip install pyserial
echo ""
# Estructura de directorios
echo -e "2. Creando directorios y copiando archivos"
sudo mkdir -vp $install_dir/archives/historical
sudo mkdir -vp $install_dir/archives/logs
sudo mkdir -vp $historical
sudo mkdir -vp $stack
sudo mkdir -vp $corrupt
sudo mkdir -vp $failed
echo ""
sudo cp -vr $files $install_dir
sudo cp -v $config /etc/nodemecu.conf
sudo ln -s $install_dir/bin/nodemecu /usr/bin/nodemecu
sudo touch $log
echo ""
echo "3. Configurando systemd"
sudo cp nodemecu.service /lib/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable nodemecu.service
sudo systemctl start nodemecu.service
sudo systemctl status nodemecu.service
echo ""
echo ". Alias de comandos."
echo "alias nodemecu='sudo nodemecu'" >> $HOME/.bashrc
echo ""
echo "Ejecute 'source ~/.bashrc' para aplicar los cambios."
echo ""

16
monitor.sh Executable file
View file

@ -0,0 +1,16 @@
#!/bin/bash
source /etc/nodemecu.conf
while :;do
clear
echo "$(date)"
echo "Stack: $(ls $stack | wc -l) ficheros"
echo "Historicos: $(ls $historical | wc -l) ficheros"
echo "Testigo: $(cat $install_dir/counter)"
echo "Errores: $(wc -l $log) registros"
echo "Ultimo error registrado:"
tail -1 $log
echo ""
echo "'ctrl-c' para salir."
sleep 100
done

11
monitor.web Executable file
View file

@ -0,0 +1,11 @@
#!/bin/bash
source /etc/nodemecu.conf
echo "<p>$(date)<br>"
echo "Stack: $(ls $stack | wc -l) ficheros<br>"
echo "Historicos: $(ls $historical | wc -l) ficheros<br>"
echo "Testigo: $(cat $install_dir/counter)<br>"
echo "Errores: $(wc -l $log) registros<br>"
echo "Ultimos errores registrados<br>"
tail -1 $log
echo "<br></p>"

18
nodemecu.conf.sample Normal file
View file

@ -0,0 +1,18 @@
url=https://ectomobile.sutty.nl/transactions
name=
interval=
mode=test
json_linter=jsonlint-php
# AJUSTES GENERALES
# SE RECOMIENDA NO MODIFICAR ESTAS LINEAS
curl_err=/tmp/curl_err
historical_file_size=1440
logs_file_size=1440
install_dir=/opt/nodemecu
stack=$install_dir/stack
historical=$install_dir/historical
log=$install_dir/errors.log
corrupt=$install_dir/corrupt
failed=$install_dir/failed

View file

@ -2,9 +2,7 @@
Description=Procesador de pila y transmisor de datos Nodemecu. Description=Procesador de pila y transmisor de datos Nodemecu.
[Service] [Service]
Restart=on-failure ExecStart=/opt/nodemecu/register.sh
RestartSec=5s
ExecStart=/opt/nodemecu/registrador
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View file

@ -1,84 +0,0 @@
#!/bin/bash
if [ $UID -ne 0 ]; then
echo "Ejecute 'sudo $0'"
exit
fi
# LECTURA FICHERO DE CONFIGURACION
config=/etc/nodemecu.conf
envs=/opt/nodemecu/envs
source $config
source $envs
source $funciones
[ -z $1 ] && exit
com=$1
case $com in
configurar)
echo "Complete los cambios a continuación:
"
echo "Nombre del dispositivo."
read -p "nombre: " -a entrada_usuario
funcion_configurar nombre ${entrada_usuario[@]}
echo ""
echo "Servidor de entrega de datos."
read -p "servidor (ej. https://url.del/servidor): " entrada_usuario
funcion_configurar servidor $entrada_usuario
echo ""
echo "Intervalo de toma de muestras, entre 1 y 60 minutos."
read -p "intervalo: " entrada_usuario
funcion_configurar intervalo $entrada_usuario
echo ""
echo "Creando juego de llaves"
source $config
comentario="$nombre $numero_serie"
generate_private_key "$comentario"
echo ""
echo "El modo de operación por defecto es 'test' y se envían datos simulados, cambie a 'sensores' con el comando 'sudo nodemecu modo sensores'
"
;;
nombre)
funcion_configurar $@
;;
servidor)
funcion_configurar $@
;;
intervalo)
funcion_configurar $@
;;
modo)
funcion_configurar $@
;;
captura)
test_conf_nombre || exit
test_conf_intervalo || exit
test_conf_key || exit
funcion_captura $2
;;
monitor)
funcion_monitor
;;
cllave)
if [ -z $nombre ]; then
echo "Debe establecer primero el nombre del dispositivo"
else
echo "Creando juego de llaves"
generate_private_key
fi
;;
*)
exit
;;
esac

View file

@ -1,39 +0,0 @@
#!/bin/bash
source /etc/nodemecu.conf
source /opt/nodemecu/envs
if [ $UID -ne 0 ]; then
echo "Ejecute 'sudo $0'"
exit
fi
seguro="Si, se lo que estoy haciendo."
echo "Está a punto de desinstalar nodemecu, esta acción eliminará todos los archivos de instalacion y registros que se hayan tomado sin posiblidad de recuperación, haga un backup de:
- /etc/nodemecu.conf
- $directorio_instalacion
- $log
Para continuar escriba la frase '$seguro'.
"
#read -p "frase: " frase
#if [ "$frase" = "$seguro" ];then
rm /etc/nodemecu.conf
rm /usr/bin/nodemecu
crontab -u root -r
rm -rf $directorio_instalacion
systemctl stop nodemecu.service
systemctl disable nodemecu.service
rm /lib/systemd/system/nodemecu.service
systemctl daemon-reload
#else
echo "La frase de seguridad no concuerda.
"
#fi

View file

@ -1,31 +0,0 @@
# NO MODIFICAR ESTE FICHERO !!!!!!!!!!
numero_serie=0000000083a999fd
curl_err=/tmp/curl_err
directorio_instalacion=/opt/nodemecu
registros=$directorio_instalacion/registros
historicos=$directorio_instalacion/historicos
log=/var/log/nodemecu_errors.log
registros_corruptos=$directorio_instalacion/corruptos
lock=$directorio_instalacion/lock
funciones=$directorio_instalacion/funciones
arduinos_py=$directorio_instalacion/arduinos.py
key_dir=$directorio_instalacion/llaves
private_key=$key_dir/$numero_serie.key
public_key=$key_dir/$numero_serie.key.pub

View file

@ -1,271 +0,0 @@
#!/bin/bash
#set -x
get_stack () {
if [[ ! -z $1 && $1 == "wc" ]];then
ls -I "*.sig" $registros | wc -l
else
ls -I "*.sig" $registros | tail -1
fi
}
# Generar una llave privada ECDSA si no existe
generate_private_key () {
test -f "$private_key" && return 1
ssh-keygen -t ecdsa -f "$private_key" -N "" -C "$@"
}
# Firmar el archivo usando la llave privada.
#
# Uso: sign_file archivo.json
# Devuelve: La firma
sign_file () {
local _file="$1"
test ! -f "$_file" && return 1
test -f "$_file.sig" || ssh-keygen -Y sign -f "$private_key" -n file "$_file" >/dev/null 2>&1
cat "${_file}.sig" | grep -v SIGNATURE | tr -d "\n"
}
funcion_datos_simulados() {
lecturas="id:dummy_plug-01 tp:temp vl:$(( $RANDOM % 20 + 15 )) un:C er:99 AD_SENSOR tp:hum vl:$(( $RANDOM % 50 + 35 )) un:percent er:99 AD_ARDUINO id:dummy_plug-02 tp:temp vl:$(( $RANDOM % 20 + 15 )) un:C er:99 AD_SENSOR tp:hum vl:$(( $RANDOM % 50 + 35 )) un:percent er:99 AD_ARDUINO id:dummy_plug-03 tp:temp vl:$(( $RANDOM % 20 + 15 )) un:C er:99 AD_SENSOR tp:hum vl:$(( $RANDOM % 50 + 35 )) un:percent er:99 AD_ARDUINO id:dummy_plug-04 tp:temp vl:$(( $RANDOM % 20 + 15 )) un:C er:99 AD_SENSOR tp:hum vl:$(( $RANDOM % 50 + 35 )) un:percent er:99 END"
}
funcion_datos_sensores() {
peticiones=1
arduinos=( 1 2 )
for arduino_id in ${arduinos[@]};do
lectura_arduino=($(timeout 3 $arduinos_py $arduino_id))
let "bloques = (${#lectura_arduino[@]} - 1) / 4"
#lecturas="$lecturas id:${lectura_arduino[0]}"
lecturas="$lecturas id:${arduino_id[0]}"
indice=1
vueltas=1
while [ $vueltas -le $bloques ]; do
lecturas="$lecturas tp:${lectura_arduino[$indice]} vl:${lectura_arduino[$(expr $indice + 1 )]} un:${lectura_arduino[$(expr $indice + 2 )]} er:${lectura_arduino[$(expr $indice + 3 )]}"
if [ $vueltas -lt $bloques ]; then
lecturas="$lecturas AD_SENSOR"
fi
let "indice = $indice + 4 "
((vueltas++))
done
if [ $peticiones -lt ${#arduinos[@]} ];then
lecturas="$lecturas AD_ARDUINO"
fi
((peticiones++))
done
lecturas="$lecturas END"
}
funcion_configurar() {
local comando=$1
local parametro=$2
local parametros=$*
local url_regex='(https?|HTTPS?)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]'
local nuevo_modo='(test|sensores)'
case $comando in
nombre)
while :;do
nuevo_nombre=$(echo $parametros | sed 's/nombre //g' | sed 's/ /_/g')
if [[ "$nuevo_nombre" =~ ^[a-zA-Z0-9_]+$ ]];then
sed -i 's/nombre='$nombre'/nombre='$nuevo_nombre'/' $config
echo "nombre: $nuevo_nombre"
break
else
echo "El nombre solo puede contener carateres alfanumericos."
read -p "nombre: " parametro
fi
done
;;
servidor)
while :;do
if [[ $parametro =~ $url_regex ]]; then
sed -i 's}servidor='$servidor'}servidor='"$parametro"'}' $config
echo "Servidor $parametro"
break
else
echo "Intruzca una url válida."
read -p "url: " parametro
fi
done
;;
intervalo)
while :;do
if [[ $parametro -ge 1 && $parametro -le 60 ]]; then
sed -i 's/intervalo=[0-9]*/intervalo='$parametro'/' $config
echo "Intervalo seteado en $parametro"
echo "Para aplicar los cambios ejecute
sudo nodemecu captura dentener
sudo nodemecu captura iniciar"
break
else
echo "Establezca un valor entre 1 y 60."
read -p "Intervalo: " parametro
fi
done
;;
modo)
while :;do
if [[ $parametro =~ $nuevo_modo ]]; then
sed -i 's/modo='$modo'/modo='$parametro'/' $config
break
else
echo "Los modos posibles son 'test' y 'sensores'"
read -p "modo: " parametro
fi
done
esac
}
funcion_captura() {
if [ "$1" = "iniciar" ]; then
echo "Iniciando la captura de datos en modo '$modo'"
echo ""
read -p "Desea continuar? Presione 'enter' para continuar o 'ctrl-c' para cancelar..."
echo "*/$intervalo * * * * $directorio_instalacion/generador_json" > /tmp/nodemecu.crontab
crontab -u root /tmp/nodemecu.crontab
echo ""
echo "Se tomarán datos cada $intervalo minutos."
echo ""
exit
elif [ "$1" = "detener" ]; then
crontab -u root -r
echo "Se detuvo la toma de datos."
echo ""
else
echo "Ingrese una orden válida: 'iniciar' o 'detener'."
fi
}
### Validaciones
test_conf_nombre() {
if [ -z $nombre ]; then
echo "No se establecio un nombre para el dispositivo."
return 1
fi
}
test_conf_servidor () {
if [ -z $servidor ];then
echo "No se establecio un servidor de entrega."
return 1
fi
}
test_conf_intervalo() {
if [ -z $intervalo ];then
echo "No se establecio un intervalo de captura."
return 1
fi
}
test_conf_key() {
if [ ! -f $private_key ];then
echo "No se creo juego de llaves."
return 1
fi
}
funcion_validador_json() {
validar="$@"
echo $validar | jsonlint-php > /dev/null 2>&1 || return 1
}
funcion_verificar_internet() {
if host fsf.org > /dev/null 2>&1; then
return 0
else
return 1
fi
}
funcion_espera() {
sleep 1m
#sleep ${intervalo:-1}m
}
funcion_envio_registro() {
curl -s --show-error -w "~%{http_code}" \
-X POST -H "X-Signature: $(sign_file $registros/$file)" \
-H "Content-Type: application/json" -d @$registros/$file \
$servidor 2> $curl_err
}
funcion_monitor() {
local sb="\x1b["
local eb="\x1b[K\x1b[0m"
local st="\e["
local et="\e[0m"
while :;do
clear
echo -e "${sb}1;44;97m Nodemecu Monitor${eb}"
echo ""
echo -e "${st}1;94mNombre:${et} $nombre ${st}1;94mServidor:${et} $servidor ${st}1;94mIntervalo:${et} $intervalo"
echo ""
echo -e "${sb}1;44;97m Registros${eb}"
echo ""
echo -e "En cola: $(ls -I *.sig $registros| wc -l)"
echo -e "Enviados: $(ls -I *.sig $historicos | wc -l)"
echo -e "Registros corrupts: $(ls -I *.sig $registros_corruptos | wc -l)"
echo ""
echo -e "${sb}1;44;97m Ultimos mensajes${eb}"
echo ""
echo -e ${st}1m"Systemd unit 'nodemecu.service'${et}"
journalctl -n 3 -u nodemecu
echo ""
echo -e ${st}1m"Fichero '$log'${et}"
cat /var/log/nodemecu_errors.log | grep -v "Salida de curl" | grep -v '[*<>{}]' | tail -3
sleep 2
done
}

View file

@ -1,70 +0,0 @@
#!/bin/bash
source /etc/nodemecu.conf
source /opt/nodemecu/envs
source $funciones
test -z $nombre && exit
test -f $public_key || exit
uuid="$(uuid)"
marca_de_tiempo="$(date +%s)"
case $modo in
test)
funcion_datos_simulados
;;
sensores)
funcion_datos_sensores
;;
esac
# ARMADO DE FICHERO JSON
for i in $lecturas;do
case $i in
id*)
sensores="$sensores { $(echo \"id\":\"$(echo $i | cut -d ":" -f 2)\", \"sensores\": [ )"
;;
tp*)
sensores="$sensores { $(echo \"type\": \"$(echo $i | cut -d ":" -f 2)\",)"
;;
vl*)
sensores="$sensores $(echo \"value\": $(echo $i | cut -d ":" -f 2),)"
;;
un*)
sensores="$sensores $(echo \"unit\": \"$(echo $i | cut -d ":" -f 2)\",)"
;;
er*)
sensores="$sensores $(echo \"error\": $(echo $i | cut -d ":" -f 2) })"
;;
AD_SENSOR)
sensores="$sensores,"
;;
AD_ARDUINO)
sensores="$sensores]},"
;;
END)
sensores="$sensores]}"
;;
esac
done
sensores=$(echo $sensores | tr -d '[:blank:]')
json="{\"transaction_uuid\":\"$uuid\",\"serial_number\":\"$numero_serie\",\"public_key\":\"$(cat $public_key)\",\"controller_id\":\"$nombre\",\"timestamp\":\"$marca_de_tiempo\",\"error_code\":\"10\",\"coordinates\":{\"lat\":1,\"lng\":1},\"battery_status\":\"98\",\"sample\":\"0\",\"storage\":\"uso del almacenamiento\",\"arduinos\":[$sensores]}"
touch $lock
file=$(date +%Y%m%d%H%M%S -d @$marca_de_tiempo)-$uuid
if funcion_validador_json $json ;then
echo $json > $registros/$file && rm $lock
else
echo "$(date +%Y-%m-%d-%H:%M:%S -d @$marca_de_tiempo) - No se pudo generar fichero json:" >> $log
echo $json >> $log
rm $lock
fi

View file

@ -1,90 +0,0 @@
#!/bin/bash
#set -x
if [ $UID -ne 0 ]; then
echo "Ejecute 'sudo $0'"
exit
fi
basedir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
configuracion=$basedir/nodemecu.conf.ejemplo
envs=$basedir/envs
source $configuracion
source $envs
if [ -d $directorio_instalacion ] ; then
echo "nodemecu ya se encuentra instalado"
exit
fi
ficheros="bin envs arduinos.py generador_json funciones registrador desinstalar"
# Dependencias
echo "1. Instalando dependencias
"
apt update && apt install -y python3-pip jsonlint jq uuid
pip3 install pyserial
echo ""
# Directorio de instalación
echo "2. Creando directorios y copiando archivos"
echo "
Creación de directorios
"
mkdir -vp $registros_corruptos
mkdir -v $historicos
mkdir -v $registros
mkdir -v $key_dir
echo "
Copiado de archivos
"
cp -vr $ficheros $directorio_instalacion
cp -v $configuracion /etc/nodemecu.conf
echo "
Enlaces a binarios
"
chmod 755 $directorio_instalacion/bin/nodemecu
ln -vs $directorio_instalacion/bin/nodemecu /usr/bin/nodemecu
echo "
Fichero de logs
"
touch $log
ls $log
echo "3. Configurando systemd
"
cp -v nodemecu.service /lib/systemd/system/
systemctl daemon-reload
echo "
4. Obteniendo numero de serie
"
sn=$(cat /proc/cpuinfo | grep Serial | cut -d ' ' -f 2)
sed -i 's/numero_serie=/numero_serie='$sn'/' $directorio_instalacion/envs
echo "Número de serie: $sn"
echo "
5. Configurar
"
echo "- Ejecute 'sudo nodemecu configurar' para comenzar.
"
echo "- Ejecute 'sudo nodemecu modo sensores' para obtener datos desde sensores.
"
echo "- Ejecute 'sudo nodemecu captura iniciar' para comenzar a tomar datos de sensores o datos de prueba.
"
echo "- Ejecute 'sudo systemctl start nodemecu.service' para iniciar el envío de datos.
"

View file

@ -1,4 +0,0 @@
nombre=
servidor=
intervalo=
modo=test

View file

@ -1,80 +0,0 @@
#!/bin/bash
#set -x
source /etc/nodemecu.conf
source /opt/nodemecu/envs
source $funciones
while :;do
# archivo a procesar
file=$(get_stack)
# si no hay nada que procesar reinicia el bucle
test -z $file && funcion_espera && continue
# si no hay servidor definido se reinicia el bucle
test -z $servidor && echo "No se configuró nigun servidor de entrega." && funcion_espera && continue
# si no hay internet reinica el bucle
if ! funcion_verificar_internet; then
err_time=$(date +%Y-%m-%d-%H:%M:%S)
echo "$err_time - Parece no haber internet." | tee -a $log
funcion_espera
continue
fi
# si el fichero 'lock' existe (se esta creando un nuevo registro) reinicia el bucle
test -f $lock && continue
# validación del fichero
if ! funcion_validador_json "$(cat $registros/$file)";then
mv $registros/$file $registros_corruptos
continue
fi
# firmado de regisro
firma=$(sign_file $registros/$file)
# UUID del registro a enviar
uuid_registro=$(jq -r '."transaction_uuid"' $registros/$file)
# envio de registro
transaccion=$(curl -v -s --show-error -w "~%{http_code}" -X POST -H "X-Signature: $(sign_file $registros/$file)" -H "Content-Type: application/json" -d @$registros/$file $servidor 2> $curl_err)
# respuestas del servidor
respuesta_servidor="$(echo $transaccion | cut -d '~' -f 1)"
error_servidor="$(echo $transaccion | cut -d '~' -f 2)"
if [ ${#respuesta_servidor} -eq 36 ] && [ "$uuid_registro" == "$respuesta_servidor" ]; then
echo -e "$respuesta_servidor: \e[92mOK\e[0m"
mv $registros/$file $registros/$file.sig $historicos
else
err_time=$(date +%Y-%m-%d-%H:%M:%S)
srv_msg="$(echo $respuesta_servidor | grep -o '<body.*>.*</body>')"
echo -e "$err_time - $uuid_registro: \e[91mFAIL\e[0m"
echo "$err_time - $uuid_registro - Error del servidor: $error_servidor" >> $log
echo "$err_time - $uuid_registro - Mensaje del servidor:" >> $log
echo "$srv_msg" >> $log
if [ -s $curl_err ];then
echo "$err_time - $uuid_registro - Salida de curl:" >> $log
cat $curl_err >> $log
fi
rm $curl_err
#funcion_espera
fi
#exit
done
######
# se testea que el servidor responda
#test_url="$(curl -s -X POST -o /dev/null -w "%{http_code}" $servidor)"
#if [ $test_url -eq 404 ];then
# echo "$(date +%Y-%m-%d-%H:%M:%S) - $url - $test_url" >> /opt/nodemecu/errors.log && sleep 300 && continue
#fi

47
register.sh Executable file
View file

@ -0,0 +1,47 @@
#!/bin/bash
#set -e
source /etc/nodemecu.conf
source $install_dir/functions
# No expandir directorios vacíos
shopt -s nullglob
# Revisando stack
for filename in $install_dir/stack/*;do
$json_linter $filename >/dev/null 2>&1 || mv -v $filename $corrupt
done
while :;do
[ -f $install_dir/stop ] && break
[ -f $install_dir/lock ] && continue
file=$(get_stack)
[ -z $file ] && sleep ${interval:-1}m && continue
ping -c 1 fsf.org > /dev/null 2>&1 || continue
test_url="$(curl -s -X POST -o /dev/null -w "%{http_code}" $url)"
if [ $test_url -ne 200 ];then
echo "$(date +%Y-%m-%d-%H:%M:%S) - $url - $test_url" >> $log && sleep 300 && continue
fi
file="$stack/$file"
local_transaction_uuid="$(echo "$file" | cut -d - -f 2-)"
remote_transaction=$(curl -s --connect-timeout 1 --show-error -w "~%{http_code}" -X POST -H "Content-Type: application/json" -d @$file $url 2> $curl_err)
remote_response="$(echo $remote_transaction | cut -d '~' -f 1)"
server_error="$(echo $remote_transaction | cut -d '~' -f 2)"
if [ "$local_transaction_uuid" = "$remote_response" ]; then
mv $file $historical
echo -e "$remote_response: \e[92mOK\e[0m"
else
mv $file $failed
echo -e "$local_transaction_uuid: \e[91mFAIL\e[0m"
# errores
unset srv_msg
unset curl_msg
[ ! -z "$remote_response" ] && srv_msg="- $( echo $remote_response | grep -o '<body.*>.*</body>')"
[ -s "$curl_err" ] && curl_msg="- $(<$curl_err)"
echo $(date +%Y-%m-%d-%H:%M:%S) - $local_transaction_uuid - server status: $server_error $srv_msg $curl_msg >> $log
fi
done

13
uninstall.sh Executable file
View file

@ -0,0 +1,13 @@
#!/bin/bash
sudo rm /etc/nodemecu.conf
sudo rm /usr/bin/nodemecu
sudo crontab -u root -r
sudo rm -rf /opt/nodemecu/
sed -i '/*sudo nodemecu*/d' $HOME/.bashrc
sudo rm /lib/systemd/system/nodemecu.service
sudo systemctl stop nodemecu.service
sudo systemctl disable nodemecu.service
sudo systemctl daemon-reload