Tabla de contenido:

BBQ Pi (¡con visualización de datos!): 4 pasos (con imágenes)
BBQ Pi (¡con visualización de datos!): 4 pasos (con imágenes)

Video: BBQ Pi (¡con visualización de datos!): 4 pasos (con imágenes)

Video: BBQ Pi (¡con visualización de datos!): 4 pasos (con imágenes)
Video: 12) Raspberry PI 4 y Python3 desde Cero - Comunicación Serial, Integración con Arduino 2024, Noviembre
Anonim
BBQ Pi (¡con visualización de datos!)
BBQ Pi (¡con visualización de datos!)
BBQ Pi (¡con visualización de datos!)
BBQ Pi (¡con visualización de datos!)
BBQ Pi (¡con visualización de datos!)
BBQ Pi (¡con visualización de datos!)

Introducción

Asar a la parrilla generalmente se refiere al proceso lento de usar calor indirecto para cocinar sus carnes favoritas. Aunque este método de cocción es muy popular, especialmente en los EE. UU., Tiene lo que algunos pueden considerar una debilidad bastante grave: requiere horas de atención semi-lúcida para monitorear la temperatura de su hoyo y comida. Ingrese: Raspberry Pi.

El proyecto original

La fuente original de este proyecto se puede encontrar aquí: https://old.reddit.com/r/raspberry_pi/comments/a0… La esencia de esto es que el usuario de reddit Produkt pudo transmitir datos de temperatura de los alimentos y del pozo desde relativamente baratos, termómetros inalámbricos disponibles comercialmente a una Raspberry Pi (que tenía conectado a sus pines GPIO un pequeño módulo de RF). En el proyecto original (vinculado arriba), Produkt tenía sus datos almacenados en una base de datos sqlite y mostrados en un sitio web apache2 php alojado localmente.

Esta solución ya resuelve el problema original que se mencionó en la introducción de este blog: ahora puede controlar la temperatura de los alimentos y el hoyo de forma remota con un navegador web. Pero, ¿y si quisiéramos ampliar esto? Ingrese: GridDB.

Suministros

Frambuesa Pi4

Módulo receptor inalámbrico superheterodino SUNKEE 433Mhz

Paso 1: API web GridDB y FluentD

API web GridDB y FluentD
API web GridDB y FluentD

Al ver este proyecto, mi primer pensamiento, después de la ola inicial de entusiasmo, fue pensar en las formas en que puedo extender la funcionalidad. Al usar GridDB y su complemento Grafana, busqué visualizar mis datos de comida y pozo. Más allá de eso, deseaba configurar anotaciones de Grafana para buscar puntos de datos anómalos: ¡no puedo tener carne quemada!

Para comenzar, necesitaba usar el código C del proyecto original para leer los datos provenientes del termómetro inalámbrico y publicar esos datos en mi servidor GridDB. Para que esto funcione, puse en marcha un servidor GridDB en Azure usando una máquina virtual CentOS. La forma más fácil de compartir datos desde nuestra máquina perimetral (Raspberry Pi) a nuestro servidor en la nube fue a través de la API web GridDB. Entonces, en esa máquina virtual, configuré la WebAPI de GridDB junto con Fluentd y el conector GridDB que lo acompaña.

Antes de enviar datos a la nube, necesitaba crear el esquema básico para mi contenedor BBQ Pi. El conjunto de datos que ingresa es extremadamente simple: tenemos dos sensores de temperatura, una identificación de cocción y, por supuesto, la marca de tiempo. Entonces nuestro esquema se ve así:

