import network, time, json, os, ubinascii, dht, ntptime
from machine import Pin, I2C
from umqtt.simple import MQTTClient
from ascon import ascon_aead_encrypt_64
from i2c_lcd import I2cLcd
# ---------- WIFI ----------
SSID = "Wokwi-GUEST"
PASSWORD = ""
# ---------- THINGSBOARD ----------
THINGSBOARD_HOST = 'eu.thingsboard.cloud'
ACCESS_TOKEN = 'vL6P9Ky7B8UEMfZxEtme'
CLIENT_ID = '10f5f230-2dcf-11f1-a3ea-950631e217c8'
TOPIC = 'v1/devices/me/telemetry'
# ---------- CRYPTO ----------
KEY = b'1234567890abcdef'
AD = b'esp32'
DIFF_SECONDS = 946684800
sensor = dht.DHT22(Pin(15))
# ---------- LCD INIT ----------
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
devices = i2c.scan()
lcd = None
print("--- SERIAL MONITOR ĐÃ HOẠT ĐỘNG ---")
if devices:
LCD_ADDR = devices[0]
lcd = I2cLcd(i2c, LCD_ADDR, 2, 16)
lcd.clear()
lcd.putstr("LCD Ready")
# ===============================
def get_formatted_time():
t = time.time() + 7*3600
st = time.localtime(t)
return "{:02d}:{:02d}:{:02d} {:02d}/{:02d}/{:04d}".format(
st[3], st[4], st[5], st[2], st[1], st[0]
)
# ---------- Nonce mới ----------
counter = 0
DEVICE_ID = ubinascii.crc32(b'esp32').to_bytes(4, 'big') # ví dụ: hash MAC/ID
def mix(x):
x ^= x >> 16
x *= 0x7feb352d
x ^= x >> 15
x *= 0x846ca68b
x ^= x >> 16
return x & 0xFFFFFFFF
def generate_nonce():
global counter
ts_unix = int(time.time() + DIFF_SECONDS) & 0xFFFFFFFF
ts_bytes = ts_unix.to_bytes(4, 'big')
ctr_bytes = counter.to_bytes(4, 'big')
raw = ts_bytes + DEVICE_ID + ctr_bytes
m = mix(counter).to_bytes(4, 'big')
mask = m * 4 # lặp đủ 128-bit
nonce = bytes([a ^ b for a, b in zip(raw, mask)])
counter = (counter + 1) & 0xFFFFFFFF
return nonce
# ---------- CONNECT WIFI ----------
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
while not wlan.isconnected():
time.sleep(0.5)
print("WiFi connected")
try:
ntptime.settime()
except:
pass
# ---------- MQTT ----------
client = MQTTClient("esp32_final", THINGSBOARD_HOST, user=ACCESS_TOKEN, password="")
client.connect()
print("MQTT connected")
# ===============================
while True:
try:
sensor.measure()
t = sensor.temperature()
h = sensor.humidity()
full_time = get_formatted_time()
# Dữ liệu ở dạng Plaintext (Không bảo mật)
# Gửi theo định dạng Key-Value để ThingsBoard tự hiểu
telemetry_data = {
"temperature": t,
"humidity": h
}
# Dữ liệu muốn hiển thị trong Client Attributes
attribute_data = {
"temperature_attr": t,
"humidity_attr": h,
"device_status": "Online",
"ip_address": wlan.ifconfig()[0]
}
# Gửi dữ liệu
# LOG ra màn hình Console
print(f"\n{full_time} | Temp: {t}°C | Humi: {h}%")
# ===== LCD DISPLAY =====
if lcd:
lcd.clear()
lcd.move_to(0, 0)
lcd.putstr("T:{:.1f} H:{:.1f}".format(t, h))
lcd.move_to(0, 1)
lcd.putstr(full_time[:16])
# Gửi dữ liệu trực tiếp lên ThingsBoard qua MQTT
client.publish(TOPIC, json.dumps(attribute_data))
# client.publish(TOPIC, json.dumps(telemetry_data))
print("Data sent to ThingsBoard")
except Exception as e:
print("Error:", e)
# Thử kết nối lại nếu MQTT bị ngắt
try:
client.connect()
except:
pass
time.sleep(60)