Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

Dari Data ke Grafik:Perjalanan Web Dengan Flask dan SQLite

Menangkap data nyata (RPi/DHT22), menyimpannya dalam database (SQLite), membuat grafik (Matplotlib) dan menampilkannya di halaman web (Flask).

Pendahuluan:Dari Data ke Grafik. Web Jorney Dengan Flask dan SQLite

Pada tutorial saya sebelumnya, Python WebServer With Flask dan Raspberry Pi, kita belajar bagaimana berinteraksi dengan dunia fisik, melalui halaman front-end web, yang dibuat dengan Flask. Jadi, langkah alami berikutnya adalah mengumpulkan data dari dunia nyata, menyediakannya untuk kita di halaman web. Sangat sederhana! Tapi, apa jadinya jika kita ingin tahu seperti apa situasi sehari sebelumnya, misalnya? Atau membuat semacam analisis dengan data tersebut? Dalam kasus tersebut, kita juga harus menyimpan data dalam database.

Singkatnya, pada tutorial baru ini, kita akan:

Rekam data nyata (suhu udara dan kelembaban relatif) menggunakan sensor DHT22;Muat data tersebut di database local lokal , dibuat dengan SQLite; Buat grafik dengan data historis menggunakan Matplotlib; Menampilkan data dengan “pengukur” animasi, dibuat dengan JustGage; Jadikan semuanya tersedia secara online melalui server web lokal yang dibuat dengan Python dan Flask;

Diagram blok memberi kita gambaran tentang keseluruhan proyek:

Langkah 1:BoM – Bill of Material

Langkah 2:Menginstal SQLite

Oke, ide umumnya adalah mengumpulkan data dari sensor dan menyimpannya dalam database.

Tapi "mesin" database apa yang harus digunakan?

Ada banyak pilihan di pasar dan mungkin 2 yang paling banyak digunakan dengan Raspberry Pi dan sensornya adalah MySQL dan SQLite. MySQL sangat terkenal tetapi sedikit “berat” untuk digunakan pada proyek berbasis Raspberry sederhana (selain itu milik Oracle!). SQLite mungkin adalah pilihan yang paling cocok. Karena tanpa server, ringan, opensource, dan mendukung sebagian besar kode SQL (lisensinya adalah "Domain Publik"). Hal lain yang berguna adalah bahwa SQLite menyimpan data dalam satu file yang dapat disimpan di mana saja.

Tapi, apa itu SQLite?

SQLite adalah sistem manajemen basis data relasional yang terdapat dalam pustaka pemrograman C. Berbeda dengan banyak sistem manajemen database lainnya, SQLite bukanlah mesin database client-server. Sebaliknya, itu tertanam ke dalam program akhir.

SQLite adalah domain publik yang populer pilihan sebagai perangkat lunak basis data tertanam untuk penyimpanan lokal/klien dalam perangkat lunak aplikasi seperti browser web. Ini bisa dibilang mesin database yang paling banyak digunakan, seperti yang digunakan saat ini oleh beberapa browser yang tersebar luas, sistem operasi, dan sistem tertanam (seperti ponsel), antara lain. SQLite memiliki binding ke banyak bahasa pemrograman seperti Python, yang digunakan pada proyek kami.

(Selengkapnya di Wikipedia)

Kami tidak akan memasukkan terlalu banyak detail di sini, tetapi dokumentasi SQLite lengkap dapat ditemukan di link ini: https://www.sqlite.org/docs.html

Jadi, jadilah! Mari instal SQLite di Pi

Pemasangan:

Ikuti langkah-langkah di bawah ini untuk membuat database.

1. Instal SQLite ke Raspberry Pi menggunakan perintah:

sudo apt-get install sqlite3 

2. Buat direktori untuk mengembangkan proyek:

mkdir Sensors_Database 

3. Pindah ke direktori ini:

cd mkdir Sensors_Database/ 

3. Beri nama dan buat database seperti databaseName.db (dalam kasus saya “sensorsData.db”):

sqlite3 sensorData.db 

Sebuah "shell" akan muncul, di mana Anda dapat masuk dengan perintah SQLite. Kami akan kembali lagi nanti.

sqlite> 

Perintah dimulai dengan “.”, seperti “.help”, “.quit”, dll.

4. Keluar dari shell untuk kembali ke Terminal:

sqlite> .quit 

Layar cetak Terminal di atas menunjukkan apa yang dijelaskan.

The “sqlite>” di atas hanya untuk menggambarkan bagaimana shell SQLite akan muncul. Anda tidak perlu mengetiknya. Ini akan muncul secara otomatis.

Langkah 3:Membuat dan Mengisi Tabel

Untuk mencatat data pengukuran sensor DHT pada database, kita harus membuat tabel  (database dapat berisi beberapa tabel). Tabel kami akan diberi nama “DHT_data” dan akan memiliki 3 kolom, tempat kami akan mencatat data yang dikumpulkan:Tanggal dan Jam (nama kolom: stempel waktu ), Suhu (nama kolom: temp ), dan Kelembaban (nama kolom: hum ).

Membuat tabel:

Untuk membuat tabel, Anda dapat melakukannya:

