3、阿里云IoT平台接入:产品与设备创建、设备证书、Topic定义与权限、设备端SDK接入(Python SDK)

好,咱们进入第三章。这一章我打算手把手带你走一遍阿里云IoT平台的接入流程。说实话,很多新手一上来就被「产品」「设备」「证书」「Topic」这些概念搞晕了。别急,咱们一个一个拆开讲。

我个人习惯,先搭好平台上的东西,再写代码。这样思路清晰,调试也方便。你想想看,如果代码写完了,发现平台上产品没创建,那多尴尬。

3.1 产品与设备创建

先说说「产品」和「设备」的区别。产品是一个抽象的概念,比如「智能灯泡」「智能插座」。设备是具体的实例,比如「客厅的灯泡」「厨房的插座」。一个产品下面可以挂成千上万个设备。

登录阿里云IoT平台控制台,找到「公共实例」或者「企业实例」。我个人建议新手先用公共实例,免费额度够你折腾一阵子。

创建产品的步骤很简单:

  1. 点击「创建产品」
  2. 填写产品名称,比如「智能照明灯」
  3. 选择节点类型:设备直连
  4. 选择数据格式:Alink JSON(默认)
  5. 点击确认

嗯,这里要注意一个坑。数据格式选Alink JSON,别选透传。透传虽然省流量,但调试起来太痛苦了。我在项目中遇到过,客户非要透传,结果每次排查问题都要拿十六进制转来转去,效率极低。

产品创建好之后,就可以添加设备了。点击「设备管理」→「添加设备」,输入DeviceName(设备名称)。如果不填,平台会自动生成一个。我建议你手动填,比如light_001,这样后期管理方便。

关键点:设备创建成功后,系统会生成三个核心证书:ProductKey、DeviceName、DeviceSecret。这三个东西,说白了就是设备在云上的身份证。丢了任何一个,设备都连不上平台。

3.2 设备证书详解

咱们来仔细看看这三个证书:

证书名称 含义 是否可变
ProductKey 产品唯一标识,同一产品下所有设备共享 不可变
DeviceName 设备名称,同一产品下唯一 不可变
DeviceSecret 设备密钥,用于身份认证 可重置

为什么会设计成三个?我刚开始也纳闷。后来做多了才明白,ProductKey相当于你家小区地址,DeviceName是门牌号,DeviceSecret是钥匙。三者缺一不可。

避坑指南:我曾经在项目里把DeviceSecret写死在代码里,结果设备出货后想改密钥,得一个个去刷固件。那叫一个酸爽。后来我学乖了,证书都存到配置文件中,或者用烧录工具在产线写入。

3.3 Topic定义与权限

Topic,说白了就是消息的「主题」。设备发消息叫「发布」,设备收消息叫「订阅」。阿里云IoT平台默认提供了几个标准Topic:

  • /sys/{ProductKey}/{DeviceName}/thing/event/property/post — 设备上报属性
  • /sys/{ProductKey}/{DeviceName}/thing/service/property/set — 云端下发属性设置
  • /sys/{ProductKey}/{DeviceName}/thing/event/property/post_reply — 属性上报的回复

每个Topic都有权限控制,分为「发布」和「订阅」。比如设备上报属性的Topic,设备端只能发布,不能订阅。云端下发属性的Topic,设备端只能订阅,不能发布。

我个人习惯,在创建产品时就把Topic定义好。点击产品详情页的「Topic类列表」,可以自定义Topic。比如我定义一个/user/{ProductKey}/{DeviceName}/light/control,用来接收手机App发来的开关指令。

注意:自定义Topic的权限要仔细设置。我曾经见过一个项目,把控制Topic设成了「发布和订阅」,结果设备端也能往这个Topic发消息,导致控制指令被篡改。安全无小事啊。

3.4 设备端SDK接入(Python SDK)

好,平台上的东西准备好了,咱们开始写代码。阿里云提供了Python SDK,叫aliyun-iot-linkkit。安装很简单:

pip install aliyun-iot-linkkit

嗯,这里要注意Python版本。SDK支持Python 3.6以上,我建议用3.8或3.9,兼容性最好。

咱们写一个最简单的设备端程序,实现连接平台和上报属性:

from linkkit import linkkit
import time
import json

# 设备证书
product_key = "你的ProductKey"
device_name = "light_001"
device_secret = "你的DeviceSecret"

# 初始化LinkKit
lk = linkkit.LinkKit(
    host_name="cn-shanghai",
    product_key=product_key,
    device_name=device_name,
    device_secret=device_secret
)

# 连接成功回调
def on_connect(session_flag, rc, userdata):
    print("连接成功,返回码:", rc)

# 连接
lk.on_connect = on_connect
lk.connect_async()
lk.start()

# 上报属性
def report_property():
    payload = {
        "LightSwitch": 1,  # 1表示开,0表示关
        "Brightness": 80   # 亮度0-100
    }
    rc, request_id = lk.thing_post_property(
        params=payload,
        identifier="LightSwitch"
    )
    print("上报结果:", rc)

# 每秒上报一次
while True:
    report_property()
    time.sleep(1)

这段代码看起来简单,但有几个关键点我得提醒你:

  • host_name要填对,不同地域不一样。我一般用cn-shanghai
  • thing_post_propertyidentifier参数,对应你在平台上定义的属性标识符。别写错了,否则平台不认。
  • 连接是异步的,所以要先connect_async()start()

经验之谈:我在实际项目中,从来不会在while循环里直接上报。一般会加个判断,只有属性变化时才上报。否则设备多了,平台流量费能让你哭出来。

再来看订阅云端指令的代码:

# 订阅属性设置指令
def on_property_set(identifier, params, userdata):
    print("收到属性设置:", identifier, params)
    if identifier == "LightSwitch":
        if params["LightSwitch"] == 1:
            print("开灯")
        else:
            print("关灯")

lk.on_property_set = on_property_set

这段代码订阅了云端下发的属性设置。当你在控制台或者App上修改设备属性时,设备端就会收到回调。

最后,别忘了断开连接:

lk.disconnect()

好了,这一章的内容就这些。从产品创建到设备证书,从Topic定义到SDK接入,咱们都过了一遍。下一章我会讲如何用MQTT协议直接接入,不用SDK,让你更深入地理解底层原理。