Brandon Engineer

Shopping cart

Subtotal 0,00 

View cartCheckout

Como guardar y visualizar datos en base de datos GRATIS

  • Home
  • Dashboard
  • Como guardar y visualizar datos en base de datos GRATIS
Brandon%20Engineer

Introducción

Hace poco una persona tenia dudas de como almacenar datos del consumo de la red en una base de datos y yo le comentaba que se puede hacer con costes muy reducidos o incluso gratuitos

Hardware

Para este ejercicio práctico se usará un dispositivo de domótica por su reducido coste

blank

https://amzn.to/3CjvGMA

Si necesitas varios siempre puedes comprar un pack para ahorrar dinero:

https://amzn.to/3Oq3VoF

Para la inserción en base de datos usaremos un servidor en red con linux aunque yo recomiendo un IPC con procesador ARM por tener diversificado las funciones de cada dispositivo

Software

Como instalar Docker en ubuntu

Para la instalación del software empezaremos por instalar el gestor de contenedores de Docker en servidor linux basado en ubuntu

				
					sudo apt update
sudo apt upgrade
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt upgrade
sudo apt install docker-ce docker-ce-cli containerd.io

				
			

Por ultimo verificamos que esta instalado correctamente

				
					sudo docker --version
				
			

Como instalar Node Red en Docker

Para el software de inserción en base de datos instalaremos Node Red que es un software de open source que nos permitiré conectar con infinidad de protocolos de comunicación e insertar en base de datos

				
					docker run -d --name mynodered -p 1880:1880 --restart unless-stopped nodered/node-red

				
			

Una vez ya instalado podemos proceder a acceder a los datos que nos comparte el dispositivo de Tasmota con su servidor web en mi caso esta almacenada en esta dirección IP (se recomienda usar la guía de configuración de la conexión por wifi del dispositivo para configurarlo correctamente):

http://192.168.0.34

El cual nos dará la información sobre el enchufe:

blank

Para obtener los datos nos podemos dirigir a la siguiente:

http://192.168.0.34/cm?cmnd=STATUS%200

El cual podemos ver que esta toda la información en un JSON

				
					   "ENERGY": {
      "TotalStartTime": "2024-11-06T09:10:05",
      "Total": 1.058,
      "Yesterday": 0.268,
      "Today": 0.206,
      "Power": 0,
      "ApparentPower": 0,
      "ReactivePower": 0,
      "Factor": 0,
      "Voltage": 208,
      "Current": 0
    },
				
			

Ahora procederemos a programar la función ciclica que recopilará la información para insertarla en la base de datos para ello haremos lo siguiente:

-Añadimos nodo que se ejecuta cada 3 segundos

-Normalizamos la hora para poder insertarla en la base de datos

-Obtenemos los datos mediante una petición HTTP mediante el método «GET»

-Extraemos los datos que nos interesa del JSON

-Creamos la consulta con los datos extraídos

-Insertamos en nuestro servidor

-Mostramos en consola para comprobar que todo funciona correctamente

blank

				
					[
    {
        "id": "72594c6cf3e187c5",
        "type": "debug",
        "z": "a7cda68e269cad0e",
        "name": "debug 25",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 720,
        "y": 940,
        "wires": []
    },
    {
        "id": "e49938d64834e868",
        "type": "http request",
        "z": "a7cda68e269cad0e",
        "name": "",
        "method": "GET",
        "ret": "txt",
        "paytoqs": "ignore",
        "url": "http://192.168.0.34/cm?cmnd=STATUS%200",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "x": 530,
        "y": 880,
        "wires": [
            [
                "273d22936082a16a"
            ]
        ]
    },
    {
        "id": "7957f9fe99d9eee6",
        "type": "inject",
        "z": "a7cda68e269cad0e",
        "name": "",
        "props": [
            {
                "p": "date",
                "v": "iso",
                "vt": "date"
            }
        ],
        "repeat": "3",
        "crontab": "",
        "once": true,
        "onceDelay": "3",
        "topic": "",
        "x": 200,
        "y": 880,
        "wires": [
            [
                "23d3e98baab1ce6a"
            ]
        ]
    },
    {
        "id": "273d22936082a16a",
        "type": "function",
        "z": "a7cda68e269cad0e",
        "name": "Extraer datos del JSON",
        "func": "// Convierte msg.payload a string si no lo es\nvar payloadStr = msg.payload.toString();\n\n// Elimina espacios en blanco al inicio y al final\npayloadStr = payloadStr.trim();\n\n// Si el payload comienza y termina con comillas dobles, las elimina\nif (payloadStr.startsWith('\"') && payloadStr.endsWith('\"')) {\n    payloadStr = payloadStr.substring(1, payloadStr.length - 1);\n}\n\n// Reemplaza las comillas dobles escapadas por comillas dobles reales\npayloadStr = payloadStr.replace(/\\\\\"/g, '\"');\n\ntry {\n    // Parsea el string a objeto JSON\n    var payloadObj = JSON.parse(payloadStr);\n\n    // Verifica si existen los datos de ENERGY\n    if (payloadObj.StatusSNS && payloadObj.StatusSNS.ENERGY) {\n        // Asigna los valores de ENERGY al payload\n        msg.payload = payloadObj.StatusSNS.ENERGY;\n    } else {\n        node.error(\"No se encontró 'StatusSNS.ENERGY' en el payload\", msg);\n        return null;\n    }\n} catch (e) {\n    // Maneja errores de parseo\n    node.error(\"Error al parsear JSON: \" + e.message, msg);\n    return null;\n}\n\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 250,
        "y": 940,
        "wires": [
            [
                "456e7462c5d896e9"
            ]
        ]
    },
    {
        "id": "4086d7eafeeaf2bd",
        "type": "mysql-r2",
        "z": "a7cda68e269cad0e",
        "name": "",
        "host": "192.168.0.125",
        "database": "****",
        "username": "****",
        "password": "****",
        "sql": "",
        "port": "****",
        "pooling": false,
        "waitForConnections": true,
        "connectionLimit": "10",
        "queueTimeout": "10000",
        "x": 580,
        "y": 940,
        "wires": [
            [
                "72594c6cf3e187c5"
            ]
        ]
    },
    {
        "id": "456e7462c5d896e9",
        "type": "template",
        "z": "a7cda68e269cad0e",
        "name": "",
        "field": "sql",
        "fieldType": "msg",
        "format": "handlebars",
        "syntax": "mustache",
        "template": "INSERT INTO `Grafana`.`Consume` (`con_date`, `con_voltage`, `con_current`, `con_power`, `con_AppPower`, `con_ReactPower`, `con_PowerFactor`, `con_EnergyToday`) VALUES ('{{date}}', '{{payload.Voltage}}', {{payload.Current}}, {{payload.Power}}, {{payload.ApparentPower}}, {{payload.ReactivePower}}, {{payload.Factor}}, {{payload.Today}});",
        "output": "str",
        "x": 440,
        "y": 940,
        "wires": [
            [
                "4086d7eafeeaf2bd"
            ]
        ]
    },
    {
        "id": "23d3e98baab1ce6a",
        "type": "function",
        "z": "a7cda68e269cad0e",
        "name": "Normalizar hora",
        "func": "// Obtiene la fecha original de msg.date\nvar originalDate = msg.date;\n\n// Verifica si msg.date está definido\nif (!originalDate) {\n    node.error(\"msg.date no está definido.\", msg);\n    return null;\n}\n\n// Convierte la cadena de fecha a un objeto Date\nvar dateObj = new Date(originalDate);\n\n// Verifica si la fecha es válida\nif (isNaN(dateObj.getTime())) {\n    node.error(\"La fecha proporcionada no es válida: \" + originalDate, msg);\n    return null;\n}\n\n// Extrae los componentes de la fecha y hora en UTC\nvar year = dateObj.getUTCFullYear();\nvar month = ('0' + (dateObj.getUTCMonth() + 1)).slice(-2);\nvar day = ('0' + dateObj.getUTCDate()).slice(-2);\nvar hours = ('0' + dateObj.getUTCHours()).slice(-2);\nvar minutes = ('0' + dateObj.getUTCMinutes()).slice(-2);\nvar seconds = ('0' + dateObj.getUTCSeconds()).slice(-2);\n\n// Formatea la fecha al formato deseado\nmsg.date = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 360,
        "y": 880,
        "wires": [
            [
                "e49938d64834e868"
            ]
        ]
    }
]
				
			

Como instalar Grafana

Para la visualización utilizaremos Grafana el cual tiene una gran variedad de herramientas de visualización en mi caso hare que sea accesible por el puerto 1882

				
					docker run -d --name mygrafana -p 1882:3000 --restart unless-stopped grafana/grafana
				
			

Una vez listo yo recomiendo realizar las siguientes configuraciones para poder acceder a los gráficos sin tener que iniciar sesión cada vez que se arranque el visualizador

				
					docker exec -it -u root mygrafana /bin/sh
vi /etc/grafana/grafana.ini
				
			

Ahora habilitaremos la visualización de forma anonima modificando estas lineas:

				
					[auth.anonymous]
enabled = true
org_role = Viewer
				
			

Por último habilitaremos el uso de graficas en iframes

				
					[security]
allow_embedding = true
				
			

Una vez listo configuraremos nuestras gráficas como deseemos en mi caso tengo estas gráficas

blank

Como instalar FUXA

Para la instalación de Fuxa como SCADA de código abierto al tener ya instalado docker es tan sencillo como hacer una pull del repositorio de github y hacer que se autoarranque al iniciar el servidor

				
					docker run -d \
  --name fuxa \
  -p 1881:1881 \
  -v fuxa_appdata:/usr/src/app/FUXA/server/_appdata \
  -v fuxa_db:/usr/src/app/FUXA/server/_db \
  -v fuxa_logs:/usr/src/app/FUXA/server/_logs \
  -v fuxa_shapes:/usr/src/app/FUXA/client/assets/lib/svgeditor/shapes \
  -v fuxa_images:/usr/src/app/FUXA/server/_images \
  --restart unless-stopped \
  frangoteam/fuxa:latest

				
			

Ya tenemos listo ahora es tan facil como crear un proyecto usar el objeto «iFrame» de Fuxa y ya podemos empezar a visualizar los datos

Leave A Comment

Your email address will not be published. Required fields are marked *

en_USEnglish