Chương trình chính cla HTTP server tao ra cdc API nhận các dữ liệu nhiệt độ, độ ẩm và 3 giá trị trạng thái LED import base64 from io import BytesIO from fastapi import FastAPI from fasta
Trang 1
BỘ CÔNG THƯƠNG TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP TP HỒ CHÍ MINH
KHOA CÔNG NGHỆ ĐIỆN TỬ
A
8
NHÓM 10
Bài báo cáo 8
GIẢNG VIEN: PHAM QUANG TRI
Sinh vién
O Pham Quéc Nhat — 21117061
H Nguyễn Phước Thành Tâm — 21116741
O Hoang Gia Kha Thi - 21130471
Trang 2
Mức độ 3+: Xây dựng ITTTP server có cơ sở dữ liệu thực hiện các chức năng sau:
Oo
Oo
Oo
Oo
API để gửi dữ liệu nhiệt độ, độ ẩm, 3 giá trị trạng thái 3 LED lên Server; dữ liệu
có thể theo định dạng json hoặc form-urlencoded
Yéu cM 1: BS cuc phan céng nhiém vu ting thành viên, trình bày nội dung bài báo
cao
STT MSSV Ho va Tén Nhiém vu/Céng viéc
1 2111674 | Nguyễn Phước Thành Tâm | Vẽ Alũum, quay video và thuyết
1 trình video báo cáo
2 2111706 | Phạm Quốc Nhật Lập trình đi 'âi khiển, viết báo cáo
- _ Mô tả tóm tất nội dung bài báo cáo
+ Mức đệ 3+: Xây dựng server HTTP có cơ sở đữ liệu thực hiện các chức năng:
©_ API để gửi dữ liệu nhiệt độ, độ ẩm, 3 giá trị trạng thái 3 LED lên Server; dữ liệu có thể theo định dạng json hoặc form-urlencoded
Có hỗ trợ cả 2 giao thức POST/GET
API đọc dữ liệu nhiệt độ, độ ẩm 3 giá trị trạng thái 3 LED tử Server
Có thể chọn đọc N dữ liệu gần nhất, truy xuất dữ liệu theo một khoảng thời gian tùy chọn
o_ Dữ liệu gửi lên Server phải có thông tin _¡d, thời gian, tên thiết bị gửi lên và có hỗ trợ bảo mật dạng API_KEY (không lưu API vào cơ
sở đữ liệu)
Trang 3+ Nâng cao: Viết chương trình vẽ đ ôthi bằng python, tích hợp vào server và hiển thị đ ôthi dạng line theo thời gian cho tất cả các biến được lưu ở cơ sở
Trang 4Yêu cẦ 2: Sơ đônguyên lý chỉ tiết của hệ thống
Trang 5Yêu cầi 4: Mã ngu ôn của chương trình (không chấp nhận hình chụp)
Chương trình chính cla HTTP server tao ra cdc API nhận các dữ liệu nhiệt độ, độ
ẩm và 3 giá trị trạng thái LED
import base64
from io import BytesIO
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
import uvicorn
from pymongo import MongoClient
from pydantic import BaseModel
from data_model import data_list
import matplotlib.pyplot as plt
app = FastAPIQ)
myclient = MongoClient(
"mongodb+srv://quocnhat02092003:nhatfc 123 @qalochat.efezjhc.mongodb.net/? retry Writes=true&w=majority &appName=QaloChat"
Trang 6uvicorn.run(app, host="0.0.0.0", port=8000)
Các chương trình con của HTTP server tạo ra các API nhận các dữ liệu nhiệt độ, độ
ẩm và 3 giá trị trạng thái LED
@app.get("/data_post")
async def get_data_post(api: str, number: int):
number_data = data_list(mycol.find().sort([("_id", -1)])limit(number + 1))
async def get_record_by_time(start: str, end: str):
number_record = data_list(mycol.find({"time": {"$gte": start, "$lt": end}}))
Trang 9
-8-for item in data:
# Hàm vẽ biểu đ ồcho dữ liệu nhiệt độ và độ ẩïn
def plot_temp_humi_chart(id_values, humi_data, temp_data): plt.ñgureQ
# Vẽ biểu đ'`ônhiệt độ và độ ẩm
plt.plotGid_values, humi_data, label="Humidity" , color="blue") plt.plotGid_values, temp_data, label="Temperature"”, color="orange")
-9.
Trang 10plt.xlabel("Số IẦn đo")
plt.ylabel( "Giá trị")
plt.legendQ
plt.itle("Biểu đ ôNhiệt độ và Độ aim")
# Lưu biểu đ ôvào một bién BytesIO
img_buf = BytesIOQ
plt.savefig(img_buf, format="png")
img_buf.seek(0)
img_base64 = base64.b64encode(img_buf-read()).decode("utf-8") plt.close(.) # Dong figure sau khi vẽ xong
return img_base64
# Ham vé biéu d Scho ting gid tri LED riêng lẻ
def plot_led_chart(id_values, led_data, led_name, color="green"): plt.ñgureQ
# Vẽ biểu đ ồtrạng thái LED
plt.plotGid_values, led_data, label=led_name, color=color) plt.xlabel("Số IẦn đo")
plt.ylabel(f"Trang thái {led_name}")
plt.legendQ
plt.title(f"Biéu đ ôtrang thái {led_name}")
# Lưu biểu đ ôvào một bién BytesIO
Trang 11# Vẽ biểu đ ôcho nhiệt độ và độ ẩm
img_temp_humi = plot_temp_humi_chart(id_values, humi_data, temp_data)
# Vẽ biểu d‘G6cho LED 1
img_led1 = plot_led_chart(id_values, trang_thai_led1, "LED 1", color="green")
# Vẽ biểu đ ôcho LED 2
img_led2 = plot_led_chart(id_values, trang_thai_led2, "LED 2", color="red")
Trang 12
-11-# Vẽ biểu đ ôcho LED 3
img_led3 = plot_led_chart(id_values, trang_thai_led3, "LED 3", color="purple")
# Nội dung HTML để hiển thị tất cả các biểu đ ồ
html_content = f"""
<html>
<head>
<title>Biểu đ ôdữ liệu cảm biến và trang thai LED</title>
<meta http-equiv="refresh" content="5">
Trang 13from time import sleep
import json
import datetime
import platform
from gpiozero import LED
from seeed_dht import DHT
Trang 14print("So lan:{}" format(i)}
humi, temp = sensor.read()
print("Temp: {:.2f}, Humi: {:.2f}”.format(femp, humi))
Trang 16-15-sleep(20)
Các chương trình con đọc dữ liệu tử cảm biến nhiệt độ độ ẩm cùng 3 trạng thái LED gửi lên HTTP server qua API và lưu các đữ liệu vào database thông qua các API
def make_data(api, id, time, device, temp, humi, led1, led2, led3):
Trang 17return response_ data
def record_serializer(data_post) -> dict:
def data_list(datas) -> list:
return [record_serializer(data) for data in datas]
Trang 18
-17-Yêu cẦ 5: Giải thích tác dụng của từng dòng mã ngu Ên được bổ sung vào (kể cả các hàm, các chương trình con tham khảo)
Chương trình chính cla HTTP server tao ra cdc API nhận các dữ liệu nhiệt độ, độ
ẩm và 3 giá trị trạng thái LED
import base64 Khai báo sử dụng thư viện base64
Thư viện dùng để mã hóa hoặc giải
mã dữ liệu dạng base6G4 (thưởng dùng cho hình ảnh hoặc dữ liệu nhị phân)
from io import BytesIO Khai báo st dung ham BytesIO ctia
thu vién io Dùng để xử lý dữ liệu nhị phân trong bộ nhớ như một đối tượng I/O
from fastapi import FastAPI Khai báo sử dụng hàm FastAPI của
thư viện fastapi Một thư viện để xây dựng ứng dụng web API
from fastapi.responses import
HTMLResponse
Khai báo sử dụng hàm HTMLResponse của thư viện fastapi Dùng để trả v`ềphản h`ổ dạng HTML tử một API
import uvicorn Khai báo sử dụng thư viện uvicorn
Uvicorn la mét ASGI server chạy các ứng dụng web như FastAPI, để
sử dụng server này khi chạy ứng dụng
from pymongo import MongoClient Khai báo sử dung ham MongoClient
của thư vién pymongo PyMongo là thư viện Python để tương tác, thiết lập kết nối đến MongoDB
from pydantic import BaseModel Khai báo sử dụng hàm BaseModel
của thư viện pydantic pydantic là một thư viện giúp xác thực dữ liệu
và tạo mô hình dữ liệu BaseModel được dùng làm lớp cơ sở cho mô hình dữ liệu trong FastAPI
from data_model import data_list Đồng này nhập dữ liệu hoặc mô
hình tử một module bên ngoài có tên data_ model
import matplotlib.pyplot as plt
Khai báo sử dụng thư viện
matplotlib Matplotlib la một thư vién pho bién dé tao biéu d 6va dS thi trong Python
Trang 19
app = FastAPIQ [ao ra một đối tượng ứng dụng
FastAPI Đây là ứng dụng chính mà các API sẽ được định nghĩa và chạy
Tạo kết nối đến MongoDB thông
qua một chuỗi kết nối Chuỗi kết nối
này sẽ kết nối đến các cơ sở dữ liệu của database và có thể tương tác với các database
mydb = myclient["buoi8_database"] Thỏ đến cơ sở dữ liệu có tên là
"buoi8_ database"
mycol = mydb["Sensor Data"] Dong này trd dén collection "Sensor
Data" trong cơ sở dữ liệu
Collection trong MongoDB 1a noi lưu trữ các tai ligu (documents) tương tự như các bảng trong cơ sở
dữ liệu quan hệ
class Item(BaseModel): Định nghĩa một lớp đữ liệu tên là
ltem, kế thừa từ BaseModel của pydantic Lớp này dùng để mô tả dữ liệu mà API sẽ nhận hoặc trả về,
d tng thoi dam bao rang dif liéu được xác thực đúng kiểu
api: str Thusc tinh nay dai dién cho API
dưới dạng chuỗi (string)
id: int ID của dữ liệu, là một số nguyên
(int) time: str Thời gian ghi nhận dữ liệu, dạng
chuỗi (string) device: str Khai báo tên hoặc mã thiết bị, dang
chuỗi (string) temp: float Nhiệt độ mà cảm biến đo được,
dạng foat (số thực) humi: float Độ ẩm mà cảm biến đo được, dạng
float (số thực) led1: int Trang thái của céc LED (LED1, led2: int LED2, LED3), dang s& nguyén (int) led3: int
IÍ_ name_ ==" main": Đòng này kiểm tra tập tin có đang uvicorn.run(app, host="0.0.0.0", được chạy trực tiếp hay không port=8000) Nếu đi lân kiện trên đúng, ứng dụng
FastAPI sẽ được chạy bởi Uvicorn Tham số:
app: Là đối tượng FastAPI đã tạo ở
Trang 20
trên host="0.0.0.0": Ung dụng sẽ lắng nghe trên tất cả các địa chỉ IP của máy chủ
port=8000: Cổng mà ứng dụng sẽ chạy (8000)
Các chương trình con của HTTP server tạo ra các API nhận các dữ liệu nhiệt độ, độ
ẩm và 3 giá trị trạng thái LED
@app.get("/data_post") mm ay la mét decorator trong
FastAPI, dinh nghia mét endpoint API cho phương thức
GET tại đường dẫn /data_ post
Hàm get_ data_ post sẽ được sử dụng để xử lý yêu cân khi người dùng truy cập endpoint này với phương thức GET
Hai tham số được yêu cân cho hàm này
api: str: Đây là một chuỗi
(string) chứa API key mà người dùng cung cấp để xác thực
number: int: SO luong dir liéu
mà người dùng muốn truy xuất được hiển thị bằng một số nguyên
v`ềmệt đối tượng JSON với:
"status": "ok": Trang thai yêu
c a thành công
"data": number_data: Dvr liéu
từ MongoDB đã được truy vấn
Trang 21else: Néu API key sai, tra v €mét ddi
return {"API KEY bi sai"} tượng JSON với thông báo lỗi
"API KEY bi sai", théng bao rằng khóa API người dùng cung cấp không chính xác
@app.get("/data:id") mm ây là một decorator trong
FastAPI, định nghĩa một API endpoint cho phương thức GET
tại đường dẫn /data:id
async def get_record_by_time(start: str, end:
str):
Định nghĩa một hàm bất đ ông bộ (asynchronous function) để xử lý các yêu c âi TET
Hàm nhận hai tham số đầu vào từ yêu c3 GET:
s(art: Một chuỗi (string) đại điện cho thời gian bất đầu
end: Một chuỗi (string) đại diện cho thời gian kết thúc
Đây có thể là các timesfamp (thời
gian dưới dang chuỗi) để giới hạn
khoảng thơi gian của dữ liệu cn truy vấn từ cơ sở dữ liệu
"status": "ok": Tra v €trang thai cua yéu c 4 1a "ok", nghia la yêu c& da được xử lý thành công
"đata": number_record: Trả v`êdữ liệu kết quả (danh sách các bản ghi) từ MongoDB, đã được lọc theo thời gian
@app.post("/update_post") les)
ay la mét decorator trong FastAPI, định nghĩa một API endpoint cho phương thức POST
tại đường dan /update_post
-21-
Trang 22
async def update_data_post(item: Item): h7 ¡nh nghĩa một hàm bất đ ông bộ
(asynchronous function) để xử lý yêu c3 POST
Hàm nhận đ3n vào là một đối tượng ifem của lớp Item, được định nghĩa trước đó trong mã Item chứa các trưởng đữ liệu như
id, time, device, temp, humi, led1, led2, led3 va api
bị, nhiệt độ, độ aim, va trang thai cua 3 LED (led1, led2, led3)
return {"Da gui du lieu theo phuong thuc
POST thanh cong"}
thông tin từ đối tượng item) vào collection mycol trong MongoDB Tra v €chudi JSON thông báo
> ~ 1° ÄA ~ rd `
răng dữ liệu đã được gửi và lưu thành công vào MongoDB thông qua phương thức POST
else: Nếu API không họp lệ:
return {"API Key bi sai"} Trả v`êphản h ổ JSON với thông
báo rằng API key sai, từ chối yêu c3 lưu dữ liệu
@app.get("/update_get") ay la mét decorator trong
FastAPI, dinh nghia mét API endpoint cho phương thức GET tại
đường dẫn /update_ get
async def update_data_get(item: Item): ịnh nghĩa một hàm bất đ ông bộ
(asynchronous function}) để xử lý yéu ca GET
Hàm nhận đẦn vào là một đối tượng ifem của lớp Item, được định nghĩa trước đó trong mã Item chứa các trưởng đữ liệu như ¡d,
Trang 23
time, device, temp, humi, led1, led2, led3 va api
3 LED (led1, led2, led3)
return {"Da gui du lieu theo phuong thuc
GET thanh cong"}
thông tin từ đối tượng item) vào collection mycol trong MongoDB Tra v échudi JSON thông báo rằng
dữ liệu đã được gửi và lưu thành công vào MongoDB thông qua phương thức POST
else: Nếu API không họp lệ:
return {"API KEY bi sai"} Tra v phan h‘@ JSON voi théng
báo rằng API key sai, từ chối yêu c3 lưu dữ liệu
def get_data(Q): Định nghĩa hàm get_ dataQ
Hàm get_ dataQ truy vấn dữ liệu tử một collection trong MongoDB va lưu trữ các giá trị tử các trưởng cụ thể vào các danh sách tương ứng
data = mycol.findQ Đây là lệnh để truy vấn tất cả
dữ liệu tử collection mycol trong MongoDB mycol là một đối tượng của collection MongoDB đã được kết nối trước đó
Trang 24for item in data: Duyệt qua từng bản ghi (item)
trong kết quả truy vấn data
humi_data.append(item["humi"]) Tiong mdi | lặp, giá trị của
trang_ thai_ led3.append(tem[ "led3 "]) item["humi"]: Độ ẩm được
thêm vào humi_data
item["temp"]: Nhiét độ được thêm vào temp_ data
item["id"]: ID dworc thém vao id_values
item["led1"], item["led2"], item["led3"]: Trang thai cia các đèn LED l8 lượt được thêm vào các danh sách tương ứng
temp_ data):
refurn ( Hàm trả v ềcác giá trị tương
humi_data, ứng của các trưởng từ cơ sở temp_data, dữ liệu MongoDB
Trang 25temp_ data: Danh sách chứa các giá trị nhiệt độ
plt.ñgureQ Tao mét figure moi dé vé
biéu d%4 Di G nay cho phép bat di vé mot biéu
đ ồmới mà không làm ảnh hưởng đến bất kỳ biểu đ ônào trước đó
color="blue": Chon mau xanh cho đương biểu diễn độ ẩm
độ ẩm và đường nào đại điện cho nhiệt độ