1. Menggunakan Shell:

Buka database yang telah dibuat pada langkah terakhir:

sqlite3 sensorData.db 

Dan masuk dengan pernyataan SQL:

sqlite> BEGIN;sqlite> CREATE TABLE DHT_data (timestamp DATETIME, temp NUMERIC, hum NUMERIC);sqlite> COMMIT; 

Semua pernyataan SQL harus diakhiri dengan “;”. Juga biasanya, pernyataan tersebut ditulis menggunakan huruf kapital. Ini tidak wajib, tetapi praktik yang baik.

2. Menggunakan Python

import sqlite3 sebagai liteimport syscon =lite.connect('sensorsData.db')dengan con:cur =con.cursor() cur.execute("DROP TABLE JIKA ADA DHT_data") cur.execute("CREATE TABLE DHT_data(timestamp DATETIME, temp NUMERIC, hum NUMERIC)") 

Buka kode di atas dari GitHub saya: createTableDHT.py

Jalankan di Terminal Anda:

python3 createTableDHT.py 

Di mana pun metode yang digunakan, tabel harus dibuat. Anda dapat memverifikasinya di SQLite Shell menggunakan perintah “.table”. Buka cangkang basis data:

sqlite3> sensorData.db 

Di shell, setelah Anda menggunakan .table perintah, nama tabel yang dibuat akan muncul (dalam kasus kami hanya akan ada satu:“DHT_table”. Keluar dari shell setelahnya, menggunakan .quit  perintah.

sqlite> .tableDHT_datasqlite> .quit 

Memasukkan data pada tabel:

Mari kita masukan pada database kita 3 set data, dimana setiap set akan memiliki 3 komponen masing-masing:(timestamp, temp, dan hum). Komponen stempel waktu akan nyata dan diambil dari sistem, menggunakan fungsi bawaan 'sekarang' dan temp dan hum adalah data dummy dalam oC dan % masing-masing.

Catatan bahwa waktunya dalam "UTC", apa bagusnya karena Anda tidak perlu khawatir tentang masalah yang berkaitan dengan waktu musim panas dan hal-hal lain. Jika Anda ingin menampilkan tanggal dalam waktu lokal, cukup konversikan ke zona waktu yang sesuai setelahnya.

Cara yang sama dilakukan dengan pembuatan tabel, Anda dapat memasukkan data secara manual melalui shell SQLite atau melalui Python. Pada shell, Anda akan melakukannya, data demi data menggunakan pernyataan SQL seperti ini (Sebagai contoh kami, Anda akan melakukannya 3 kali):

sqlite> INSERT INTO DHT_data VALUES(datetime('now'), 20.5, 30); 

Dan dengan Python, Anda akan melakukan hal yang sama tetapi sekaligus:

import sqlite3 sebagai liteimport syscon =lite.connect('sensorsData.db')dengan con:cur =con.cursor() cur.execute("INSERT INTO DHT_data VALUES (datetime('now'), 20.5, 30)") cur.execute("INSERT INTO DHT_data VALUES(datetime('now'), 25.8, 40)") cur.execute("INSERT INTO DHT_data VALUES(datetime(' sekarang'), 30.3, 50)") 

Buka kode di atas dari GitHub saya: insertTableDHT.py

Jalankan di Terminal Pi:

python3 insertTableDHT.py 

Untuk memastikan bahwa kode di atas berfungsi, Anda dapat memeriksa data di tabel melalui shell, dengan pernyataan SQL:

sqlite> PILIH * DARI DHT_DATA; 

Layar cetak Terminal di atas menunjukkan bagaimana baris tabel akan muncul.

Langkah 4:Memasukkan dan Memverifikasi Data Dengan Python

Untuk memulai, mari kita lakukan hal yang sama seperti sebelumnya (memasukkan dan mengambil data), tetapi melakukan keduanya dengan python dan juga mencetak data di terminal:

import sqlite3import sysconn=sqlite3.connect('sensorsData.db')curs=conn.cursor()# berfungsi untuk menyisipkan data pada tabledef add_data (temp, hum) :curs.execute("INSERT INTO DHT_data values(datetime('now'), (?), (?))", (temp, hum)) conn.commit()# memanggil fungsi untuk memasukkan dataadd_data (20.5, 30 )add_data (25.8, 40)add_data (30.3, 50)# print database contentprint ("\nSeluruh isi database:\n")untuk baris di curs.execute("SELECT * FROM DHT_data"):print (baris)# tutup database setelah useconn.close() 

Buka kode di atas dari GitHub saya: insertDataTableDHT.pydan jalankan di Terminal Anda:

python3 insertDataTableDHT.py 

Layar cetak Terminal di atas menunjukkan hasilnya.

Langkah 5:Sensor Suhu dan Kelembaban DHT22

Sejauh ini kami telah membuat tabel di database kami, di mana kami akan menyimpan semua data yang akan dibaca oleh sensor. Kami juga telah memasukkan beberapa data dummy di sana. Sekarang saatnya menggunakan data nyata untuk disimpan di tabel kami, suhu udara dan kelembaban relatif. Untuk itu, kami akan menggunakan DHTxx lama dan bagus (DHT11 atau DHT22). Situs ADAFRUIT menyediakan informasi hebat tentang sensor tersebut. Di bawah ini, beberapa informasi diambil dari sana:

Ringkasan

Sensor suhu &kelembaban DHT murah sangat mendasar dan lambat tetapi sangat bagus untuk penggemar yang ingin melakukan pencatatan data dasar. Sensor DHT terdiri dari dua bagian, sensor kelembaban kapasitif, dan termistor. Ada juga chip yang sangat mendasar di dalamnya yang melakukan beberapa konversi analog ke digital dan mengeluarkan sinyal digital dengan suhu dan kelembaban. Sinyal digital cukup mudah dibaca menggunakan mikrokontroler apa pun.

DHT11 vs DHT22

Kami memiliki dua versi sensor DHT, mereka terlihat sedikit mirip dan memiliki pinout yang sama, tetapi memiliki karakteristik yang berbeda. Berikut spesifikasinya:

DHT11 (biasanya biru)

Baik untuk pembacaan kelembaban 20-80% dengan akurasi 5% Baik untuk pembacaan suhu 0-50 °C Akurasi ±2 °C Tidak lebih dari 1 Hz sampling rate (sekali setiap detik)

DHT22 (biasanya putih)

Baik untuk pembacaan kelembaban 0-100% dengan akurasi 2-5% Baik untuk pembacaan suhu -40 hingga 125 °C Akurasi ±0,5 °C Tidak lebih dari 0,5 Hz sampling rate (setiap 2 detik sekali)

Seperti yang Anda lihat, DHT22 sedikit lebih akurat dan bagus pada rentang yang sedikit lebih besar. Keduanya menggunakan satu pin digital dan 'lamban' karena Anda tidak dapat menanyakannya lebih dari sekali setiap detik (DHT11) atau dua (DHT22).

Kedua sensor akan bekerja dengan baik untuk mendapatkan informasi dalam ruangan untuk disimpan di database kami.

DHTxx memiliki 4 pin (menghadap sensor, pin 1 paling kiri) :

Kami akan menggunakan DHT22 dalam proyek kami.

Setelah biasanya Anda akan menggunakan sensor pada jarak kurang dari 20m, resistor 4K7 ohm harus dihubungkan antara pin Data dan VCC. Pin data output DHT22 akan terhubung ke Raspberry GPIO 16.

Periksa diagram kelistrikan di atas yang menghubungkan sensor ke pin RPi seperti di bawah ini:

Jangan lupa Pasang resistor 4K7 ohm antara Vcc dan pin Data. Setelah sensor terhubung, kita juga harus menginstal perpustakaannya di RPi kita. Kami akan melakukan ini di langkah berikutnya.

Langkah 6:Memasang Pustaka DHT

Di Raspberry Anda, mulai dari /home, buka /Documents:

cd Dokumen  

Buat direktori untuk menginstal perpustakaan dan pindah ke sana:

mkdir DHT22_Sensorcd DHT22_Sensor 

Di browser Anda, buka Adafruit GITHub: https://github.com/adafruit/Adafruit_Python_DHT

Unduh perpustakaan dengan mengklik tautan unduhan zip di sebelah kanan dan unzip arsip di folder Raspberry Pi Anda yang baru saja dibuat. Lalu pergi ke direktori perpustakaan (subfolder yang secara otomatis dibuat ketika Anda membuka ritsleting file), dan jalankan perintah:

sudo python3 setup.py install 

Buka program uji (DHT22_test.py) dari GITHUB saya:

import Adafruit_DHTDHT22Sensor =Adafruit_DHT.DHT22DHTpin =16humidity, temperature =Adafruit_DHT.read_retry(DHT22Sensor, DHTpin)jika kelembapan tidak Tidak ada dan suhu tidak Tidak ada:print('Temp={0:0.1f}*C Kelembaban={1:0.1f}%'.format(suhu, kelembapan))else:print('Gagal membaca. Coba lagi!') 

Jalankan program dengan perintah:

python3 DHT22_test.py 

Layar cetak Terminal di atas menunjukkan hasilnya.

Langkah 7:Menangkap Data Nyata

Sekarang setelah kita memiliki keduanya, sensor dan database kita semua terinstal dan dikonfigurasi, saatnya untuk membaca dan menyimpan data yang sebenarnya.

Untuk itu, kita akan menggunakan kode:

import timeimport sqlite3import Adafruit_DHTdbname='sensorsData.db'sampleFreq =2 # waktu dalam detik# dapatkan data dari DHT sensordef getDHTdata():DHT22Sensor =Adafruit_DHT.DHT22 DHTpin =16 hum, temp =Adafruit_DHT.read_retry(DHT22Sensor, DHTpin) jika hum tidak None dan temp tidak None:hum =round(hum) temp =round(temp, 1) logData (temp, hum)# data sensor log pada databasedef logData (temp, hum):conn=sqlite3.connect(dbname) curs=conn.cursor() curs.execute("INSERT INTO DHT_data values(datetime('now'), (?), (?))", (temp , hum)) conn.commit() conn.close()# menampilkan database datadef displayData():conn=sqlite3.connect(dbname) curs=conn.cursor() print ("\nSeluruh isi database:\n") untuk baris di curs.execute("SELECT * FROM DHT_data"):print (baris) conn.close()# main functiondef main():for i in range (0,3):getDHTdata() time.sleep(sampleFreq) displayData ()# Jalankan program main() 

Buka file di atas dari GitHub saya: appDHT.pydan jalankan di Terminal Anda:

python3 appDHT.py 

Fungsi getDHTdata() mengambil 3 sampel sensor DHT, mengujinya untuk kesalahan, dan jika OK, simpan data di database menggunakan fungsi logData (temp, hum) . Bagian terakhir dari kode memanggil fungsi displayData() yang mencetak seluruh isi tabel kita di Terminal.

Layar cetak di atas menunjukkan hasilnya. Perhatikan bahwa 3 baris (baris) terakhir adalah data nyata yang diambil dengan program ini dan 3 baris sebelumnya adalah yang dimasukkan secara manual sebelumnya.

Sebenarnya appDHT.py bukanlah nama yang bagus. Secara umum, "appSomething.py" digunakan dengan skrip Python di server web seperti yang akan kita lihat lebih lanjut di tutorial ini. Tapi tentu saja Anda bisa menggunakannya di sini.

Langkah 8:Menangkap Data Secara Otomatis

Pada titik ini, yang harus kita terapkan adalah mekanisme untuk membaca dan memasukkan data ke database kita secara otomatis, “Logger” kita.

Buka jendela Terminal baru dan masukkan dengan kode Python di bawah ini:

import timeimport sqlite3import Adafruit_DHTdbname='sensorsData.db'sampleFreq =1*60 # waktu dalam detik ==> Sampel setiap 1 menit# dapatkan data dari DHT sensordef getDHTdata() :DHT22Sensor =Adafruit_DHT.DHT22 DHTpin =16 hum, temp =Adafruit_DHT.read_retry(DHT22Sensor, DHTpin) jika hum tidak None dan temp tidak None:hum =round(hum) temp =round(temp, 1) return temp, hum # data sensor log pada databasedef logData (temp, hum):conn=sqlite3.connect(dbname) curs=conn.cursor() curs.execute("INSERT INTO DHT_data values(datetime('now'), (?), ( ?))", (temp, hum)) conn.commit() conn.close()# main functiondef main():while True:temp, hum =getDHTdata() logData (temp, hum) time.sleep(sampleFreq) # ------------ Jalankan program main() 

Atau dapatkan dari GitHub saya: logDHT.py. Jalankan di Terminal:

python3 logDHT.py 

Apa yang dilakukan fungsi main() adalah:

Panggil fungsi getDHTdata() , yang akan mengembalikan data yang ditangkap oleh sensor DHT22. Ambil data tersebut (suhu dan kelembapan) dan meneruskannya ke fungsi lain: logData(temp, hum) yang memasukkannya, bersama dengan tanggal dan waktu sebenarnya, ke meja kita. Dan pergi tidur, menunggu hingga waktu terjadwal berikutnya untuk mengambil data (ditentukan oleh sampleFreq , yang dalam contoh ini adalah 1 menit).

Biarkan jendela Terminal terbuka.

Sampai Anda mematikan program dengan [Ctr+z], misalnya, program akan terus mengambil data, memasukkannya ke dalam database kami. Saya membiarkannya berjalan sebentar pada frekuensi 1 menit untuk mengisi database lebih cepat, mengubah frekuensi setelah beberapa jam menjadi 10 menit.

Ada mekanisme lain yang jauh lebih efisien untuk melakukan "penebang otomatis" semacam ini daripada menggunakan "time.sleep", tetapi kode di atas akan berfungsi dengan baik untuk tujuan kita di sini. Bagaimanapun, jika Anda ingin menerapkan “penjadwal” yang lebih baik, Anda dapat menggunakan Crontab , yang merupakan alat UNIX yang berguna untuk menjadwalkan pekerjaan. Penjelasan yang baik tentang apa itu Crontab dapat ditemukan dalam tutorial ini: “Menjadwalkan Tugas di Linux Menggunakan Crontab”, oleh Kevin van Zonneveld.

Langkah 9:Kueri

Sekarang database kita sedang diumpankan secara otomatis, kita harus menemukan cara untuk bekerja dengan semua data tersebut. Kami melakukannya dengan pertanyaan!

Apa itu kueri?

Salah satu fitur terpenting dalam bekerja dengan bahasa SQL di atas basis data adalah kemampuan untuk membuat "kueri basis data". Dengan kata lain, kueri mengekstrak data dari database yang memformatnya dalam bentuk yang dapat dibaca. Kueri harus ditulis dalam bahasa SQL , yang menggunakan PILIH pernyataan untuk memilih data tertentu.

Kami sebenarnya telah menggunakannya pada "cara yang luas" pada langkah terakhir:"SELECT * FROM DHT_data".

Contoh:

Mari kita buat beberapa query atas data pada tabel yang telah kita buat. Untuk itu, masukkan dengan kode di bawah ini:

import sqlite3conn=sqlite3.connect('sensorsData.db')curs=conn.cursor()maxTemp =27.6print ("\nSeluruh isi database:\n") untuk baris di curs.execute("SELECT * FROM DHT_data"):print (baris)print ("\nEntri database untuk nilai kelembapan tertentu:\n")untuk baris di curs.execute("SELECT * FROM DHT_data WHERE hum='29'"):print (baris) print ("\nEntri database dengan suhu di atas 30oC:\n") untuk baris di curs.execute("SELECT * FROM DHT_data WHERE temp>
30.0"):print (baris) print ("\nEntri database dengan suhu di atas x:\n")untuk baris di curs.execute("SELECT * FROM DHT_data WHERE temp>
(?)", (maxTemp,)):print (baris)  

Atau dapatkan dari GitHub saya: queryTableDHT.py, dan jalankan di Terminal:

python3 queryTableDHT.py 

Anda dapat melihat hasilnya pada layar cetak Terminal di atas. Itu adalah contoh sederhana untuk memberi Anda gambaran tentang kueri. Luangkan waktu untuk memahami pernyataan SQL dalam kode di atas.

Jika Anda ingin tahu lebih banyak tentang bahasa SQL, sumber yang bagus adalah Tutorial SQL W3School.

Langkah 10:Data Terakhir Dimasukkan pada Tabel:

Kueri yang sangat penting adalah kueri untuk mengambil data terakhir yang dimasukkan (atau dicatat) di atas meja. Kita bisa melakukannya langsung di shell SQLite, dengan perintah:

sqlite> PILIH * DARI DHT_data ORDER BY timestamp DESC LIMIT 1; 

Atau jalankan kode python sederhana seperti di bawah ini:

import sqlite3conn =sqlite3.connect('sensorsData.db')curs=conn.cursor()print ("\nData terakhir masuk ke database:\n")untuk baris di curs.execute("SELECT * FROM DHT_data ORDER BY timestamp DESC LIMIT 1"):print (baris) 

Anda dapat melihat hasilnya pada layar cetak Terminal pertama di atas.

Perhatikan bahwa hasilnya akan muncul sebagai "tupel nilai":('timestamp', temp, hum).

Tuple mengembalikan konten baris terakhir dari tabel kita, yang dibentuk dengan 3 elemen di atasnya:

Jadi, kita dapat bekerja lebih baik dengan kode kita, untuk mengambil data "bersih" dari tabel, misalnya:

import sqlite3conn=sqlite3.connect('sensorsData.db')curs=conn.cursor()print ("\nData mentah terakhir masuk ke database:\n") untuk baris di curs.execute("SELECT * FROM DHT_data ORDER BY timestamp DESC LIMIT 1"):print (str(row[0])+" ==> Temp ="+str(row[1])+" Hum ="+str(baris[2])) 

Buka file dari GitHub saya: lastLogDataTableDHT.py dan jalankan di Terminal:

python3 lastLogDataTableDHT.py 

Anda dapat melihat hasilnya pada layar cetak Terminal ke-2 di atas.

Langkah 11:Front-end Web untuk Visualisasi Data

Pada tutorial terakhir saya: Python WebServer With Flask dan Raspberry Pi, kami mempelajari cara mengimplementasikan server web (menggunakan Flask) untuk mengambil data dari sensor dan menampilkan statusnya di halaman web.

Inilah yang juga ingin kami capai di sini. Perbedaannya terletak pada data yang akan dikirim ke front end kami, yang akan diambil dari database dan tidak langsung dari sensor seperti yang kami lakukan pada tutorial itu.

Membuat lingkungan server web:

Hal pertama yang harus dilakukan adalah menginstal Flask di Raspberry Pi Anda. Jika Anda tidak memilikinya, buka Terminal dan masukkan:

sudo apt-get install python3-flask 

Yang terbaik saat Anda memulai proyek baru adalah membuat folder tempat file Anda diatur. Misalnya:

Dari rumah, buka direktori kerja kami:

cd Documents/Sensors_Database 

Buat folder baru, misalnya:

mkdir dhtWebServer 

Perintah di atas akan membuat folder bernama “dhtWebServer”, tempat kita akan menyimpan skrip python kita:

/home/pi/Documents/Sensor_Database/rpiWebServer 

Sekarang, di folder ini, mari buat 2 sub-folder: statis untuk CSS dan akhirnya file JavaScript dan templat  untuk file HTML. Buka folder baru yang Anda buat:

cd dhtWebServer 

Dan buat 2 sub-folder baru:

mkdir static 

dan

template mkdir 

Direktori akhir “pohon”, akan terlihat seperti:

├── Sensors_Database sensorData.db logDHT.py dhtWebSensor template statis 

Kami akan meninggalkan database yang kami buat di direktori /Sensor_Database, jadi Anda perlu menghubungkan SQLite dengan “../sensorsData.db”.

OKE! Dengan lingkungan yang ada, mari kita kumpulkan bagian-bagiannya dan buat Aplikasi Server Web Python . Diagram di atas memberi kita gambaran tentang apa yang harus dilakukan!

Langkah 12:Aplikasi WebServer Python

Mulai dari diagram terakhir, mari kita buat WebServer python menggunakan Flask. Saya sarankan Geany sebagai IDE yang akan digunakan,  setelah Anda dapat bekerja secara bersamaan dengan berbagai jenis file (.py, .html, dan .css).

Kode di bawah ini adalah skrip python yang akan digunakan di server web pertama kami:

from flask import Flask, render_template, requestapp =Flask(__name__)import sqlite3# Ambil data dari databasedef getData():conn=sqlite3.connect('../sensorsData .db') curs=conn.cursor() untuk baris di curs.execute("SELECT * FROM DHT_data ORDER BY timestamp DESC LIMIT 1"):time =str(row[0]) temp =row[1] hum =row [2] conn.close() kembali waktu, suhu, hum# rute utama @app.route("/")def index():waktu, suhu, hum =getData() templateData ={ 'waktu':waktu, ' temp':temp, 'hum':hum } return render_template('index.html', **templateData)if __name__ =="__main__":app.run(host='0.0.0.0', port=80, debug=Salah) 

Anda bisa mendapatkan skrip python appDhtWebServer.py dari GitHub saya. Apa yang dilakukan kode di atas adalah:

Dengan permintaan ini, hal pertama yang dilakukan dalam kode adalah mengambil data dari database menggunakan fungsi time, temp, hum =getData(). Fungsi ini pada dasarnya adalah kueri yang sama yang digunakan sebelumnya untuk mengambil data yang disimpan dalam tabel. Dengan data yang ada, skrip kami kembali ke halaman web (index.html ): waktusuhu  dan hum sebagai tanggapan atas permintaan sebelumnya.

Jadi, mari kita lihat index.html dan style.css file yang akan digunakan untuk membangun front-end kita:

index.html

  Data Sensor DHT     

Data Sensor DHT

SUHU ==> {{ tempLab }} oC

KELEMBABAN (Rel.) ==> { { humLab }} %


Pembacaan Sensor Terakhir:{{ time }} ==> REFRESH


@2018 Dikembangkan oleh MJRoBot.org

Anda bisa mendapatkan file index.html dari GitHub saya.

style.css

body{ latar belakang:biru; warna:kuning; padding:1%}.button { font:tebal 15px Arial; dekorasi teks:tidak ada; warna latar:#EEEEEE; warna:#333333; bantalan:2px 6px 2px 6px; border-top:1px solid #CCCCCC; batas-kanan:1px solid #333333; border-bottom:1px solid #333333; border-left:1px solid #CCCCCC;} 

Anda bisa mendapatkan file style.css dari GitHub saya. File harus ditempatkan di direktori Anda seperti ini:

├── Sensors_Database sensorData.db logDHT.py dhtWebSensor appDhtWebSensor.py template indeks .html statis style.css  

Sekarang, jalankan skrip python di Terminal:

sudo python3 appDhtWebServer.py 

Buka browser apa pun di jaringan Anda dan masuk dengan http://YOUR_RPI_IP (misalnya, dalam kasus saya: http://10.0.1.27)

Layar cetak di atas menunjukkan apa yang harus Anda lihat. CATATAN:Jika Anda tidak yakin tentang alamat Ip RPi Anda, jalankan di terminal Anda:

 ifconfig 

Di wlan0:bagian Anda akan menemukannya. Dalam kasus saya:10.0.1.27

Langkah 13:Membuat Web Front-End Kami Lebih Menarik!

Mari perkenalkan beberapa Pengukur untuk menyajikan nilai Suhu dan Kelembaban aktual dengan cara yang lebih baik. Perhatikan bahwa skrip Python kami tidak akan berubah, tetapi menggunakan JustGage pada file html/css kami, akan banyak meningkatkan cara penyajian data.

Apa itu JustGage?

JustGage adalah plugin JavaScript yang berguna untuk menghasilkan dan menganimasikan pengukur yang bagus &bersih. Ini didasarkan pada perpustakaan Raphaël untuk menggambar vektor, sehingga sepenuhnya bebas resolusi dan dapat menyesuaikan sendiri, bekerja di hampir semua browser.

Pemasangan:

justgage-1.2.2.zip

 Sensor Data DHT    

Data Sensor DHT


Sensor Terakhir Membaca:{{ time }} ==> REFRESH


@2018 Dikembangkan oleh MJRoBot.org

Unduh dari GitHub saya file: index_gage.html, dan ganti namanya menjadi index.html (jangan lupa untuk mengganti nama yang sebelumnya dengan nama yang berbeda jika Anda ingin menyimpannya, misalnya index_txt.html).

Pohon direktori terakhir akan terlihat seperti di bawah ini:

├── Sensors_Database sensorData.db logDHT.py dhtWebServer appDhtWebServer.py template indeks .html static style.css justgage.js raphael-2.1.4.min.js 

Tekan [Crl-C] di Terminal Anda untuk Keluar dari appDhtWebServer.py dan mulai lagi. Saat menyegarkan browser, Anda harus melihat layar cetak di atas.

Lihat contoh file yang Anda unduh dari situs web JustGage. Coba buat perubahan pada pengukur Anda. Ini sangat sederhana.

Langkah 14:Proses Lengkap

Diagram di atas melanjutkan apa yang telah kita capai sejauh ini:2 skrip terpisah berjalan secara paralel, melakukan tugasnya secara independen:

Menangkap data dengan sensor dan memuatnya ke dalam database (logDHT.py )Cari data di database dan tampilkan di front-end web (appDhtWebServer.py ).

Secara umum, proyek kami untuk menangkap data, menyimpannya di database, dan menampilkan data tersebut di halaman web telah selesai. Tetapi tidak masuk akal untuk memiliki database dengan data historis dan hanya menggunakannya untuk data terakhir yang diambil. Kita harus bermain dengan data historis dan hal paling mendasar yang harus dilakukan adalah menyajikannya dalam grafik. Ayo lakukan!

Langkah 15:Membuat Grafik Data Historis

Pustaka yang sangat baik untuk membuat grafik data adalah Matplotlib that is a Python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms.

To install matplotlib , run the command below on your Terminal:

sudo apt-get install python3-matplotlib 

Before we start, let’s create a new environment, where we will save the new application to be developed: appDhtWebHist.py  and its correspondent index.html  and style.css

├── Sensors_Database ├── sensorsData.db ├── logDHT.py ├── dhtWebHist ├── appDhtWebHist.py ├── templates │ ├── index.html └── static ├── style.css  

Create the new 3 directories (dhtWebHist; /templates  and /static ) same as we did before and open from my GitHub the 3 files below:

1. appDhtWebHist.py

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvasfrom matplotlib.figure import Figureimport iofrom flask import Flask, render_template, send_file, make_response, requestapp =Flask(__name__)import sqlite3conn=sqlite3.connect('../sensorsData.db')curs=conn.cursor()# Retrieve LAST data from databasedef getLastData():for row in curs.execute("SELECT * FROM DHT_data ORDER BY timestamp DESC LIMIT 1"):time =str(row[0]) temp =row[1] hum =row[2] #conn.close() return time, temp, humdef getHistData (numSamples):curs.execute("SELECT * FROM DHT_data ORDER BY timestamp DESC LIMIT "+str(numSamples)) data =curs.fetchall() dates =[] temps =[] hums =[] for row in reversed(data):dates.append(row[0]) temps.append(row[1]) hums.append(row[2]) return dates, temps, humsdef maxRowsTable():for row in curs.execute("select COUNT(temp) from DHT_data"):maxNumberRows=row[0] return maxNumberRows# define and initialize global variablesglobal numSamplesnumSamples =maxRowsTable() if (numSamples> 101):numSamples =100# main [email protected]("/")def index():time, temp, hum =getLastData() templateData ={ 'time' :time, 'temp' :temp, 'hum' :hum, 'numSamples' :numSamples } return render_template('index.html', **templateData)@app.route('/', methods=['POST'])def my_form_post():global numSamples numSamples =int (request.form['numSamples']) numMaxSamples =maxRowsTable() if (numSamples> numMaxSamples):numSamples =(numMaxSamples-1) time, temp, hum =getLastData() templateData ={ 'time' :time, 'temp' :temp, 'hum' :hum, 'numSamples' :numSamples } return render_template('index.html', **templateData)@app.route('/plot/temp')def plot_temp():times, temps, hums =getHistData(numSamples) ys =temps fig =Figure() axis =fig.add_subplot(1, 1, 1) axis.set_title("Temperature [°C]") axis.set_xlabel("Samples") axis.grid(True) xs =range(numSamples) axis.plot(xs, ys) canvas =FigureCanvas(fig) output =io.BytesIO() canvas.print_png(output) response =make_response(output.getvalue()) response.mimetype ='image/png' return [email protected]('/plot/hum')def plot_hum():times, temps, hums =getHistData(numSamples) ys =hums fig =Figure() axis =fig.add_subplot(1, 1, 1) axis.set_title("Humidity [%]") axis.set_xlabel("Samples") axis.grid(True) xs =range(numSamples) axis.plot(xs, ys) canvas =FigureCanvas(fig) output =io.BytesIO() canvas.print_png(output) response =make_response(output.getvalue()) response.mimetype ='image/png' return responseif __name__ =="__main__":app.run(host='0.0.0.0', port=80, debug=False) 

A new function was created here: getHistData (numSamples) , that receives as a parameter the number of rows that should be taken from the database. Basically, it is very similar to getLastData(), where numSamples  was “1”. Of course, now we must “append” the return array for all required rows.

In fact, we could use only this last function for both tasks.

The number of samples is set by default as 100, at the beginning (if there are more them 100 rows into the database) and also received it as an input from the webpage, during normal operation. When we receive the number of samples to be retrieved, we must also check if it is lower than the maximum number of rows in the database (otherwise we will get an error). The function maxRowsTable() , returns this number.

With the historical data in hand: times, temps  and hums  that are arrays, we must build the graphs saving them as a .png ímage . Those images will be the return for the routes:

@app.route(‘/plot/temp’)  and @app.route(‘/plot/hum’).

The request for the images is done by index.html, by the IMG TAG.

2. index.html

  DHT Sensor data     

DHT Sensor Data

TEMPERATURE ==> {{ temp }} oC

HUMIDITY (Rel.) ==> {{ hum }} %


Last Sensors Reading:{{ time }} ==> REFRESH


HISTORICAL DATA

Enter number of samples to retrieve:


Image Placeholder Image Placeholder

@2018 Developed by MJRoBot.org

3. style.css

body{ background:blue; color:yellow; padding:1%}.button { font:bold 15px Arial; text-decoration:none; background-color:#EEEEEE; color:#333333; padding:2px 6px 2px 6px; border-top:1px solid #CCCCCC; border-right:1px solid #333333; border-bottom:1px solid #333333; border-left:1px solid #CCCCCC;}img{ display:display:inline-block} 

The above print screen shows the result.

Step 16:Including Gage on History Webpage

If instead of text, you want also to include gages to display the actual data, you must have the 2 .js files that you have used before on /static and change the index.html file on /templates:

Below how the directory tree looks like:

├── Sensors_Database ├── sensorsData.db ├── logDHT.py ├── dhtWebHist ├── appDhtWebHist.py ├── templates │ ├── index.html └── static ├── style.css ├── justgage.js ├── raphael-2.1.4.min.js 

From my GitHub, open index_gage.html and rename it index.html. Replace the actual index.html (text version) and voilá! You will get a beautiful webpage, showing as gages the last captured data of temperature and humidity by the DHT22 and the historical graphs of those data.

Press[Crl-C] on your Terminal to Quit appDhtWebServer.py and just start it again. When you refresh your browser you must see the above print screen.

Step 17:Retrieving Data by Time Instead of Samples

So far we have build our graphics based on historical data, sending as a input parameter the numbers of samples to be retrieved from our database. Alternatively we could use as a parameter the number of past minutes that we want to show on a graph.

In order to do that, the first thing to know is the frequency of logged data on our database. Remember that this task is done for an independent program (in our case, logDHT.py ). One simple way to finfd this frequency is to retrieve the last 2 data logged on database and subtracting their correspondent timeStamp data:

in general terms: frequency =timeStamp(1) – timeStamp(0)

The function below does the work for us, using “datetime.striptime()”:

# Get sample frequency in minutesdef freqSample():times, temps, hums =getHistData (2) fmt ='%Y-%m-%d %H:%M:%S' tstamp0 =datetime.strptime(times[0], fmt) tstamp1 =datetime.strptime(times[1], fmt) freq =tstamp1-tstamp0 freq =int(round(freq.total_seconds()/60)) return (freq) 

Once we we have this frequency parameter in minutes, we will show it on index.html and asking for a “rangeTime” number of minutes to be send back to our server ==> @app.route(‘/’, methods=[‘POST’]):

@app.route('/', methods=['POST'])def my_form_post():global numSamples global freqSamples global rangeTime rangeTime =int (request.form['rangeTime']) if (rangeTime  numMaxSamples):numSamples =(numMaxSamples-1) 

The picture shows the result:

Eliminating Possible errors when constructing the graphs:

Ocasionally, strange (or corrupted) data can be storaged on database, jeopardizing our analysis. Those data can be verified (or cleaneed) on several places (like during the time sensor are capturing the data, etc). But once the script that display data is independent of the one that logged the data, let’s “cap” the maximum and minimum values of our sensors, before using the data to buit the graphs. This can be achieved with the function testData(temps, hums) :

# Test data for cleanning possible "out of range" valuesdef testeData(temps, hums):n =len(temps) for i in range(0, n-1):if (temps[i] <-10 or temps[i]>50):temps[i] =temps[i-2] if (hums[i] <0 or hums[i]>100):hums[i] =temps[i-2] return temps, hums 

The scripts for this new version can be download from my GitHub: dhtWebHist_v2

Step 18:Conclusion

As always, I hope this project can help others find their way into the exciting world of electronics!

For details and final code, please visit my GitHub depository: RPI-Flask-SQLite

For more projects, please visit my blog: MJRoBot.org

Saludos from the south of the world!

See you at my next tutorial!

Thank you,

Source:From Data to Graph:A Web Journey With Flask and SQLite


Proses manufaktur

  1. Simpan dan Kelola Data Sensitif Dengan Manajer Rahasia
  2. Microchip:ADC 24-bit dan 16-bit dengan kecepatan data hingga 153,6 kSPS
  3. Pemantau Suhu dan Kelembaban Rumah (Kamar) dengan Bagan Berbasis Web – Raspberry Pi
  4. Membuat robot dengan Raspberry Pi dan Python
  5. Mempercepat transformasi digital dengan Data IoT, berkat Cisco dan IBM
  6. Memanfaatkan data IoT dari edge ke cloud dan sebaliknya
  7. Perjalanan IIoT dimulai dengan telemetri jarak jauh
  8. Cara menjadikan IoT nyata dengan Tech Data dan IBM Bagian 2
  9. Cara menjadikan IoT nyata dengan Tech Data dan IBM Bagian 1
  10. Mendorong Hasil Bisnis Dengan Proyek Big Data dan AI