之前我們嘗試過直接把LED點亮并且閃爍。
今天嘗試一下将LED的開關狀态上雲,并可以通過雲來進行資料下發。
資料要上雲,首先開發闆要聯網。
首先我們會用 Python的network 庫, 在network庫當中,提供STA_IF和AP_IF兩種模式。其中進行連接配接的是使用STA_IF模式,如果使用AP_IF,則是将ESP32作為一個熱點。後面的文章當中我們會用到。
import network
import utime
WIFISSID = "Put your ssid here"
WIFIPWD = "Put yuou ssid password"
wlan = None
class ConnectWIFI:
def connect_wifi(self):
# network.STA_IF 站點也稱為用戶端,連接配接到上遊WiFi接入點
# network.AP_IF 作為熱點,允許其他WiFi用戶端接入。熱點模式允許使用者将自己的裝置配置為熱點,這讓多個裝置之間的無線連接配接在不借助外部路由器網絡的情況下成為可能。
wlan = network.WLAN(network.STA_IF)
wifi_connected = False
wlan.active(True)
wlan.scan()
wlan.connect(WIFISSID, WIFIPWD) # 定義好的SSID 和 密碼
while True:
# 判斷是否已經連接配接網絡
wifi_connected = wlan.isconnected()
if wifi_connected:
# 若沒有連接配接成功,則一直連接配接
break
else:
# 連接配接成功,進行提示
utime.sleep_ms(2000)
print("Wifi connet status :", wifi_connected)
ifconfig = wlan.ifconfig()
# 列印網絡情況
print(ifconfig)
當WI-FI已經連接配接成功後,我們的開發闆已經有了通訊的能力,下一步我們将我們的開發闆和阿裡雲物聯網平台進行連接配接。
在連接配接之前需要保證:
- 自己擁有阿裡雲賬戶
- 開通了IOT服務
-
已經注冊了對應的産品和裝置。
如果還沒有設定IOT的請看下面:
首先建立一個産品
設定産品的名稱,品類和其他資訊(2)用Micropython将ESP32資料上雲
完成産品建立後,進行産品物模型的定義
阿裡雲IOT平台提供了很多日常常用的一些标準功能,但是我們進行測試的話使用自定義功能。這樣能夠更好的了解每個功能裡面會有什麼樣的屬性。
完成産品添加後,需要添加裝置(即添加我們目前手裡使用的這個開發闆)
建立完成,并看到産品的資訊
這裡可以記一下三元組的概念,ProductKey, DeviceName, DeviceSecret 這三個東西能用來在資料通訊時進行開發闆的唯一性識别。
因為之前已經完成了連接配接WI-FI的代碼。是以,在WI-FI連接配接後,我們就需要将開發闆和阿裡雲物聯網連接配接。 我們直接使用HAAS提供的庫。 aliyunIoT
import utime
import ujson
from aliyunIoT import Device
from example.haas_led import HAASLed
iot_connected = False
device = None
# 物聯網平台連接配接成功的回調函數
def on_connect( data):
print('on_connect')
global iot_connected
iot_connected = True
def on_props(request):
led_entity = HAASLed()
led_entity.handle_iot_data(request)
class HaasIOT(object):
def report_data(self, data):
global device
upload_data = {'params': ujson.dumps(data)
}
device.postProps(upload_data)
def connect_iot(self):
self.test()
global device, iot_connected
key_info = {
'region': 'cn-shanghai',
'productKey': 'XXX',
'deviceName': 'XXX',
'deviceSecret': 'XXX',
'keepaliveSec': 60
}
device = Device()
# 設定連接配接到物聯網平台的回調函數,如果連接配接物聯網平台成功,則調用on_connect函數
device.on(Device.ON_CONNECT, on_connect)
# 配置收到雲端屬性控制指令的回調函數,如果收到物聯網平台發送的屬性控制消息,則調用on_props函數
device.on(Device.ON_PROPS, on_props)
# 啟動連接配接阿裡雲物聯網平台過程
device.connect(key_info)
# 等待裝置成功連接配接到物聯網平台
while(True):
if iot_connected:
print('物聯網平台連接配接成功')
break
else:
print('sleep for 1 s')
utime.sleep(1)
print('sleep for 2s')
utime.sleep(2)
代碼中的productKey, deviceName, deviceSecret分别對應到我們剛才在阿裡雲IOT平台上建立的裝置資訊。
main.py裡面的調用代碼
if __name__ == '__main__':
wifi_entity = ConnectWIFI()
wifi_connected = wifi_entity.connect_wifi()
if wifi_connected is True:
hass_iot_entity = HaasIOT()
hass_iot_entity.connect_iot()
将代碼燒錄到開發闆,我們會看到下面的資訊,表示開發闆已經完成WI-FI連接配接并和阿裡雲IOT平台連接配接成功。
Wifi connet status : False
Wifi connet status : False
('192.168.20.26', '255.255.255.0', '192.168.20.1', '11.11.2.69')
a test function
establish tcp connection with server(host='a1fuLmf5uts.iot-as-mqtt.cn-shanghai.aliyuncs.com', port=[443])
sleep for 1 s
tcp_connect: can only connect from state CLOSED
success to establish tcp, fd=54
on_connect
物聯網平台連接配接成功
在連接配接IOT平台的時候,通過了阿裡雲提供的回調方法 Device.on 注冊了 上報屬性的一個方法。
device.on(Device.ON_PROPS, on_props)
通過該回調,我們可以接收到IOT平台下發給裝置的資料,并進行處理。比如在本文當中,我們通過平台來控制3個LED燈開關。
在線上調試當中,可以對之前設定的3個屬性進行修改。(0表示關燈,1表示開燈)
該實作是用剛才的回調函數實作的。
def on_props(request):
led_entity = HAASLed()
led_entity.handle_iot_data(request)
在回調函數當中,物聯網平台下發的資料為request, 在這裡,我用了HAASLed當中的handle_iot_data方法進行處理。
物聯網平台下發的資料都是以一個dict傳輸過來的資料,形如:
{'code': 0, 'params_len': 20, 'msg_id': 659157818, 'params': '{"led_red_switch":0}'}
我們所需要擷取的資料就在 params當中。
def handle_iot_data(self, rsp):
print(type(rsp))
print(rsp) # {'code': 0, 'params_len': 20, 'msg_id': 659157818, 'params': '{"led_red_switch":0}'}
if rsp.get('code') == 0:
data = rsp.get('params')
led_switch = ujson.loads(data) # '{"led_red_switch":1}'
led_red_switch = led_switch.get('led_red_switch')
if led_red_switch is not None:
self.control_led("led_red_switch", led_red_switch)
led_green_switch = led_switch.get('led_green_switch')
if led_green_switch is not None:
self.control_led("led_green_switch", led_green_switch)
led_yellow_switch = led_switch.get('led_yellow_switch')
if led_yellow_switch is not None:
self.control_led("led_yellow_switch", led_yellow_switch)
def control_led(self,led, status):
r_led_gpio = GPIO()
y_led_gpio = GPIO()
g_led_gpio = GPIO()
r_led_gpio.open("r_led")
y_led_gpio.open("y_led")
g_led_gpio.open("g_led")
if led == "led_red_switch":
r_led_gpio.write(status)
elif led == "led_green_switch":
g_led_gpio.write(status)
elif led == "led_yellow_switch":
y_led_gpio.write(status)
可以看到,在代碼當中,首先将下發資料進行處理,并根據業務邏輯擷取到需要的内容,并調用control_led來進行LED燈的判斷。
對于從端上報資料上雲,則可以使用下面的代碼
def report_data(self, data):
global device
upload_data = {'params': ujson.dumps(data)
}
device.postProps(upload_data)
按照業務需要,将要傳送的資料拼接好後。使用device.postProps進行上報即可。所有的上報或者下發資料,都可以在日志服務當中檢視。
通過以上操作,成功的将ESP32 和 物聯網平台完成了通信。