สารบัญ:

BBQ Pi (พร้อมการแสดงภาพข้อมูล!): 4 ขั้นตอน (พร้อมรูปภาพ)
BBQ Pi (พร้อมการแสดงภาพข้อมูล!): 4 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: BBQ Pi (พร้อมการแสดงภาพข้อมูล!): 4 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: BBQ Pi (พร้อมการแสดงภาพข้อมูล!): 4 ขั้นตอน (พร้อมรูปภาพ)
วีดีโอ: เบื้องหลังวันพากย์เสียงอุตะในหนังเรื่อง One Piece Film Red 2024, พฤศจิกายน
Anonim
BBQ Pi (พร้อมการแสดงข้อมูล!)
BBQ Pi (พร้อมการแสดงข้อมูล!)
BBQ Pi (ด้วยการแสดงข้อมูล!)
BBQ Pi (ด้วยการแสดงข้อมูล!)
BBQ Pi (ด้วยการแสดงข้อมูล!)
BBQ Pi (ด้วยการแสดงข้อมูล!)

บทนำ

การย่างบาร์บีคิวโดยส่วนใหญ่หมายถึงกระบวนการที่ช้าของการใช้ความร้อนทางอ้อมในการปรุงอาหารเนื้อสัตว์ที่คุณโปรดปราน แม้ว่าวิธีการทำอาหารนี้จะได้รับความนิยมอย่างมหาศาล โดยเฉพาะอย่างยิ่งในสหรัฐอเมริกา แต่ก็มีสิ่งที่บางคนอาจมองว่าเป็นจุดอ่อนที่ค่อนข้างร้ายแรง แต่ต้องใช้เวลาหลายชั่วโมงในการสังเกตอุณหภูมิของหลุมและอาหารของคุณ ใส่: Raspberry Pi

โครงการเดิม

แหล่งที่มาดั้งเดิมของโครงการนี้สามารถพบได้ที่นี่: https://old.reddit.com/r/raspberry_pi/comments/a0… สาระสำคัญคือผู้ใช้ reddit Produkt สามารถถ่ายทอดข้อมูลอุณหภูมิอาหารและอุณหภูมิหลุมจากราคาที่ค่อนข้างถูก เทอร์โมมิเตอร์แบบไร้สายที่มีจำหน่ายทั่วไปใน Raspberry Pi (ซึ่งติดอยู่กับหมุด GPIO ของมันจะมีโมดูล RF ขนาดเล็ก) ในโครงการดั้งเดิม (ลิงก์ด้านบน) Produkt ได้เก็บข้อมูลของเขาไว้ในฐานข้อมูล sqlite และแสดงบนเว็บไซต์ php ของ apache2 ที่โฮสต์ในเครื่อง

วิธีแก้ปัญหานี้ช่วยแก้ปัญหาเดิมที่กล่าวถึงในการแนะนำบล็อกนี้แล้ว: ตอนนี้คุณสามารถตรวจสอบอุณหภูมิอาหารและหลุมได้จากระยะไกลด้วยเว็บเบราว์เซอร์ แต่ถ้าเราอยากจะขยายความในเรื่องนี้ล่ะ? ป้อน: GridDB

เสบียง

ราสเบอร์รี่ Pi4

SUNKEE 433Mhz โมดูลรับสัญญาณไร้สาย Superheterodyne

ขั้นตอนที่ 1: GridDB Web API & FluentD

GridDB เว็บ API และ FluentD
GridDB เว็บ API และ FluentD

เมื่อเห็นโปรเจ็กต์นี้ ความคิดแรกของฉัน - หลังจากคลื่นแห่งความตื่นเต้นครั้งแรก - กำลังคิดถึงวิธีที่ฉันขยายฟังก์ชันการทำงาน ด้วยการใช้ GridDB และปลั๊กอิน Grafana ฉันพยายามที่จะเห็นภาพข้อมูลอาหารและหลุมของฉัน ยิ่งไปกว่านั้น ฉันต้องการตั้งค่าคำอธิบายประกอบของ Grafana เพื่อค้นหาจุดข้อมูลที่ผิดปกติ - ไม่สามารถมีเนื้อไหม้เกรียมได้!

ในการเริ่มต้น ฉันต้องใช้รหัส C จากโครงการเดิมเพื่ออ่านข้อมูลที่มาจากเทอร์โมมิเตอร์แบบไร้สายและโพสต์ข้อมูลนั้นลงในเซิร์ฟเวอร์ GridDB ของฉัน ในการทำให้ใช้งานได้ ฉันจึงสร้างเซิร์ฟเวอร์ GridDB บน Azure โดยใช้เครื่องเสมือน CentOS วิธีที่ง่ายที่สุดในการแบ่งปันข้อมูลจาก Edge Machine (Raspberry Pi) ไปยังเซิร์ฟเวอร์คลาวด์ของเราคือผ่าน GridDB Web API ดังนั้น บน vm นั้น ฉันตั้งค่า WebAPI ของ GridDB พร้อมกับ Fluentd และตัวเชื่อมต่อ GridDB ที่มาพร้อมกัน