timeseries = gridstore.put_container ("bbqpi", [("tiempo", griddb. GS_TYPE_TIMESTAMP), ("cookid", griddb. GS_TYPE_INT), ("probe1", griddb. GS_TYPE_INT), ("probe2", griddb. GS_TYPE_INT)], griddb. GS_CONTAINERIES_TIME_SS

Para crear este contenedor de series temporales, simplemente utilicé WebAPI (puerto 8080):

curl -X POST --basic -u admin: admin -H "Tipo de contenido: aplicación / json" -d

'{"container_name": "bbqpi", "container_type": "TIME_SERIES", / "rowkey": verdadero, "columnas": [{"name": "time", "type": "TIMESTAMP"}, {"nombre": "cookid", "tipo": "INTEGER"}, {"nombre": "sonda1", "tipo": "INTEGER"}, {"nombre": "sonda2", "tipo": "INTEGER"}]} '\ https:// localhost: 8080 / griddb / v2 / defaultCluster / dbs / public / containers

Con el contenedor creado, necesitaba utilizar Fluentd (puerto 8888) para publicar datos reales en nuestro contenedor. Aquí hay un comando CURL que publica algunos datos ficticios:

curl -X POST -d 'json = {"date": "2020-01-01T12: 08: 21.112Z", "cookid": "1", "probe1": "150", "probe2": "140" } 'https:// localhost: 8888 / griddb

A partir de ahí, necesitaba agregar el código original para enviar una solicitud POST HTTP cada vez que nuestro Pi estaba leyendo datos de nuestro pozo (aproximadamente una vez cada ~ 12 segundos).

Como nota al margen: escribir este código me enseñó a apreciar cuán detallado puede ser el lenguaje C:

int postData (char time , int cookid, int probe1, int probe2, char url )

{CURL * curl; CURLcode res; / * En Windows, esto iniciará las cosas de winsock * / curl_global_init (CURL_GLOBAL_ALL); char errbuf [CURL_ERROR_SIZE] = {0,}; char agent [1024] = {0,}; char json [1000]; snprintf (json, 200, "json = {" fecha / ": \"% s.112Z / ", \" cookid / ": \"% d / ", \" probe1 / ": \"% d / ", / "probe2 \": / "% d \"} ", hora, cookid, probe1, probe2); / * obtener un identificador de curl * / curl = curl_easy_init (); if (curl) {/ * Primero configure la URL que está a punto de recibir nuestro POST. Esta URL también puede ser una URL https:// si eso es lo que debería recibir los datos. * / snprintf (agente, tamaño del agente, "libcurl /% s", curl_version_info (CURLVERSION_NOW) -> versión); agente [tamaño del agente - 1] = 0; curl_easy_setopt (curl, CURLOPT_USERAGENT, agente); curl_easy_setopt (curl, CURLOPT_URL, url); curl_easy_setopt (curl, CURLOPT_USERNAME, "admin"); curl_easy_setopt (curl, CURLOPT_PASSWORD, "admin"); curl_easy_setopt (rizo, CURLOPT_VERBOSE, 1L); curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, errbuf); curl_easy_setopt (curl, CURLOPT_POSTFIELDS, json); / * Realice la solicitud, res obtendrá el código de retorno * / res = curl_easy_perform (curl); if (res! = CURLE_OK) {size_t len = strlen (errbuf); fprintf (stderr, "\ nlibcurl: (% d)", res); if (len) fprintf (stderr, "% s% s", errbuf, ((errbuf [len - 1]! = '\ n')? "\ n": "")); fprintf (stderr, "% s / n / n", curl_easy_strerror (res)); ir a la limpieza; } limpieza: curl_easy_cleanup (curl); curl_global_cleanup (); return 0; }}

Con esta función escrita, solo necesitaba ejecutarla al mismo tiempo que se publicaban los datos de sqlite:

if (goodData == 1) {

if (last_db_write == 0 || (secs-last_db_write> = 10)) {snprintf (sql, 100, "INSERT INTO readings (cookid, time, probe1, probe2) VALUES (% d, '% s',% d, % d); ", cookID, buff, probe1, probe2); printf ("% s / n", sql); rc = sqlite3_exec (db, sql, devolución de llamada, 0, & zErrMsg); if (rc! = SQLITE_OK) {printf ("Error SQL:% s / n", zErrMsg); } más {last_db_write = segundos; } char url = "https://xx.xx.xx.xx: 8888 / griddb"; postData (buff, cookID, probe1, probe2, url); }}

Para asegurarse de que sus datos se estén insertando realmente en su servidor, puede ejecutar el siguiente comando para consultar su base de datos y ver los resultados:

curl -X POST --basic -u admin: admin -H "Tipo de contenido: aplicación / json" -d '{"límite": 1000}' https:// localhost: 8080 / griddb / v2 / defaultCluster / dbs / público / contenedores / bbqpi / filas

Paso 2: Grafana

Grafana
Grafana
Grafana
Grafana

Con el código en su lugar, ahora que usemos el portal web original para iniciar una "cocción", almacenaremos simultáneamente nuestros datos de temperatura en nuestro servidor GridDB.

El siguiente paso será visualizar nuestros datos usando Grafana. Para ello, seguimos la información de este blog: aquí. Lo bueno de esta implementación es que es extremadamente fácil ver nuestros datos en un gráfico agradable. También agrega anotaciones.

Las anotaciones discutidas en el blog hacen que sea extremadamente fácil para nosotros monitorear cuando algo sale mal, ya sea con nuestra comida o con el pozo mismo. En mi caso, estaba cocinando costillitas de ternera. Con esos, no quería que la temperatura en el pozo aumentara más allá de los 275 grados Fahrenheit. Si vi que la temperatura iba más allá de eso, podría apagar un quemador y permitir que el calor baje nuevamente:

Tenía una regla similar para que el sensor controlara la comida en sí: si la comida alcanzaba una temperatura interna de 203 grados Fahrenheit, las costillas estaban listas. Puedes ver la anotación solitaria al final del cocinero aquí:

En general, el cocinero solo me tomó alrededor de ~ 4 horas más o menos, pero este tipo de configuración realmente sobresaliría si estuviera cocinando algo que hubiera requerido aún más tiempo en la parrilla (piense en un humo lento y lento que dura ~ 12 horas). A pesar de eso, creo que el valor de esta herramienta es fácilmente evidente: poder registrar los resultados de sus alimentos y luego compararlos con cocineros anteriores significa que su barbacoa mejorará lentamente con el tiempo, ya que puede usar datos para ver qué funciona y qué no. 't.

Paso 3: la comida

Los alimentos
Los alimentos
Los alimentos
Los alimentos
Los alimentos
Los alimentos

Esta fue la primera vez que hice costillas de ternera; para condimentar, simplemente usé sal, pimienta negra y ajo en polvo. A pesar de algunos problemas con el quemador demasiado alto al principio, las costillas salieron fantásticas. Por favor echa un vistazo:

Paso 4: Conclusión

Al final, la comida salió estupenda, los sensores, GridDB y Grafana funcionaron a la perfección, y obtuvimos algunos datos valiosos sobre cómo cocinar estas cosas nuevamente para la próxima vez que queramos impresionar a algunos amigos.

Recomendado: