4135 字
21 分钟
页面浏览--访问次数--
第三章 华为云 IoTDA 物联网入门-北向

这章来讲讲鸿蒙北向吧 如果你是学鸿蒙北向的同学,多半会遇到这样的需求:

“我们南向的设备把心率数据传到云上了,你做个 App 把数据显示出来,再做个按钮能控制风扇开关。”

这一章就是为解决此问题而出的教程


第一部分 #

物联网项目里其实有三条链路,初学最容易在脑子里搅成一团:

flowchart LR
    subgraph S["南向:设备侧"]
        D["① 硬件设备传感器 / 单片机"]
    end
    subgraph C["云:华为云 IoTDA"]
        P["② 物联网平台"]
    end
    subgraph N["北向:应用侧"]
        A["③ 手机 App鸿蒙 / 网页 / 上位机"]
    end
    D -->|"MQTT 上报数据"| P
    P -->|"MQTT 下发命令"| D
    A -->|"HTTPS 调 API 读数据"| P
    A -->|"HTTPS 调 API 下发命令"| P

三条链路的分工:

链路谁到谁用什么协议谁负责
① → ②设备 → 云MQTT硬件同学
② → ①云 → 设备MQTT(下行)硬件同学
③ ↔ ②App ↔ 云HTTPS / REST API你

设备用 MQTT 跟云说话,App 用 HTTPS 跟云说话。

设备走的是 MQTT,你走的是 HTTP 那一套,所以第二章学的 HTTP 请求、请求头、JSON、Content-Type,在这里全都能直接用上。 :::

1.1 为什么设备用 MQTT,而不用 HTTP?#

你可能会问:既然 HTTP 这么好用,为什么设备不也用 HTTP?

sequenceDiagram
    autonumber
    participant D as 设备
    participant C as 云平台
    Note over D,C: HTTP:设备必须主动问
    D->>C: 有没有给我的命令?
    C-->>D: 没有
    D->>C: 有没有给我的命令?
    C-->>D: 没有
    Note over D,C: MQTT:云可以直接推
    D->>C: 建立长连接 + 订阅我的主题
    C-->>D: 有命令了,推给你!
HTTPMQTT
通信模式请求-响应(只能客户端先发起)发布-订阅(双方都能主动推)
连接短连接,用完就断长连接,一直挂着
开销头部信息大头部极小(最小只要 2 字节)
适合网页、调 API设备、传感器、弱网、省电场景

回想第二章讲的”HTTP 是无状态的、服务器不能主动给你发消息”,这正是设备场景不能忍的地方。

一台体温计不可能每隔几秒就跑去问云”有没有新命令”(那又费电又费流量)。它需要的是:连上就别断,云那边一有命令,立刻推过来。这就是 MQTT 的发布-订阅模型。

MQTT 的核心概念:主题(Topic)

MQTT 不靠”你问我答”,而是靠主题:

  • 设备订阅某个主题,就相当于”我盯着这个频道的消息”
  • 谁发布到这个主题,订阅者就会收到

比如设备订阅了 $oc/devices/{设备ID}/sys/commands/#,那么云平台往这个主题发布一条命令,设备立刻就能收到。

# 是通配符,表示”这个目录下的所有子主题”。

2. 云平台在中间干了什么#

华为云 IoTDA(设备接入服务)扮演的是中间人 + 账本的角色:

  • 设备管理:谁注册过、在不在线、是什么型号
  • 消息转发:把设备上报的数据收下来
  • 数据存储:把设备最新状态存成”设备影子”,这就是你待会儿要读的东西
  • 命令下发:把你调的 API 请求,转成 MQTT 消息推给设备

第二部分 南向:设备是怎么接进来的#

这部分内容平时是硬件同学在做,但你必须看懂,因为你要拿的就是这些配置信息。

3. 在 IoTDA 控制台上做四件事#

设备侧的四步

  1. 创建产品

    产品 = 一类设备的”型号定义”。比如”智慧养老手环”就是一个产品。

  2. 创建服务

    服务 = 一个产品下面的一组功能集合。你可以先粗略理解成”一个大产品里包含的某个小硬件”。

    这一步基本上只需要你填一个服务 ID,记住它,后面会反复用到。

  3. 创建属性

    属性 = 具体的数据项,比如心率、血氧、体温。

    创建时要填名称和数据类型(整数、小数、字符串、布尔……),名称就是数据名。

  4. 注册设备

    设备 = 这个产品下的一台具体硬件。设备标识码和密钥可以自己填,注册完成后平台会给你一份信息,里面有设备 ID 和密钥:这两个东西千万别弄丢,也千万别外传。

3.1 属性到底要不要建?#

有个常见的纠结:我到底该不该建属性?

按数据流向分两种情况:

  • 需要把数据实时读到 App 里 → 建属性,让设备上报
  • 只是 App 往设备下发命令(比如开关风扇),不需要回传数据 → 可以不建属性

4. MQTT 三元组:设备登录云的”账号密码”#

设备要连上云,需要三个东西,俗称 MQTT 三元组:

