AI Hunter
Member
Nhiệm vụ hôm nay:
1. Dạy Python Server cách "nghe" dữ liệu từ MQTT.
2. Vẽ thêm đồng hồ đo Nhiệt độ & Độ ẩm lên ứng dụng Mobile.
3. Tận hưởng cảm giác nhìn điện thoại nhảy số tanh tách.
Hiện tại Server chỉ biết "nói" (Gửi lệnh Bật/Tắt). Giờ nó phải biết "nghe" (Nhận dữ liệu cảm biến).
Mở file
Phần 1: Thêm biến lưu trữ và Topic mới
Phần 2: Cập nhật hàm xử lý MQTT
Chúng ta cần sửa hàm `on_connect` (để đăng ký nghe tin) và thêm hàm `on_message` (để xử lý tin).
Phần 3: Cập nhật API lấy dữ liệu
Sửa API
*Lưu ý:* Hãy restart lại Server sau khi sửa code (
Quay lại dự án React Native. Chúng ta cần vẽ thêm 2 cái thẻ (Card) để hiện nhiệt độ và độ ẩm.
Mở file
Bước 1: Sửa hàm `fetchStatus` để tự động cập nhật
Chúng ta cần dùng
Bước 2: Vẽ UI hiển thị cảm biến
Thêm đoạn code này vào bên trên phần danh sách thiết bị trong
Bước 3: Thêm Styles
Vậy là Jarvis đã hoàn thiện các giác quan cơ bản. Nó có thể nhìn (Camera), nghe (Micro), cảm nhận (DHT11) và hành động (Relay).
Tuy nhiên, có một vấn đề: Hiện tại bạn phải tự nhìn vào App thấy nóng thì mới bấm quạt.
Tại sao Jarvis không tự làm việc đó?
"Nhiệt độ > 32 độ -> Tự bật quạt". Đây chính là Automation (Tự động hóa) - đỉnh cao của Smart Home.
1. Dạy Python Server cách "nghe" dữ liệu từ MQTT.
2. Vẽ thêm đồng hồ đo Nhiệt độ & Độ ẩm lên ứng dụng Mobile.
3. Tận hưởng cảm giác nhìn điện thoại nhảy số tanh tách.
1. Nâng cấp Backend (server.py)
Hiện tại Server chỉ biết "nói" (Gửi lệnh Bật/Tắt). Giờ nó phải biết "nghe" (Nhận dữ liệu cảm biến).
Mở file
backend/server.py và cập nhật các phần sau:Phần 1: Thêm biến lưu trữ và Topic mới
Python:
# ... (Giữ nguyên các import cũ) ...
MQTT_TOPIC_SENSOR = "home/livingroom/sensor" # <--- Thêm dòng này
# Biến toàn cục lưu trữ dữ liệu cảm biến mới nhất
sensor_state = {
"temp": 0,
"hum": 0
}
# ... (Giữ nguyên home_state) ...
Phần 2: Cập nhật hàm xử lý MQTT
Chúng ta cần sửa hàm `on_connect` (để đăng ký nghe tin) và thêm hàm `on_message` (để xử lý tin).
Python:
# Hàm xử lý khi nhận tin nhắn từ Broker
def on_message(client, userdata, msg):
global sensor_state
try:
payload = msg.payload.decode()
print(f"📩 Nhận dữ liệu: {payload} từ {msg.topic}")
# Parse JSON từ ESP32 gửi lên
data = json.loads(payload)
# Cập nhật vào RAM
if "temp" in data and "hum" in data:
sensor_state["temp"] = data["temp"]
sensor_state["hum"] = data["hum"]
except Exception as e:
print(f"⚠️ Lỗi xử lý MQTT: {e}")
# Hàm khi kết nối thành công
def on_connect(client, userdata, flags, rc):
print(f"📡 Đã kết nối MQTT Broker! Code: {rc}")
# Đăng ký nhận tin từ topic cảm biến
client.subscribe(MQTT_TOPIC_SENSOR)
# ... (Phần khởi tạo MQTT Client) ...
mqtt_client.on_connect = on_connect
mqtt_client.on_message = on_message # <--- Gán hàm xử lý tin nhắn
# ...
Phần 3: Cập nhật API lấy dữ liệu
Sửa API
/devices để nó trả về cả trạng thái đèn VÀ cảm biến.
Python:
@app.get("/devices")
async def get_devices():
# Trả về cả thiết bị và cảm biến
return {
"devices": home_state,
"sensors": sensor_state
}
*Lưu ý:* Hãy restart lại Server sau khi sửa code (
Ctrl+C và chạy lại).2. Nâng cấp Frontend (App.js)
Quay lại dự án React Native. Chúng ta cần vẽ thêm 2 cái thẻ (Card) để hiện nhiệt độ và độ ẩm.
Mở file
App.js, tìm đến component DashboardScreen.Bước 1: Sửa hàm `fetchStatus` để tự động cập nhật
Chúng ta cần dùng
setInterval để App tự động hỏi Server mỗi 2 giây.
JavaScript:
const DashboardScreen = ({ apiUrl, apiToken }) => {
const [data, setData] = useState({
devices: { light_living_room: false },
sensors: { temp: 0, hum: 0 }
});
useEffect(() => {
fetchStatus(); // Gọi ngay lần đầu
// Thiết lập vòng lặp gọi API mỗi 2 giây
const interval = setInterval(fetchStatus, 2000);
// Dọn dẹp khi thoát màn hình
return () => clearInterval(interval);
}, []);
const fetchStatus = async () => {
try {
// Gọi API mới (trả về cả devices và sensors)
const res = await axios.get(`${apiUrl}/devices`);
setData(res.data);
} catch (e) {
console.log("Polling error:", e.message);
}
};
// ... (Hàm toggleDevice giữ nguyên, nhớ sửa lại cách truy cập data.devices) ...
const toggleDevice = async (deviceId) => {
// Lưu ý: Sửa logic state cũ từ 'devices' thành 'data.devices'
// ...
};
Bước 2: Vẽ UI hiển thị cảm biến
Thêm đoạn code này vào bên trên phần danh sách thiết bị trong
return (...):
JavaScript:
// Import thêm icon Thermometer (Nhiệt độ) và CloudRain (Độ ẩm) từ lucide-react-native
return (
<ScrollView contentContainerStyle={styles.dashboardContainer}>
{/* --- PHẦN CẢM BIẾN MỚI --- */}
<Text style={styles.sectionTitle}>Môi trường</Text>
<View style={styles.sensorRow}>
{/* Thẻ Nhiệt độ */}
<View style={[styles.sensorCard, {backgroundColor: '#ff6b6b'}]}>
<Text style={styles.sensorLabel}>NHIỆT ĐỘ</Text>
<Text style={styles.sensorValue}>{data.sensors.temp}°C</Text>
</View>
{/* Thẻ Độ ẩm */}
<View style={[styles.sensorCard, {backgroundColor: '#4ecdc4'}]}>
<Text style={styles.sensorLabel}>ĐỘ ẨM</Text>
<Text style={styles.sensorValue}>{data.sensors.hum}%</Text>
</View>
</View>
{/* --- PHẦN THIẾT BỊ CŨ --- */}
<Text style={styles.sectionTitle}>Living Room</Text>
{/* ... (Code cũ giữ nguyên, nhớ sửa truy cập state thành data.devices.light_living_room) ... */}
</ScrollView>
);
Bước 3: Thêm Styles
JavaScript:
const styles = StyleSheet.create({
// ... (Styles cũ) ...
sensorRow: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 20,
},
sensorCard: {
width: '48%',
borderRadius: 15,
padding: 20,
alignItems: 'center',
justifyContent: 'center',
elevation: 5,
},
sensorLabel: {
color: '#fff',
fontSize: 12,
fontWeight: 'bold',
opacity: 0.8,
marginBottom: 5,
},
sensorValue: {
color: '#fff',
fontSize: 32,
fontWeight: 'bold',
}
});
3. Kết quả
- Khởi động lại Server Python.
- Khởi động lại App (Reload Expo).
- Đảm bảo ESP32 đang chạy và gửi dữ liệu (xem Serial Monitor).
- Nhìn vào màn hình điện thoại:
- Bạn sẽ thấy 2 ô màu Đỏ (Nhiệt độ) và Xanh (Độ ẩm).
- Con số sẽ tự động cập nhật mỗi 2 giây.
- Thử hà hơi vào cảm biến -> Số trên điện thoại nhảy lên ngay lập tức.
- Bạn sẽ thấy 2 ô màu Đỏ (Nhiệt độ) và Xanh (Độ ẩm).
Tổng kết
Vậy là Jarvis đã hoàn thiện các giác quan cơ bản. Nó có thể nhìn (Camera), nghe (Micro), cảm nhận (DHT11) và hành động (Relay).
Tuy nhiên, có một vấn đề: Hiện tại bạn phải tự nhìn vào App thấy nóng thì mới bấm quạt.
Tại sao Jarvis không tự làm việc đó?
"Nhiệt độ > 32 độ -> Tự bật quạt". Đây chính là Automation (Tự động hóa) - đỉnh cao của Smart Home.
Bài viết liên quan