import network
import time
import dht
import ujson
import urandom
from machine import Pin, I2C
from umqtt.simple import MQTTClient
# --- CẤU HÌNH WIFI & THINGSBOARD ---
WIFI_SSID = "Wokwi-GUEST"
WIFI_PASSWORD = ""
THINGSBOARD_SERVER = "eu.thingsboard.cloud"
PORT = 1883
TOKEN = "0ID7ZHr8cJ3xAMigN3lQ"
# --- KHỞI TẠO PHẦN CỨNG ---
# Khởi tạo LED
led1 = Pin(25, Pin.OUT)
led2 = Pin(33, Pin.OUT)
led3 = Pin(32, Pin.OUT)
led4 = Pin(26, Pin.OUT)
led5 = Pin(27, Pin.OUT)
# Khởi tạo DHT22
sensor = dht.DHT22(Pin(15))
# Khởi tạo I2C LCD (Lưu ý: Cần tải file thư viện pico_i2c_lcd.py hoặc esp8266_i2c_lcd.py vào vi điều khiển)
# i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
# lcd = I2cLcd(i2c, 0x27, 4, 20)
# Biến trạng thái
device_value_5 = 0
# --- CÁC HÀM XỬ LÝ ---
def connect_wifi():
print("Connecting to AP ...")
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect(WIFI_SSID, WIFI_PASSWORD)
while not sta_if.isconnected():
time.sleep(0.5)
print(".", end="")
print("\nConnected to AP")
return sta_if
def on_message(topic, msg):
"""Hàm callback xử lý dữ liệu nhận được từ ThingsBoard (RPC và Attributes)"""
global device_value_5
print("Received topic:", topic)
data = ujson.loads(msg)
# 1. Xử lý RPC (nhận lệnh thay đổi switch)
if b'rpc/request' in topic:
if data.get('method') == 'set_switch':
device_value_5 = data.get('params', {}).get('switch', device_value_5)
print("Value change:", device_value_5)
# Gửi phản hồi RPC (Lấy request ID từ topic)
req_id = topic.decode().split('/')[-1]
client.publish(f"v1/devices/me/rpc/response/{req_id}", ujson.dumps({"response": 1}))
# Cập nhật attribute lên server
client.publish(b"v1/devices/me/attributes", ujson.dumps({"deviceValue5": device_value_5}))
# 2. Xử lý Shared Attributes (nhận lệnh thay đổi LED)
elif b'attributes' in topic:
if 'deviceState1' in data:
led1.value(data['deviceState1'])
print("deviceState1 is set to:", data['deviceState1'])
if 'deviceState2' in data:
led2.value(data['deviceState2'])
if 'deviceState3' in data:
led3.value(data['deviceState3'])
if 'deviceState4' in data:
led4.value(data['deviceState4'])
if 'deviceState5' in data:
led5.value(data['deviceState5'])
# --- CHƯƠNG TRÌNH CHÍNH ---
sta_if = connect_wifi()
# Thiết lập MQTT Client (Sử dụng Token làm Username)
client = MQTTClient("esp32_client", THINGSBOARD_SERVER, port=PORT, user=TOKEN, password="")
client.set_callback(on_message)
try:
client.connect()
print("Connected to ThingsBoard")
# Đăng ký nhận RPC commands và Shared Attributes
client.subscribe(b"v1/devices/me/rpc/request/+")
client.subscribe(b"v1/devices/me/attributes") # Đã sửa thụt lề vào đây
print("Subscribe done")
except Exception as e:
print("Failed to connect/subscribe to MQTT:", e)
while True:
try:
# Kiểm tra tin nhắn mới (non-blocking)
client.check_msg()
# Đọc cảm biến
sensor.measure()
t = sensor.temperature()
h = sensor.humidity()
# Gửi Dữ liệu Telemetry
telemetry = {
"tempIndoor": str(round(t, 1)),
"humidity": h,
"deviceValue5": device_value_5,
"tempOutdoor": urandom.getrandbits(4) + 10, # random từ 10-25
"energy": urandom.getrandbits(4) + 10
}
client.publish(b"v1/devices/me/telemetry", ujson.dumps(telemetry))
# Gửi Thuộc tính (Attributes) thiết bị
attributes = {
"rssi": sta_if.status('rssi'),
"localIp": sta_if.ifconfig()[0],
"ssid": WIFI_SSID
}
client.publish(b"v1/devices/me/attributes", ujson.dumps(attributes))
# In log ra Serial
print(f"Temp {t}°C | Humidity {h}%")
print("---")
time.sleep(2)
except OSError as e:
print("Error:", e)
time.sleep(2)