名称作用从哪来
ClientId(客户端 ID)我是哪台设备由工具根据设备 ID 生成
Username(用户名)我属于哪个设备通常是 {设备ID}
Password(密码)证明我真的是那台设备由密钥签名算出

华为云提供了一个在线工具,把设备 ID 和密钥填进去,三元组自动生成:

https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/

生成出来的东西大概长这样(下面是占位符,不是真实值):

ClientId:{设备ID}_0_0_{时间戳}
Username:{设备ID}
Password:{根据密钥算出的签名}

第三部分 没有硬件,怎么先跑起来#

手头没有硬件怎么办?用 MQTT 客户端软件模拟一台设备。 这样你可以先把整条链路跑通,等硬件到了直接替换。

推荐用 MQTTX(跨平台,界面清爽)。

5. 连接信息从哪找#

在 IoTDA 控制台的设备详情页里,能找到设备接入地址:

配置项值
服务器地址{你的设备接入域名}(形如 xxxxxx.st1.iotda-device.cn-north-4.myhuaweicloud.com)
端口1883(非加密)/ 8883(TLS 加密)—— 端口号是固定的
ClientId / Username / Password上一节生成的三元组

6. 发布和订阅#

连上之后,就要用**主题(Topic)**收发数据了。IoTDA 的主题格式是固定的,你只需要把 {设备ID} 换成自己的:

你要干什么主题动作
上报属性(设备 → 云)$oc/devices/{设备ID}/sys/properties/report发布(Publish)
订阅命令(云 → 设备)$oc/devices/{设备ID}/sys/commands/#订阅(Subscribe)
订阅属性设置(云 → 设备)$oc/devices/{设备ID}/sys/properties/set/#订阅(Subscribe)

6.1 上报的数据长什么样#

上报属性的内容就是 JSON,格式是固定的两层结构:services 数组 → 里面是 service_id 和 properties:

{
"services": [
{
"service_id": "health",
"properties": {
"heart_rate": 78,
"spo2": 98,
"temperature": 36.5
}
}
]
}

6.2 完整的通信流程#

sequenceDiagram
    autonumber
    participant D as 设备(或 MQTTX)
    participant C as 华为云 IoTDA
    participant A as 你的 App
    D->>C: ① 用三元组建立 MQTT 长连接
    D->>C: ② 订阅命令主题
    D->>C: ③ 发布属性(心率/血氧/体温)
    C->>C: ④ 更新设备影子
    A->>C: ⑤ 调 API 读设备影子(HTTPS)
    C-->>A: ⑥ 返回 JSON(含 reported 数据)
    A->>C: ⑦ 调 API 修改设备属性(下发命令)
    C-->>D: ⑧ MQTT 推送命令到设备
    D-->>A: (可选)设备上报新状态,App 再读一次影子

第四部分 北向:App 要调哪些接口#

动手写代码之前,有三个问题绕不开:

  1. 调用什么 API 接口获取设备上传的数据?
  2. 调用什么 API 接口下发命令给设备?
  3. 调用这些接口需要什么参数?

7. 先拿凭证:IAM Token#

App 要调华为云的接口,得先证明”我有权限”。这个凭证就是 Token。

7.1 准备好这几样东西#

名称说明
IAM 账号 / 密码你创建的子账号和密码
主账号名称企业管理员名称(华为云账号名)
AK / SKAccess Key / Secret Key,程序调用时用的密钥对
项目 IDProject ID,标识你的资源在哪个项目下

项目 ID 在哪找:控制台右上角 → 我的凭证 → 项目列表 → 点进你在做的项目,就能看到项目 ID 和所属区域。

AK/SK 怎么拿:找到右上角统一身份认证,创建一个子账号,创建并配置完成后就会得到 user name(IAM 账号名)、AK 和 SK。

7.2 用 API Explorer 生成 Token#

华为云的 API Explorer 可以在线帮你拼请求、直接调试、还会自动生成 SDK 代码,这是北向开发最省事的入口。

https://apiexplorer.developer.huaweicloud.com/

按顺序把参数填进去,遇到不确定的字段就用默认生成的,只要最后右边的「生成 Token」是成功的就说明配对了。

Token 有有效期,通常是 24 小时,过期就会返回 401。所以 App 里要处理”token 失效就重新获取”这件事。

8. 读数据:查询设备影子#

这是回答”调用什么接口获取设备上传数据”的答案。

项目内容
接口名查询设备影子数据(ShowDeviceShadow)
方法GET
文档API Explorer 搜 ShowDeviceShadow

请求地址的格式是:

GET https://{应用侧接入点}/v5/iot/{项目ID}/devices/{设备ID}/shadow
Header: X-Auth-Token: {你的 Token}

9. 下命令:两种方式#

回答第二个问题,怎么让 App 控制硬件。IoTDA 提供两条路:

方式特点
法一:下发命令(同步命令)语义明确,适合”立刻执行一次”的动作
法二:修改设备属性语义是”把设备改成这个状态”,更贴近物联网场景

两者除了接口不同,功能上没有本质区别。 下面用**法二(修改设备属性)**来演示,因为它跟前面的”属性”概念是连贯的。

项目内容
接口名修改设备属性(UpdateProperties)
方法PUT
地址https://{应用侧接入点}/v5/iot/{项目ID}/devices/{设备ID}/properties

下发命令的三个前提

  1. 保证设备在线

    设备离线的话,命令发不出去。先在控制台确认设备状态是”在线”。

  2. 填写数据

    想改哪个属性就写哪个,注意类型和名字要和建属性时一致。

  3. 构造并调试请求体

    请求体是 JSON,格式必须自己写对,写完先在 API Explorer 里调试通过。

请求体长这样:

{
"services": [
{
"service_id": "health",
"properties": {
"fan_switch": true
}
}
]
}

调试成功后,服务器就会把这条指令通过 MQTT 推给设备。设备收到 true,代码里做个字符串判断,就可以打开风扇。


第五部分 落到鸿蒙:北向 App 怎么写#

前面都是”看懂”,现在讲”写出来”。

10. 整体思路:四步走#

flowchart LR
    A["① 拿 TokenPOST IAM 接口"] --> B["② 读影子GET shadow"]
    B --> C["③ 显示到界面ArkTS UI"]
    C --> D["④ 下发命令PUT properties"]
    D --> B

11. ArkTS 里怎么发 HTTPS 请求#

鸿蒙应用侧用 @kit.NetworkKit 的 http 模块就能发 HTTPS 请求。

11.1 拿 Token#

import { http } from '@kit.NetworkKit';
const IAM_ENDPOINT = 'https://iam.cn-north-4.myhuaweicloud.com';
const PROJECT_NAME = 'cn-north-4';
export async function getToken(account: string, password: string, domain: string): Promise<string> {
const req = http.createHttp();
try {
const resp = await req.request(`${IAM_ENDPOINT}/v3/auth/tokens`, {
method: http.RequestMethod.POST,
header: { 'Content-Type': 'application/json' },
extraData: JSON.stringify({
auth: {
identity: {
methods: ['password'],
password: {
user: { name: account, password, domain: { name: domain } }
}
},
scope: { project: { name: PROJECT_NAME } }
}
})
});
// Token 不在 body 里,而是在响应头 X-Subject-Token 中
return resp.header['X-Subject-Token'] as string;
} finally {
req.destroy();
}
}

11.2 读设备影子#

const APP_ENDPOINT = '{你的应用侧接入点}';
const PROJECT_ID = '{你的项目 ID}';
const DEVICE_ID = '{你的设备 ID}';
export async function getShadow(token: string): Promise<ShadowResp> {
const req = http.createHttp();
try {
const resp = await req.request(
`https://${APP_ENDPOINT}/v5/iot/${PROJECT_ID}/devices/${DEVICE_ID}/shadow`,
{
method: http.RequestMethod.GET,
header: { 'X-Auth-Token': token }
}
);
return JSON.parse(resp.result as string) as ShadowResp;
} finally {
req.destroy();
}
}

11.3 下发命令(改属性)#

export async function setFan(token: string, on: boolean) {
const req = http.createHttp();
try {
return await req.request(
`https://${APP_ENDPOINT}/v5/iot/${PROJECT_ID}/devices/${DEVICE_ID}/properties`,
{
method: http.RequestMethod.PUT,
header: {
'X-Auth-Token': token,
'Content-Type': 'application/json' // 别忘了它,服务器才知道怎么解包
},
extraData: JSON.stringify({
services: [{ service_id: 'health', properties: { fan_switch: on } }]
})
}
);
} finally {
req.destroy();
}
}

12. 写在最后:几个能让作品加分的地方#

  1. 别把凭证写死在代码里 Token 有 24 小时有效期,AK/SK 更是永久凭证。比赛演示可以在本地配置,但提交的代码里一定要留占位符。

  2. 给状态加个”刷新”和”自动轮询” 设备状态会变,界面得能跟着变。最简单的做法是定时轮询影子接口(比如 3~5 秒一次),进阶可以用 WebSocket。

  3. 命令下发要有反馈 按钮点下去之后,别只是”发了请求”。要提示”发送中 / 成功 / 失败”,最好再读一次影子确认状态真的变了。

  4. UI 是评委最直观的感受 数据卡片、状态色块、开关动画,这些”面子工程”在比赛里真的很重要,而且这正是鸿蒙北向同学的核心优势。


13. 三条链路对照#

环节谁做用什么你要关心的
设备连上云硬件同学MQTT 三元组知道设备 ID 就行
设备上报数据硬件同学MQTT 发布到 properties/report知道服务 ID、属性名
云保存状态华为云 IoTDA设备影子记住 reported / desired
App 读数据你HTTPS GET .../shadow带 Token
App 下命令你HTTPS PUT .../properties设备在线 + JSON 正确

最后如果你在开发需要好用的API接口,你可以看看你想接入的任何产品接口文档,还有华为云自己的华为开发者联盟

第三章 华为云 IoTDA 物联网入门-北向
https://cnyicheng.top/posts/huawei-iotda-harmonyos-northbound/
作者
伊橙
发布于
2026-09-17
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取