ก่อนที่จะส่งข้อมูลไปยังคลาวด์ ฉันต้องสร้างสคีมาพื้นฐานสำหรับคอนเทนเนอร์ BBQ Pi ชุดข้อมูลที่เข้ามานั้นง่ายมาก: เรามีเซ็นเซอร์อุณหภูมิสองตัว รหัสปรุงอาหารหนึ่งรหัส และแน่นอนว่ามีการประทับเวลา สคีมาของเราจึงมีลักษณะดังนี้:

อนุกรมเวลา = gridstore.put_container("bbqpi", [("เวลา", griddb. GS_TYPE_TIMESTAMP), ("cookid", griddb. GS_TYPE_INT), ("probe1", griddb. GS_TYPE_INT), ("probe2", griddb. GS_TYPE_INT)], griddb. GS_CONTAINER_TIME_SERIES)

ในการสร้างคอนเทนเนอร์อนุกรมเวลานี้ ฉันเพียงแค่ใช้ WebAPI (พอร์ต 8080):

curl -X POST --basic -u admin:admin -H "Content-type:application/json" -d

'{"container_name":"bbqpi", "container_type":"TIME_SERIES", / "rowkey":true, "columns":[ {"name": "time", "type": "TIMESTAMP" }, {"name": "cookid", "type": "INTEGER" }, {"name": "probe1", "type": "INTEGER" }, {"name": "probe2", "type": "จำนวนเต็ม" }]}'

เมื่อสร้างคอนเทนเนอร์แล้ว ฉันจำเป็นต้องใช้ Fluentd (พอร์ต 8888) เพื่อโพสต์ข้อมูลจริงลงในคอนเทนเนอร์ของเรา นี่คือคำสั่ง CURL ที่โพสต์ข้อมูลจำลอง:

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

จากนั้น ฉันต้องต่อท้ายโค้ดเดิมเพื่อส่งคำขอ HTTP POST เมื่อใดก็ตามที่ Pi ของเราอ่านข้อมูลจากพิทของเรา (ประมาณทุกๆ 12 วินาที)

หมายเหตุด้านข้าง: การเขียนโค้ดนี้สอนให้ฉันซาบซึ้งว่าภาษา C ละเอียดเพียงใด:

int postData (เวลาถ่าน, int cookid, int probe1, int probe2, ถ่าน url)

{ หยิก * ขด; CURLcode res; /* ใน windows สิ่งนี้จะเริ่มต้นสิ่ง winsock */ curl_global_init(CURL_GLOBAL_ALL); ถ่าน errbuf[CURL_ERROR_SIZE] = { 0, }; ตัวแทนถ่าน [1024] = { 0, }; ถ่าน json[1000]; snprintf(json, 200, "json={"date\":\"%s.112Z\", \"cookid\":\"%d\", \"probe1\":\"%d\", \"probe2\":\"%d\"}", เวลา, cookid, probe1, probe2); /* รับ curl handle */ curl = curl_easy_init(); if(curl) { /* ตั้งค่า URL ที่กำลังจะรับ POST ของเราก่อน URL นี้สามารถเป็น https:// URL ได้เช่นกัน หากนั่นคือสิ่งที่ควรได้รับข้อมูล */ snprintf(agent, sizeof agent, "libcurl/%s", curl_version_info(CURLVERSION_NOW)->version); ตัวแทน[ขนาดตัวแทน - 1] = 0; curl_easy_setopt(curl, CURLOPT_USERAGENT, ตัวแทน); curl_easy_setopt(ขด, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_USERNAME, "ผู้ดูแลระบบ"); curl_easy_setopt(curl, CURLOPT_PASSWORD, "ผู้ดูแลระบบ"); curl_easy_setopt(ขด, CURLOPT_VERBOSE, 1L); curl_easy_setopt (ขด, CURLOPT_ERRORBUFFER, errbuf); curl_easy_setopt (ขด, CURLOPT_POSTFIELDS, json); /* ดำเนินการตามคำขอ res จะได้รับโค้ดส่งคืน */ res = curl_easy_perform(curl); ถ้า (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)); ไปทำความสะอาด; } การล้างข้อมูล: curl_easy_cleanup(curl); curl_global_cleanup(); กลับ 0; } }

เมื่อเขียนฟังก์ชันนี้ ฉันแค่ต้องการให้มันทำงานพร้อมๆ กับที่มีการโพสต์ข้อมูล sqlite:

ถ้า (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);", รหัสคุก, บัฟ, โพรบ1, โพรบ2); printf("%s\n", sql); rc=sqlite3_exec(db, sql, โทรกลับ, 0, &zErrMsg); ถ้า (rc!=SQLITE_OK) { printf ("ข้อผิดพลาดของ SQL: %s\n", zErrMsg); } อื่น ๆ { last_db_write=secs; } char url = "https://xx.xx.xx.xx:8888/griddb"; postData(บัฟ, รหัสคุก, โพรบ1, โพรบ2, url); } }

เพื่อให้แน่ใจว่าข้อมูลของคุณถูกแทรกลงในเซิร์ฟเวอร์ของคุณจริงๆ คุณสามารถเรียกใช้คำสั่งต่อไปนี้เพื่อสอบถามฐานข้อมูลของคุณและดูผลลัพธ์:

curl -X POST --basic -u admin:admin -H "Content-type:application/json" -d '{"limit":1000}' https://localhost:8080/griddb/v2/defaultCluster/dbs/ สาธารณะ/คอนเทนเนอร์/bbqpi/แถว

ขั้นตอนที่ 2: Grafana

กราฟานา
กราฟานา
กราฟานา
กราฟานา

ด้วยรหัสที่มีอยู่ ตอนนี้เมื่อเราใช้เว็บพอร์ทัลดั้งเดิมเพื่อเริ่ม "ทำอาหาร" เราจะจัดเก็บข้อมูลอุณหภูมิของเราลงในเซิร์ฟเวอร์ GridDB ของเราพร้อม ๆ กัน

ขั้นตอนต่อไปคือการแสดงภาพข้อมูลของเราโดยใช้ Grafana โดยเราได้ติดตามข้อมูลจากบล็อกนี้: ที่นี่ สิ่งที่ดีเกี่ยวกับการใช้งานนี้คือ ง่ายมากที่จะเห็นข้อมูลของเราสร้างแผนภูมิเป็นกราฟที่ดี นอกจากนี้ยังเพิ่มคำอธิบายประกอบ

คำอธิบายประกอบที่กล่าวถึงในบล็อกช่วยให้เราตรวจสอบได้ง่ายมากเมื่อมีสิ่งผิดปกติเกิดขึ้นกับอาหารของเราหรือตัวอาหารเอง ในกรณีของฉัน ฉันกำลังปรุงเนื้อซี่โครงสั้น ฉันไม่ต้องการให้อุณหภูมิในหลุมเพิ่มขึ้นเกิน 275 องศาฟาเรนไฮต์ หากฉันเห็นอุณหภูมิเกินกว่านั้น ฉันสามารถปิดเตาและปล่อยให้ความร้อนลดลงอีกครั้ง:

ฉันมีกฎที่คล้ายคลึงกันสำหรับเซ็นเซอร์ที่จะคอยจับตาดูตัวอาหารเอง: ถ้าอาหารมีอุณหภูมิภายใน 203 องศาฟาเรนไฮต์ ซี่โครงก็พร้อมแล้ว คุณสามารถดูคำอธิบายประกอบที่ส่วนท้ายของพ่อครัวได้ที่นี่:

โดยรวมแล้ว พ่อครัวใช้เวลาเพียงประมาณ 4 ชั่วโมงหรือมากกว่านั้น แต่การตั้งค่าแบบนี้จะยอดเยี่ยมจริงๆ ถ้าฉันทำอาหารบางอย่างที่อาจต้องใช้เวลามากขึ้นในเตาย่าง (ลองนึกถึงควันไฟต่ำที่คงอยู่นาน ~12 ชั่วโมง). แม้จะเป็นเช่นนั้น ฉันเชื่อว่ามีประโยชน์หากเครื่องมือนี้มองเห็นได้ง่าย: ความสามารถในการบันทึกผลลัพธ์ของอาหารแล้วเปรียบเทียบกับพ่อครัวคนก่อน ๆ หมายความว่าการย่างบาร์บีคิวของคุณจะค่อยๆ ดีขึ้นเมื่อเวลาผ่านไป เนื่องจากคุณสามารถใช้ข้อมูลเพื่อดูว่าอะไรได้ผลและอะไรไม่ได้ผล 'NS.

ขั้นตอนที่ 3: อาหาร

อาหาร
อาหาร
อาหาร
อาหาร
อาหาร
อาหาร

นี่เป็นครั้งแรกที่ฉันเคยทำซี่โครงสั้นเนื้อ สำหรับปรุงรส ฉันแค่ใช้เกลือ พริกไทยดำ และผงกระเทียม แม้จะมีปัญหาบางอย่างที่หัวเตาจะสูงเกินไปสำหรับช่วงเริ่มต้นเล็กน้อย แต่ซี่โครงก็ออกมาได้อย่างยอดเยี่ยม โปรดดู:

ขั้นตอนที่ 4: บทสรุป

ในที่สุด อาหารก็ออกมาได้อย่างยอดเยี่ยม เซ็นเซอร์ GridDB และ Grafana ทำงานร่วมกันได้อย่างสวยงาม และเราได้รับข้อมูลอันมีค่าเกี่ยวกับวิธีการปรุงอาหารเหล่านี้อีกครั้งในครั้งหน้าที่เราอยากจะสร้างความประทับใจให้เพื่อนๆ

แนะนำ: