Versión Inicial

This commit is contained in:
2025-04-08 18:38:27 +02:00
parent 661c1a69af
commit 58b7e6ebae
6 changed files with 546 additions and 0 deletions

96
libs/api.js Normal file
View File

@@ -0,0 +1,96 @@
// Importamos las utilidades que necesitemos y la configuración del programa
import { sleep } from './utils.js';
import config from '../config.js';
// Creamos una lista de elementos que contendrá las peticiones acumuladas para enviarlas de golpe
const peticionesRetrasadas = [];
/**
* Añade el dato a la lista de peticiones en el formato que necesita la api
* @param {object} datos Objeto con los datos a subir
*/
async function subirDato(datos) {
if (datos === null || datos === undefined) {
return;
}
const datosParaEnviar = {
created_at: datos.datetime,
delta_t: 1,
field1: datos.paquetes,
field2: datos.temperatura,
field3: datos.presion,
field4: datos.altitudSegunPresion,
latitude: datos.latitud,
longitude: datos.longitud
};
//console.log(datosParaEnviar);
peticionesRetrasadas.push(datosParaEnviar);
}
/**
* Sube los datos de golpe al ThingSpeak
* @param {Array} datosParaSubir Array de objetos con los datos a subir
* @returns {Promise<boolean>} True si se subieron los datos correctamente, false si no
*/
async function subirDatosDeGolpe(datosParaSubir) {
//console.log("Subiendo datos de golpe...");
// Si no hay datos, no subimos nada
if(datosParaSubir.length === 0) {
return false;
}
// Preparamos los datos para subir añadiendo la apiKey
const datosParaEnviar = {
write_api_key: config.thingSpeak.writeKey,
updates: datosParaSubir
}
//console.log(datosParaEnviar);
// Hacemos la petición a la API de ThingSpeak
let resultado = false;
await fetch(`https://api.thingspeak.com/channels/${config.thingSpeak.channelId}/bulk_update.json`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(datosParaEnviar) // Convertimos el objeto a JSON para enviarlo
})
.then(response => response.json())
.then(data => {
//console.log(data);
resultado = true;
})
.catch(error => {
console.error('Error al subir los datos:', error);
})
return resultado;
}
async function bucleSubidaDatos() {
while(true) {
await sleep(20000);
console.log("Lista por subir: " + peticionesRetrasadas.length);
const datosQueSeVanASubir = JSON.parse(JSON.stringify(peticionesRetrasadas))
if (await subirDatosDeGolpe(datosQueSeVanASubir)) { // Con eso creamos una copia de los datos del array
if (peticionesRetrasadas.length == datosQueSeVanASubir.length) {
peticionesRetrasadas.length = 0;
} else {
peticionesRetrasadas.splice(0, datosQueSeVanASubir.length);
//console.log("Datos que se hubieran perdido: " + peticionesRetrasadas)
}
}
}
}
export {
subirDato
}
bucleSubidaDatos();

51
libs/utils.js Normal file
View File

@@ -0,0 +1,51 @@
/**
* Convierte una línea de datos en un objeto
* @param {string} line Línea de datos para convertir a objeto
* @returns {object} Objeto con los datos convertidos
*/
function dataLineToObject(line) {
//Separamos nuestra línea en diferentes trozos usando como separador el ';'
const lineArray = line.split(";");
//Devolvemos un objeto con sus propiedades convertidas
//Usamos el trim() para eliminar los espacios delante y detrás de los valores
//Usamos el parseFloat para convertir esos valores a decimales, ya que son cadenas de texto
//Usamos el parseInt para convertir esos valores a enteros, ya que son cadenas de texto
try {
return {
paquetes: parseInt(lineArray[0].trim()),
temperatura: parseFloat(lineArray[1].trim()),
presion: parseFloat(lineArray[2].trim()),
altitudSegunPresion: parseFloat(lineArray[3].trim()),
nombreEstacion: lineArray[4].trim(),
latitud: parseFloat(lineArray[5].trim()),
longitud: parseFloat(lineArray[6].trim()),
altitudMetros: parseFloat(lineArray[7].trim()),
velocidadKmph: parseFloat(lineArray[8].trim()),
direccionONose: parseFloat(lineArray[9].trim()),
numSatelites: parseInt(lineArray[10].trim()),
datetime: new Date(lineArray[11].trim().replace("Date/Time: ", ""))
};
} catch (error) {
console.error('Error al convertir los datos:', error);
return null;
}
}
/**
* Espera un cierto tiempo, esto sirve para crear temporizadores
* @param {number} ms Milisegundos que hay que esperar
* @returns {Promise<void>}
*/
async function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
// Exportamos las funciones para poder usarlas en otras partes del programa
export {
dataLineToObject,
sleep
}