万字技术指南STM32F103C8T6 + ESP8266-01 连接 OneNet 平台 MQTT/HTTP

此博客为一份详细的指南,涵盖 STM32F103C8T6 通过 ESP8266-01 连接 OneNet 平台,并使用 MQTT/HTTP 进行数据通信的完整流程。这份文档包括:

  • OneNet 平台的介绍与功能概览
  • 在 OneNet 上创建和配置设备的方法
  • STM32CubeIDE 的开发环境搭建
  • ESP8266 AT 指令解析及如何连接 OneNet
  • STM32 通过 MQTT 向 OneNet 发送/接收数据的详细实现
  • 使用 OneNet API 进行 HTTP 交互的方式
  • 从设备到云端再到 App 的完整示例代码及解析

本指南详细讲解如何使用 STM32F103C8T6 微控制器通过 ESP8266-01 WiFi 模块接入中国移动 OneNet 物联网平台,并通过 MQTT 和 HTTP 协议实现数据通信的完整流程。内容涵盖 OneNet 平台简介、设备创建配置、硬件与开发环境准备、ESP8266 AT 指令联网流程、STM32 通过 MQTT 发送/接收数据、移动 App 通过 HTTP 获取数据,以及从设备到云端再到手机 App 的综合示例演示。文中包含详细的步骤、代码示例、配置方法和常见问题解答,帮助读者从零开始完成项目集成。

1. OneNet 物联网平台简介与功能概览

OneNet 平台概述: OneNet 是中国移动提供的物联网开放平台,属于 PaaS(Platform as a Service)层服务。在物联网架构中,OneNet 扮演连接设备终端和上层应用的桥梁角色,为设备侧提供可靠的接入手段,为应用开发者提供丰富的 API 和数据管理能力。开发者可以通过 OneNet 对设备进行在线管理、数据存储分析、命令下发和应用构建。OneNet 支持海量设备的高并发接入,提供 99.9% 的服务可用性保障,同时通过分布式架构和多重机制确保数据安全存储与传输。借助 OneNet,企业和个人开发者能够快速搭建物联网应用,实现设备数据上云和远程监控控制等功能。

主要功能特点: OneNet 平台支持多种主流物联网协议,包括 MQTT、HTTP、LwM2M(NB-IoT)、EDP(设备协议)、TCP 透传、ModBus、JT/T808 等等。这意味着各种类型的终端设备都可以选择合适的协议与平台通信。在资源模型上,OneNet 采用“用户 -> 产品 -> 设备 -> 数据流”的组织架构:每个用户账户下可创建多个产品,每个产品下可添加多个设备,并为每台设备定义数据流、触发器、应用等资源。平台提供数据存储(数据流/数据点)、命令下发、触发器(满足条件自动动作)、应用托管等完整的 IoT 功能。此外,OneNet 通过可视化界面和开放 API,使开发者既能在网页端监控管理设备,也能通过 RESTful API 或 SDK 将平台能力集成到自己开发的 App、服务器中。

MQTT 与 HTTP 在 OneNet 中的应用: MQTT 和 HTTP 是 OneNet 平台最常用的两种设备接入和数据交互方式。MQTT(Message Queuing Telemetry Transport)是一种轻量级发布/订阅模型的消息协议,适合资源受限设备和不稳定网络环境,在 IoT 领域广泛使用。在 OneNet 中,MQTT 通常用于设备实时上线、上传传感数据、接收平台指令等场景。设备通过 MQTT 与 OneNet 的消息Broker保持长连接,采用主题 (Topic) 订阅/发布机制交换数据。OneNet 支持 MQTT 3.1.1 标准协议,并针对设备数据上传和命令下发定义了一系列系统主题格式,使物模型数据的上报和下发更加规范。例如,OneNet 平台允许设备发布传感数据到 $sys/{产品ID}/{设备名称}/thing/property/post 主题,并从 $sys/{产品ID}/{设备名称}/thing/property/set 主题接收下发的属性控制指令。同时,OneNet 也允许设备自由创建和订阅自定义主题,以便实现设备间的消息交互(同一产品内不同设备可订阅彼此发布的主题消息)。相比之下,HTTP 则是一种请求/响应式通信协议,更适合应用服务器或移动App和平台进行交互。OneNet 提供完整的 RESTful 风格 API,允许第三方应用通过 HTTP(S) 请求查询设备数据、下发命令、管理设备等。比如,应用可以通过 HTTP GET 请求获取某设备最新的数据点,或通过 HTTP POST 请求调用 OneNet API 向设备发送命令。由于 HTTP 通信不需要保持长连接,通常设备本身不使用 HTTP 实时上线(除非设备无法使用MQTT而周期性通过HTTP上报数据点),但应用层(如手机App、Web后台)会通过 HTTP API 来获取云端已存储的数据或触发控制操作。

简而言之,OneNet 提供了 MQTT 和 HTTP 两种互补的通信方式:设备侧倾向于使用 MQTT 保持长连接进行实时数据传输和指令接收,而应用侧多通过 HTTP API 实现数据查询和控制下发。在本项目中,我们将利用这两者的配合:STM32+ESP8266 设备以 MQTT 协议将传感数据上传到 OneNet,同时我们的手机 App 则通过 OneNet 的 HTTP API 获取设备数据,实现从传感器到云端再到用户界面的闭环。

2. OneNet 平台上的设备创建与配置

在将设备连入 OneNet 之前,需要先在平台上进行账户注册、产品和设备的创建,并获取相关的身份认证信息(如设备ID和APIKey)。以下是具体步骤:

2.1 注册 OneNet 开发者账户: 打开 OneNet 官方网站 open.iot.10086.cn 并完成账户注册流程。注册时需要提供手机号进行验证。注册成功后,使用账号登录 OneNet,进入平台“开发者中心”。OneNet 平台分为老版和新版界面,当前版本通常需要先点击首页右上角的“控制台”,再选择“前往Studio”进入新版开发者中心 (最新版Onenet云平台HTTP协议接入上传数据_onenet物联网postman软件-CSDN博客)。开发者中心是管理产品和设备的主要界面。

2.2 创建产品: 在开发者中心内,找到“产品管理”或直接点击“添加产品”。根据提示填写产品名称、描述等基本信息。设备接入协议选项非常重要,这里请选择“公开协议产品”并指定MQTT协议(如果你的设备走MQTT)或 HTTP 协议(如果设备打算通过HTTP直连)。对于本项目,我们选择 MQTT 协议,因为设备通过 ESP8266 使用 MQTT 上报数据。此外,联网方式可根据设备使用的网络类型选择(如 WiFi、蜂窝等,影响统计信息,不妨选择 Wi-Fi)。产品创建后,系统会分配一个全局唯一的产品ID。进入产品详情页面,能看到“产品概况”,其中包含“产品ID”等关键信息。请记录下产品ID,后续设备连接和 API 调用都需要它。

2.3 创建设备: 在产品的管理页面下,找到“设备管理”并点击“添加设备”。填写设备名称(例如“STM32_Sensor01”)和设备描述等。每个设备会被分配一个设备ID(一般是纯数字)以及初始鉴权信息。在 OneNet 新版 Studio 平台中,设备鉴权有两种方式:一种是设备有设备秘钥(Device APIKey),另一种是每次连接时使用动态 Token。如果平台生成了设备APIKey(通常在设备详情的鉴权信息中可以查看),建议将它记录下来。有些新版界面可能没有直接显示设备APIKey,而是需要用户使用 OneNet 的 Token 生成工具计算一个 Token 来作为密码(后文详细说明)。**注意:**产品ID、设备ID、设备名称、设备APIKey/鉴权信息都是后续设备 MQTT 连接和 HTTP API 访问所需的重要参数,一定要保存好。在OneNet上,每个设备也可以选择不同接入协议,如果是在 MQTT 协议的产品下添加设备,则默认该设备使用 MQTT 协议接入;如果在 HTTP 产品下,则设备通过HTTP上报数据等。

2.4 设备接入方式介绍: OneNet 支持多协议,最常用的还是 MQTT 和 HTTP。对于MQTT接入,前面已经提到设备连接时需要用到三元组:设备ID(作为客户端ID)、产品ID(作为用户名)、鉴权信息(作为密码)。设备连上 OneNet MQTT Broker 成功后,即可通过发布/订阅主题与平台通信(平台不需要预先创建Topic,除系统主题外皆可动态使用,这简化了开发)。而对于HTTP接入,设备可以通过HTTP请求将数据点上传至 OneNet 的REST API(例如通过POST发送JSON数据),通常需要在HTTP请求的Header中包含API-Key用于鉴权 (轻松使用中移物联网平台Onenet,MQTT协议快速接入实验 - ThingsKit)。HTTP方式也可以用于定期上报数据或让不适合长连接的设备与平台交互。在本项目中,我们主要采用 MQTT 连接实时上传数据,HTTP 则用于应用侧读取数据。但了解HTTP接入也有助于理解OneNet API,例如通过HTTP可以方便地测试数据上传和下发。后续章节会详细介绍通过HTTP API 获取设备数据并在App中显示的过程。

小贴士:如果是首次使用 OneNet 平台,建议先在 OneNet 后台熟悉各项操作:浏览产品概况查看产品ID、在设备列表查看设备ID、在设备详情页查看**鉴权信息(设备秘钥或Token)**等。一旦产品和设备设置完成,并确认这些信息,才能进入下一步的硬件配置和编码。

3. 硬件环境与开发环境准备

在软件配置妥当后,我们需要准备硬件环境(STM32F103C8T6 开发板和 ESP8266-01 模块的连接)以及开发调试所需的软件工具。

3.1 STM32F103C8T6 硬件介绍

STM32F103C8T6 是 STM32F1系列中非常经典的一款 MCU,基于 ARM Cortex-M3 内核,主频 72MHz,拥有64KB Flash和20KB SRAM,以及丰富的片上外设(USART、SPI、I2C、ADC、TIM 等)。由于其性价比高、资源适中,被广泛用于入门开发板(如“蓝色小板” BluePill)。本项目中,我们选用 STM32F103C8T6 作为主控,负责采集传感器数据(例如温湿度)、通过串口与 ESP8266 通信,并处理来自云端的控制指令。请确保您的 STM32 开发板已烧录了合适的 Bootloader 或固件,或者通过 SWD 接口连接了调试器(如 ST-Link),以便我们后续下载程序进行调试。

引脚资源回顾: STM32F103C8T6 有多个通用异步收发器 UART/USART。其中 USART1(PA9 TX, PA10 RX)和 USART2(PA2 TX, PA3 RX)经常用于与外部模块通信或打印日志。由于我们的 ESP8266-01 使用串口通信,需要占用STM32的一个 USART 接口。USART1通常连接ST-Link的虚拟串口用于调试打印,因此我们可选择USART2与 ESP8266 通信(当然,用 USART1 给 ESP8266 通信、USART2 用于调试也行,这取决于具体开发板的引出和需求)。无论选择哪个串口,需要确保STM32能以 ESP8266 默认的波特率通信(ESP8266 默认波特率多为 115200bps,某些版本也可能是9600bps,可通过AT指令配置)。另外,STM32需提供3.3V电源给ESP8266模块,且两个器件共地。

3.2 ESP8266-01 硬件介绍及接线方式

ESP8266-01 模块简介: ESP8266-01(简称 ESP-01)是基于乐鑫 ESP8266 芯片的最小系统WiFi模块。它体积小巧(约 25mm x 14mm),板上有 8 个引脚,包含ESP8266所需的最小Flash存储和天线。ESP-01 自带完整的 TCP/IP 协议栈,可以通过 AT 指令集由外部主控(如 STM32)进行控制,实现 WiFi 联网和数据通信。ESP8266-01 的优点是价格便宜、功耗适中,并且通过 UART 串口即可控制,非常适合作为 MCU 的 WiFi 扩展模块。在默认的 AT 固件下,ESP8266-01 可以执行各种网络操作指令,如连接路由器 (AT+CWJAP)、启动TCP连接(AT+CIPSTART)等。通过升级到最新的 MQTT AT 固件,它甚至直接支持 MQTT 客户端的内置指令,如连接 MQTT 服务器、发布/订阅消息等。本项目将利用 ESP8266-01 以 AT 指令模式连接到 WiFi,并通过 MQTT AT 指令连接 OneNet 平台。

ESP8266-01 引脚定义: ESP-01 有 8 个引脚,典型分布和功能如下 (ESP8266-01引脚说明与连接_esp01引脚定义-CSDN博客):

  • VCC:3.3V 电源输入(切勿使用5V,否则会烧毁模块)。
  • GND:电源地。
  • TXD:UART 串口数据发送端 (模块发送数据给STM32,接STM32 RX 引脚) (ESP8266-01引脚说明与连接_esp01引脚定义-CSDN博客)。
  • RXD:UART 串口数据接收端 (模块接收数据,从STM32 TX 引脚获取) (ESP8266-01引脚说明与连接_esp01引脚定义-CSDN博客)。
  • CH_PD(或 EN):芯片使能引脚,**必须接高电平(3.3V)**使模块工作 (ESP8266-01引脚说明与连接_esp01引脚定义-CSDN博客) (ESP8266-01引脚说明与连接_esp01引脚定义-CSDN博客)。拉低该引脚会让芯片休眠/禁用。
  • RST:复位引脚,低电平有效。可以接STM32一个GPIO用于软件复位,或简单地接高电平通过手动断电复位 (ESP8266-01引脚说明与连接_esp01引脚定义-CSDN博客)。
  • GPIO0:引导引脚0。悬空或拉高= 正常运行模式;拉低= 串口下载模式 (ESP8266-01引脚说明与连接_esp01引脚定义-CSDN博客)。平时要确保 GPIO0 不被误拉低,否则模块会进入固件下载模式无法正常运行。通常上电时 GPIO0 接高(内部有上拉可悬空)。
  • GPIO2:引导引脚2。需拉高运行(上电时禁止为低) (ESP8266-01引脚说明与连接_esp01引脚定义-CSDN博客)。一般直接悬空即可(内部上拉)。

ESP8266-01 与 STM32 连接: 按照上面的引脚功能,连接方式如下 (ESP8266-01引脚说明与连接_esp01引脚定义-CSDN博客):

  • 将 ESP8266-01 的 VCC 引脚接 3.3V 电源。确保电源能提供足够电流(建议至少500mA裕量),因为 ESP8266 WiFi 发射时瞬时电流可达数百毫安。使用稳压的 3.3V 且在模块VCC和GND间加旁路电容以稳定供电。
  • GND 接地:连接 ESP8266-01 和 STM32 开发板的地线,保证两者参考电平一致。
  • ESP-01 TX 接 STM32 的 RX 引脚(例如 STM32 PA3 若用USART2作为接收) (ESP8266-01引脚说明与连接_esp01引脚定义-CSDN博客)。
  • ESP-01 RX 接 STM32 的 TX 引脚(例如 STM32 PA2 若用USART2发送) (ESP8266-01引脚说明与连接_esp01引脚定义-CSDN博客)。请注意 ESP8266 RX 引脚默认3.3V逻辑,STM32F103也是3.3V GPIO,因此可以直接相连。如果主控是5V逻辑,则需要电平转换。STM32F103C8T6 在3.3V下运行,无需电平转换。
  • CH_PD/EN 引脚接 3.3V(可与 VCC 短接)。这个引脚必须为高,等效于使能芯片 (ESP8266-01引脚说明与连接_esp01引脚定义-CSDN博客)。可以通过 10k 上拉电阻上拉到3.3V。如果希望STM32控制使能,也可接STM32一个GPIO,但通常直接上拉更简单。
  • GPIO0 引脚保持悬空或上拉(默认就有上拉)。若您的模块未集成上拉,可用电阻上拉到3.3V。除非要刷固件,否则无需专门连接STM32引脚。
  • GPIO2 引脚一般悬空(内部有上拉即可满足正常启动要求)。
  • RST 引脚可以暂时悬空或通过上拉电阻拉高。如果需要STM32复位模块,可以将其接到STM32一个GPIO(通过低脉冲复位)。简化起见也可不接,由需要时断电重启模块代替。

连接后,请仔细检查线路:特别是电源和地要可靠连接,串口交叉连接(TX对RX),CH_PD确实为高电平。一个常见的错误是忘记给 CH_PD 上电,导致模块没有响应;或者串口接反。正确连线后,给模块上电,ESP8266 蓝色指示灯会在上电或复位时闪烁一下(ESP-01 上通常有一个蓝色LED连接在UART TX上,每次串口发送数据会闪烁)。如果有 USB 转TTL 模块,可在PC上通过串口工具接ESP8266测试 AT 指令响应,以确认模块工作正常。

3.3 STM32CubeIDE 的安装及配置

开发环境选择: STM32F103 的开发可以使用多种IDE,例如 Keil MDK、IAR、PlatformIO 等。本指南采用 ST 官方的免费开发环境 STM32CubeIDE,它集成了 STM32CubeMX 图形配置和 Eclipse/CDT 编译调试功能,适合构建 HAL 库或 LL 库项目。如果尚未安装,请从 ST 官方网站下载安装 STM32CubeIDE,安装过程中选择相应的包支持 STM32F1 系列。

启动新工程: 打开 STM32CubeIDE,选择 File -> New STM32 Project。在 Target Selector 中搜索 STM32F103C8(或选择相应开发板型号),然后 Next。输入项目名称,如 "STM32_OneNet_Demo",选择使用 CubeMX 初始化。CubeIDE 将创建包含 CMSIS 和 HAL 库的基本工程。接下来会自动打开 CubeMX 配置界面。

3.4 使用 STM32CubeMX 配置 STM32 外设(USART、GPIO 等)

在 CubeMX 图形配置中,我们需要启用并配置以下外设:用于与 ESP8266 通信的 USART、一些 GPIO(可能用作ESP8266 RST控制或板上LED)、如果连接传感器还需要相应接口(如I2C/SPI等),以及调试所需配置。

USART 配置: 找到用于连接 ESP8266 的串口。例如我们选用 USART2:在 CubeMX 的 Pinout & Configuration 中,展开 Connectivity -> USART2,将其模式设置为 Asynchronous。CubeMX 会自动将 PA2/PA3 配置为 USART2 TX/RX。然后在 USART2 参数中,将 Baud Rate 设置为 115200(与 ESP8266 AT默认波特率匹配 (STM32与物联网01-ESP8266基本操作 - 博客园)),数据位8,无奇偶校验,1个停止位,硬件流控 None。开启 **USART2 的中断(NVIC Settings)**以便后续用中断接收数据,或者使用 DMA 接收(可选)。如果打算通过另一个串口打印调试信息,可以同时开启 USART1 并将其TX引脚映射到SWO或者PA9,引出给ST-Link虚拟串口。但简化起见本指南主要描述 USART2 用于WiFi通信。

GPIO 配置: 将用于控制 ESP8266 的 RST 引脚配置为推挽输出(如果需要)。例如我们可用 PB0 连到 ESP8266 RST,那么在 CubeMX 中将 PB0 设置为 GPIO_Output,初始状态设置为高(不复位)。另外,可以配置板载 LED(如 PC13)为输出用于指示状态。

时钟与其他配置: 确保启用了外部高速晶振HSE(如使用外部8MHz晶振的板子),设置系统时钟 72MHz,以获得准确的USART波特率。如果使用内部晶振,需要校准以确保串口通信可靠。开启需要用的定时器(用于延时或心跳)、I2C/SPI/ADC(用于传感器)等。本项目例如使用定时器中断做一个1秒的计时,或者使用 SysTick 实现简单延时函数。

配置完成后,点击 Generate Code。CubeIDE 将根据CubeMX配置生成初始化代码,包括 MX_USART2_Init()MX_GPIO_Init() 等函数。至此,STM32 外设配置就绪,我们可以编写代码控制USART收发 AT指令来驱动 ESP8266。

开发环境准备小结: 我们现在拥有:STM32F103 硬件连接好 ESP8266-01,并在CubeIDE项目中初始化好了串口和必要引脚。接下来需要考虑 ESP8266 的固件和AT指令用法,然后编写 STM32 程序通过串口发送AT指令,驱动 ESP8266 完成 WiFi联网和 MQTT 连接 OneNet 的流程。

4. ESP8266(AT 模式)连接 OneNet 的基本流程

ESP8266 模块将作为 WiFi调制解调器,通过 AT 指令集由 STM32 来控制。我们首先要确保 ESP8266-01 上烧录了合适的 AT 固件版本,且支持 MQTT 功能。目前常见的方案有:

  • 使用乐鑫官方 AT 固件(例如 ESP-AT),版本要求支持 MQTT AT 指令。如果您的模块固件版本较旧(AT+GMR可查看版本号),可能不直接支持 MQTT,需要更新到新版本。
  • 或使用第三方定制的 MQTT AT 固件(如安信可提供的 MQTT 版AT固件)。更新固件需要将 ESP8266 IO0 拉低进入下载模式,通过 USB 转串口烧录。考虑到步骤复杂,本指南假设已获得支持 MQTT指令的ESP8266 AT固件。

OneNet 平台允许使用标准 MQTT 协议,我们可以直接利用 ESP8266 的 MQTT AT命令集来连接 OneNet,无需在 STM32 上编写MQTT协议栈。这大大简化了工作。下面分步骤介绍 ESP8266 AT 指令实现从联网到 MQTT 连接的流程。

4.1 常用 AT 指令简介

ESP8266 AT 指令是一系列以“AT”开头的文本命令,用于配置 WiFi模块参数和控制网络操作。以下是我们将用到的一些指令及其功能:

  • AT:测试AT连通性。发送AT\r\n模块应返回OK,用于验证串口通信是否正常。
  • AT+RST:重启模块。模块会复位并重新上电自检。
  • AT+GMR:查询固件版本号,用于确认固件支持情况。
  • AT+CWMODE:设置 WiFi 工作模式。AT+CWMODE=1 将模块设为 Station模式(STA),即作为客户端连接路由器。
  • AT+CWJAP="SSID","PWD":加入WiFi网络。参数为 WiFi 热点的 SSID 和密码。执行成功后模块会连接到指定路由器并获取IP。
  • AT+CIPSTA?:查询模块当前的 IP 地址(可选,确认联网成功)。
  • AT+MQTTUSERCFG=<...>:配置 MQTT 客户端参数。这个是 MQTT 扩展指令,格式较复杂,详见后文。
  • AT+MQTTCONN=<...>:建立 MQTT 连接,指定服务器地址和端口等。
  • AT+MQTTSUB=<...>:订阅 MQTT 主题。
  • AT+MQTTPUB=<...>:发布 MQTT 消息。
  • AT+MQTTPUBRAW=<...>:发布 MQTT 原始消息(需先指定长度,再发送数据)。
  • AT+MQTTCLEAN:断开 MQTT 连接(视固件支持情况)。

其中,AT+MQTTUSERCFGAT+MQTTCONNAT+MQTTSUBAT+MQTTPUB 等属于新版固件中增加的 MQTT 命令集。若输入这些命令提示未知,说明固件不支持MQTT,需要升级固件。

4.2 ESP8266 连接 WiFi 并接入 OneNet

步骤1:模块上电自检 – 给ESP8266上电后,等待1~2秒它完成自检。STM32 向ESP8266串口发送一次AT\r\n,若返回OK则表示串口通信正常。如果无响应,可尝试发送AT+RST\r\n复位模块,或检查串口接线/波特率。

步骤2:设置 WiFi 模式 – 发送AT+CWMODE=1\r\n,将ESP8266切换到 STA(Station)模式。默认有些固件可能已是1,但确认一下最好。期望收到OK回应。若返回ERROR可能是指令格式错误或模块不支持,请检查指令拼写和换行符。

步骤3:连接到路由器 – 发送 AT+CWJAP="你的WiFi名称","WiFi密码"\r\n。此命令执行时间相对较长(数秒),模块会尝试加入指定AP。成功时返回WIFI CONNECTEDWIFI GOT IP消息以及最终的OK (STM32使用esp8266的AT指令连接mqtt服务器,以Thing Cloud为例(标准库和HAL库)_stm32 mqtt at指令-CSDN博客)。若返回FAIL,请检查SSID/密码是否正确,或模块距离路由器过远信号不好。成功获取IP后,可以用AT+CIFSRAT+CWJAP?验证IP地址。至此,ESP8266 已连接互联网。

步骤4(可选):时间/NTP 配置 – OneNet MQTT可能要求时间戳(一般不需要此步,但部分物模型功能可能涉及时间)。示例中有使用 AT+CIPSNTPCFG=1,8,"ntp1.aliyun.com"\r\n 设置NTP (STM32使用esp8266的AT指令连接mqtt服务器,以Thing Cloud为例(标准库和HAL库)_stm32 mqtt at指令-CSDN博客)。这步可选,仅确保模块时间同步,对MQTT连接OneNet不是必须。

步骤5:解析 OneNet MQTT 连接参数 – 在发起 MQTT 连接前,我们需要准备好 OneNet 的服务器地址、端口以及客户端身份参数。根据 OneNet MQTT 接入规范,我们总结出如下参数:

  • 服务器地址:OneNet MQTT Broker 的域名或IP。官方文档显示 OneNet 公共云 MQTT 接入地址可以使用 183.230.40.39(这是OneNet华北主站IP)和端口 6002。也可以使用域名 mqtt.heclouds.commqtts.heclouds.com。据近期实践,OneNet 新平台也开放了标准端口1883 供非TLS连接。例如域名 mqtt.heclouds.com:1883 也指向 OneNet MQTT 服务 (oneNet之MQTT按键控制LED 原创 - Csdn博客)。本指南选择传统地址 183.230.40.39:6002(非加密),对应 MQTT 3.1 协议。
  • 客户端ID:即设备ID。在 OneNet 平台设备列表中可找到,例如创建设备时给出的数字ID(假设为 "123456789")。
  • 用户名:即产品ID。可在产品概况页面查看,如 "98765"
  • 密码:即鉴权信息。OneNet 支持直接使用 设备APIKey 作为 MQTT 密码 (oneNet之MQTT按键控制LED_在检测mqtt用以执行其它按键-CSDN博客) (oneNet之MQTT按键控制LED_在检测mqtt用以执行其它按键-CSDN博客)。例如设备的APIKey(16或24位字符串,如 "aFKcWTrm6VJfgfF1pQqW2=NWDck=" (oneNet之MQTT按键控制LED_在检测mqtt用以执行其它按键-CSDN博客))。新版OneNet也允许使用通过产品ID、设备名和设备秘钥计算的 Token 值作为密码。计算 Token 一般需要时间戳和签名,这里为了简便,我们直接使用 设备APIKey,假定平台允许。注意,如果你的 OneNet 产品是新物模型类型,设备可能没有独立APIKey,需要通过 OneNet 提供的 Token 生成工具计算一个 token 字符串,再用作 MQTT 密码 (最新版Onenet云平台HTTP协议接入上传数据_onenet物联网postman软件-CSDN博客) (最新版Onenet云平台HTTP协议接入上传数据_onenet物联网postman软件-CSDN博客)。生成token的规则通常是:token = version=2018-10-31&res=products/<产品ID>/devices/<设备名称>&et=<过期时间>&method=md5&sign=<签名> (ESP8266/01s AT指令连接OneNET MQTT篇上报和下发数据_onenet mqtt 命令下发-CSDN博客)。签名是把上述信息和产品MasterKey一起MD5生成的字符串。这较复杂,如非必要可使用设备APIKey简单连接。

搞清上述参数后,我们组装 MQTT 用户配置命令。ESP8266 MQTT AT指令 AT+MQTTUSERCFG 用于设置这些参数,其格式为:

AT+MQTTUSERCFG=<链接ID>,<生存周期>,<客户端ID>,<用户名>,<密码>,<KEEPTIME>,<cleansession>,<LWTTOPIC>

各字段含义:

  • 链接ID:0(ESP8266可以维护多个MQTT连接,0表示第一个)。
  • 生存周期:1(MQTT版本,0=3.1, 1=3.1.1)。
  • ClientID:设备ID字符串。
  • Username:产品ID字符串。
  • Password:鉴权信息字符串(设备APIKey或生成的Token)。
  • KEEPTIME:心跳时间(单位s),OneNet默认可用无关紧要值如0表示默认60s。
  • cleansession:0或1,设置会话清理,一般设0保持会话,设1表示每次连接不保留会话。
  • LWTTOPIC:遗嘱消息主题,可留空""无遗嘱。

例如,假设设备ID为123456789,产品ID为98765,设备APIKey为abc123XYZ...,则命令为:

AT+MQTTUSERCFG=0,1,"123456789","98765","abc123XYZ...",0,0,""

发送该命令,模块应返回OK表示参数接受成功 (STM32使用esp8266的AT指令连接mqtt服务器,以Thing Cloud为例(标准库和HAL库)_stm32 mqtt at指令-CSDN博客)。如果返回错误,请检查参数格式,特别是引号、逗号是否正确。

步骤6:建立 MQTT 连接 – 接下来发送 AT+MQTTCONN=0,"183.230.40.39",6002,1\r\n。其中参数依次为:链接ID=0,服务器地址,端口号,最后的1表示clean session(这里设1或者0需跟前面的 cleansession 保持一致,否则可能出错)。注意 OneNet MQTT 非TLS,用 6002 端口;如用1883端口将域名改为mqtt.heclouds.com相应调整。建立连接后,ESP8266会尝试和OneNet进行MQTT握手。成功的话,会收到 OK 和一个 MQTT 状态指示,比如:+MQTTCONNECTED:0。如果连接失败,常见错误代码包括:

  • ERROR 直接报错:检查域名/IP是否可达,端口是否正确。
  • +MQTTCONNECTED: -1+MQTTCONNECTED:4 等:这些是MQTT Connect 报文被服务端拒绝的返回码。例如 4表示登录被拒绝(可能用户名/密码错误)。请核对产品ID/设备ID/APIKey是否正确对应,或Token是否过期。
  • +CME ERROR: Recv timeout:表示在超时时间内没收到响应,可能网络问题或参数有误。

当 OneNet 平台收到正确的 ClientID(设备ID)、Username(产品ID)和Password(APIKey/token)后,会建立 MQTT 连接,OneNet 后台设备列表应该能看到该设备上线。成功连接后,我们就可以进行 MQTT 数据收发了。

4.3 OneNet MQTT 通信主题格式解析

OneNet 平台的数据交互通过 MQTT 主题(Topic)完成。OneNet 有一些系统主题专门用于物模型设备的数据上下行,为统一格式,通常以 $sys/{产品ID}/{设备名称}/thing/ 开头。例如:

  • 上报设备属性(数据点)使用主题:$sys/{产品ID}/{设备名称}/thing/property/post。设备向该主题发布属性值的JSON数据。
  • 平台下发写属性命令使用主题:$sys/{产品ID}/{设备名称}/thing/property/set。设备需订阅该主题来接收指令。
  • 属性上报回复主题:$sys/{产品ID}/{设备名称}/thing/property/post/reply,平台每次收到设备上报数据会反馈结果,设备可选择订阅此主题确认数据是否成功被平台接收。
  • 属性设置回复主题:$sys/{产品ID}/{设备名称}/thing/property/set_reply,当设备执行完平台下发的属性设置指令后,需向该主题回复执行结果(如成功或错误)以通知平台。

这些主题含有产品ID和设备名称,是OneNet新版物模型统一的路径。如果你的产品在OneNet上创建了物模型(数据流模板)并定义了属性,建议使用上述系统主题来上传和下发数据,平台将自动解析 JSON 格式数据点并存储到对应的属性中。如果没有用物模型,OneNet 也支持另一种数据流透传方式:设备可以向主题 $dp 发布数据点(Data Point)消息 (10.2. MQTT协议:2上传数据点到OneNET平台 — mPython掌控 2.2.0 documentation)。$dp 是 OneNet 定义的特殊主题,用于简化数据上报,它要求发布的消息为特定格式:前3字节指示JSON数据长度和类型,后面跟实际JSON内容 (10.2. MQTT协议:2上传数据点到OneNET平台 — mPython掌控 2.2.0 documentation)。例如 micropython 客户端通过 c.publish("$dp", pubdata(message)) 上报数据点 (10.2. MQTT协议:2上传数据点到OneNET平台 — mPython掌控 2.2.0 documentation)。但考虑到 $dp 较旧且需要自己构造报文头,我们更推荐使用物模型主题直接发 JSON 字符串,这也便于与OneNet Studio中的设备属性对应。

本项目主题规划: 假设我们定义了两个属性数据流:温度(temp)和湿度(humi)。我们将在设备端通过 $sys/{产品ID}/{设备名称}/thing/property/post 发布属性数据,JSON格式如:{"id":"123","params":{"temp":{"value":23.5},"humi":{"value":60}}}。平台处理后,可在OneNet设备详情看到 temp和humi的数据点各自更新。为了接收平台对上报的响应,我们可以订阅 $sys/{产品ID}/{设备名称}/thing/property/post/reply(但其实OneNet当前对post上报一般不需要特殊确认,error=0说明成功)。更重要的是,为了让手机App通过平台控制设备(比如打开设备上的LED),平台会通过 property/set 下发命令,因此设备需要订阅 $sys/{产品ID}/{设备名称}/thing/property/set 主题。一旦收到此主题消息,STM32 就触发对应的控制,并回复执行结果到 set_reply 主题。

4.4 配置 ESP8266 订阅 OneNet 主题

在 MQTT 连接建立后,ESP8266 可以通过 AT 命令订阅所需主题。使用指令格式:

AT+MQTTSUB=<链接ID>,"<主题>",<QoS>

其中 QoS 为服务质量等级,0最多送一次,1至少送一次。OneNet 支持 QoS0 和 QoS1,这里用 QoS0 足矣。

订阅设备下行主题: STM32应发送:

AT+MQTTSUB=0,"$sys/{产品ID}/{设备名称}/thing/property/set",0\r\n

这样当 OneNet 平台有对该设备的控制指令下发时,ESP8266会收到,并通过串口通知STM32。ESP8266 固件在收到订阅的消息时,会通过一种 URC 非命令的格式输出,比如:

+MQTTSUBRECV:0,"$sys/pid/devName/thing/property/set","{...json...}"

具体格式视固件有所不同,可能还带消息长度等信息。但一般包含链接ID、主题、以及消息内容。STM32 程序需解析出消息内容中的 JSON,然后根据指令执行相应动作(如打开LED或改变阈值等)。

(可选)订阅上报回复主题: 若希望确认每次数据上报平台是否成功,可订阅 $sys/{产品ID}/{设备名称}/thing/property/post/reply。平台在收到属性上报后会返回类似:{"id":"123","code":0,"msg":"success"},表示id为123的请求成功(code=0)。ESP8266 收到后STM32可读取+MQTTSUBRECV并判断 code 是否为0,非0可重试上报。订阅指令同理:

AT+MQTTSUB=0,"$sys/{产品ID}/{设备名称}/thing/property/post/reply",0\r\n

回复 OK 则订阅成功。

ESP8266 可以一次订阅多个主题,顺序发送多条 AT+MQTTSUB 命令即可。OneNet 支持动态创建主题,订阅不存在的主题也会成功(只要格式合法),这点和其他云(如阿里IoT)需要预定义Topic不同。所以无须在OneNet平台额外配置这些主题。

注意: 每条 AT 命令都应有相应 OK/ERROR 来指示执行结果。我们在 STM32 程序中通常会发送命令后等待特定应答字符串。例如,发送 MQTTSUB 后等待 "OK" 确认。如果一直等不到(超时),应考虑重发或判定失败。合理的延时和重试机制可以提高连接成功率。

4.5 综合:ESP8266 连接过程命令序列

将上面所有配置串联起来,ESP8266 从上电到订阅完成的大致 AT 指令序列如下(带简要注释):

  1. AT → 模块应答 OK(测试通信)
  2. AT+RSTOK(重启模块)
  3. (模块重启后会输出一些启动信息,等待1~2秒继续)
  4. AT+CWMODE=1OK(设置为Station模式)
  5. AT+CWJAP="SSID","PWD"WIFI CONNECTED WIFI GOT IP ... OK(连接WiFi,联网成功)
  6. AT+MQTTUSERCFG=0,1,"<DeviceID>","<ProductID>","<APIKey/token>",0,0,""OK(配置MQTT参数) (STM32使用esp8266的AT指令连接mqtt服务器,以Thing Cloud为例(标准库和HAL库)_stm32 mqtt at指令-CSDN博客)
  7. AT+MQTTCONN=0,"183.230.40.39",6002,1 → 若成功:OK 和可能的 +MQTTCONNECTED:0
  8. AT+MQTTSUB=0,"$sys/<pid>/<dev>/thing/property/post/reply",0OK(订阅上报回复主题,可选)
  9. AT+MQTTSUB=0,"$sys/<pid>/<dev>/thing/property/set",0OK(订阅平台下行控制主题)

到此,设备已做好与 OneNet 云通信的准备。接下来,STM32 就可以根据应用需要发布数据或者接收指令进行处理了。

5. STM32 通过 MQTT 向 OneNet 发送/接收数据

这一部分我们关注 STM32 程序如何控制 ESP8266 完成 MQTT 数据通信。核心是通过串口发送上节的 AT 指令序列,实现设备数据上报(Publish)和云端命令下发接收(Subscribe)。

5.1 STM32 串口通信控制 ESP8266

USART 通信实现: 在 STM32 中,我们可以使用 HAL 库提供的 HAL_UART_Transmit()HAL_UART_Receive() 函数与 ESP8266 通信,也可以使用中断或 DMA 提高效率。典型地,我们会实现一个函数 ESP8266_SendCmd(const char* cmd, const char* ack, uint32_t timeout) 用于发送 AT 命令并等待某个应答关键字。例如,伪代码:

uint8_t rxBuf[128];
uint8_t ESP8266_SendCmd(const char* cmd, const char* ack, uint32_t timeout) {HAL_UART_Transmit(&huart2, (uint8_t*)cmd, strlen(cmd), 1000);// 清空接收缓冲memset(rxBuf, 0, sizeof(rxBuf));// 等待接收,循环直到发现 ack 或超时uint32_t t0 = HAL_GetTick();uint8_t found = 0;while(HAL_GetTick() - t0 < timeout) {// 假设我们使用中断将数据搬到rxBuf并随时检查if(strstr((char*)rxBuf, ack) != NULL) {found = 1;break;}if(strstr((char*)rxBuf, "ERROR") != NULL) {break;}}return found;
}

上面使用 strstr 查找应答。为此,我们需要在UART接收中断中持续填充 rxBuf 缓冲区。可以开USART接收空闲中断,把每次接收到的新字节追加到 rxBuf 末尾。为了简单,也可以采用 HAL_UART_Receive polling 方式读字符,边读边检查字符串,但效率略低。在实际代码中,还要考虑Buffer溢出以及必要时清除旧应答。

AT 指令发送顺序: STM32上电后,按4.2节流程逐条调用 ESP8266_SendCmd 发送。比如:

ESP8266_SendCmd("AT\r\n", "OK", 500);
ESP8266_SendCmd("AT+RST\r\n", "ready", 2000); // 等待重启后的 "ready" 字样
ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK", 500);
ESP8266_SendCmd("AT+CWJAP=\"MyWiFi\",\"password\"\r\n", "GOT IP", 10000);
sprintf(cmdBuf, "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n", deviceID, productID, apiKey);
ESP8266_SendCmd(cmdBuf, "OK", 1000);
sprintf(cmdBuf, "AT+MQTTCONN=0,\"183.230.40.39\",6002,1\r\n");
ESP8266_SendCmd(cmdBuf, "OK", 5000);
ESP8266_SendCmd("AT+MQTTSUB=0,\"$sys/xxx/yyy/thing/property/set\",0\r\n", "OK", 1000);

如上所示,在每一步等待适当的应答。其中连接WiFi可能耗时较长,要给出足够 timeout(10秒甚至更长),而MQTT 连接也需要几秒完成 TLS 握手/认证等(OneNet非TLS会快些)。确保每一步都判断结果,若失败可以重试或进入错误处理(比如重新初始化ESP8266)。

常见错误处理:

  • 如果 AT 测试不通,可能是串口问题,可重发几次AT或者直接指示错误闪LED。
  • AT+CWJAP 返回 FAIL,可尝试再次发送或让用户检查WiFi凭据。
  • AT+MQTTCONN 若返回错误,需要检查鉴权。OneNet常见是用户名密码不对导致 Connect 报文返回 4 (Connection Refused: bad user/pass)。这种情况下,可打印调试信息 (比如将 ESP8266 返回的整个字符串通过调试串口输出) 来分析。
  • 整个流程若卡在某一步超过重试次数,可考虑重启模块(AT+RST)重来。

经过上述步骤,假设 STM32 最终在MQTT连接和订阅主题上都收到 OK,我们就进入正常通信阶段了。

5.2 发布 MQTT 数据(设备上传)

构造发布命令: 发布属性数据使用 AT+MQTTPUBAT+MQTTPUBRAW。区别是:MQTTPUB 可以直接附带消息字符串,但需要对消息内的特殊字符转义,而且长度有限制;MQTTPUBRAW 则分两步发送,可避开转义问题。我们用普通 AT+MQTTPUB 简化流程。

格式:

AT+MQTTPUB=0,"<主题>","<消息>",<QoS>,<retain>\r\n

其中 QoS=0, retain=0 即可(OneNet 暂无保留消息需求)。

例如上传温湿度:
主题 $sys/pid/dev/thing/property/post,消息内容:{"id":"123","params":{"temp":{"value":23.5},"humi":{"value":60}}}
则命令为:

sprintf(cmdBuf, "AT+MQTTPUB=0,\"$sys/%s/%s/thing/property/post\",\"{\\\"id\\\":\\\"123\\\",\\\"params\\\":{\\\"temp\\\":{\\\"value\\\":%.1f},\\\"humi\\\":{\\\"value\\\":%.1f}}}\",0,0\r\n", productID, deviceName, temperature, humidity);
ESP8266_SendCmd(cmdBuf, "OK", 1000);

注意在C字符串中双引号和反斜杠需要转义(如 \"\\\")。上例用了 %.1f 代入浮点温湿度值并保留1位小数。id 字段可用来匹配应答,这里随意给"123"即可,每次上报可增1或使用时间戳字符串。

发送该命令,如果ESP8266返回 OK,表示消息已发出。OneNet 平台会将数据解析写入设备属性data流。如果我们之前订阅了 post/reply 主题,那么ESP8266稍后会输出一行,例如:

+MQTTSUBRECV:0,"$sys/pid/dev/thing/property/post/reply","{"id":"123","code":0,"msg":"success"}"

STM32 程序在 UART 接收数据中检测到有 +MQTTSUBRECV 字样,就可以进一步解析出主题和内容。可以通过寻找引号来截取主题字符串,再根据主题决定处理方式。如果是 post/reply,解析 JSON 看 code是否为0。如果为0则表示平台接受数据成功;非0表示失败,此时可选择重发该数据或者上报错误状态。一般 code 非0的情况很少出现,除非 JSON 格式不符合物模型定义、数据类型错误等。

循环发布数据: 实际应用中,STM32 会周期性采集传感器数据然后发布。例如每隔 10秒发送一次温湿度。可以使用定时中断或RTOS任务来调用发布函数。确保不要发太频繁以免淹没网络,一般 OneNet 对MQTT上报频率没有苛刻限制,但合理的间隔有助于功耗和流量。

发布调试: 在开发时可以借助 OneNet 平台的“设备调试”功能或 MQTT.fx 等客户端来观察数据是否到云端。OneNet Studio 提供“数据流”或“设备详情”页面,可以看到属性的最新值和历史曲线,验证我们的发布确实成功。

5.3 订阅主题消息处理(设备下行)

STM32 需要处理 ESP8266 通过串口反馈的订阅消息,即当平台有命令下发时,ESP8266 会打印类似 +MQTTSUBRECV: 的信息。我们需要在 UART 接收回调中寻找这个标志并提取其中的 JSON 命令。

示例: 平台通过 HTTP API 或控制台调用下发命令,OneNet 会向主题 $sys/pid/dev/thing/property/set 发送消息。例如让设备LED开关,OneNet 定义了属性 "LED" 为布尔或数值,那么下发 JSON 可能是:{"id":"4","params":{"LED":{"value":1}}}。ESP8266收到,会输出:

+MQTTSUBRECV:0,"$sys/pid/dev/thing/property/set","{"id":"4","params":{"LED":{"value":1}}}"

STM32 程序需解析 params 内的内容。可以采用和发布相同的 cJSON 库(如果使用嵌入式JSON解析库的话)或者简单字符串查找方法。例如,查找 "LED":{"value": 子串,取其后紧跟的数字。或者更通用地,把整个 JSON 文本提取出来,然后用 JSON parser 获取键值。由于OneNet物模型下发格式就是这个 "params":{...},我们可以硬编码寻找目标属性。

执行命令并回复: 一旦提取出 LED 要设置为1,我们就在 STM32 控制相应GPIO点亮 LED。然后需要回复平台,告知命令已执行。回复主题 $sys/pid/dev/thing/property/set_reply,内容一般包含同样的 id 以及 code 表示结果。OneNet 希望收到 code 200 表示设备已成功执行,或其他错误码。示例如ESP8266命令:

AT+MQTTPUB=0,"$sys/pid/dev/thing/property/set_reply","{"id":"4","code":200,"msg":"success"}",0,0

来回应 id=4 的指令执行成功。在 AT 指令里,双引号要转义,同发布类似:

sprintf(cmdBuf, "AT+MQTTPUB=0,\"$sys/%s/%s/thing/property/set_reply\",\"{\\\"id\\\":\\\"%s\\\",\\\"code\\\":200,\\\"msg\\\":\\\"success\\\"}\",0,0\r\n",productID, deviceName, cmdIdString);
ESP8266_SendCmd(cmdBuf, "OK", 1000);

其中 cmdIdString 是收到命令 JSON 里的 id(例如 "4"),需要原样放回。发送完成后,OneNet 运维页面“API调试”处将显示 code:0 表示平台收到了设备的确认。若不回复或回复不正确,平台可能视为设备未执行命令,会显示超时。

总结设备下行处理:

  1. STM32监听串口数据,捕获 +MQTTSUBRECV 行。
  2. 判断主题是 property/set 还是别的。可通过在该行字符串中搜索 "thing/property/set" 来确定。如果以后还有别的订阅主题,也类似判断。
  3. 提取 JSON 字符串。因为包含引号,我们可以找到第一个出现的 { 和最后一个 } 括号的位置,截取之间的字符串作为 JSON。
  4. 根据具体的物模型字段解析需要控制的项和值。对简单项目,也可以通过 strstr寻找属性名然后取其后 value值。
  5. 执行相应动作(如控制硬件)。
  6. 构造 set_reply 消息发送确认。

整个过程应尽量迅速完成,避免下一条UART数据覆盖尚未处理的数据。可以考虑把 JSON 放到任务中处理,以免阻塞UART中断。不过对于一般速度的消息和STM32F1性能,这样处理是足够的。

6. App 与 OneNet 平台的数据交互(HTTP)

在设备通过 MQTT 将数据上传云端后,我们希望手机 App 或其他上层应用能够获取这些数据并展示,同时也能够通过 App 控制设备(本例中如远程开关LED等)。OneNet 平台提供了丰富的 HTTP API 来满足这些需求。开发者可以通过 HTTP 请求查询设备状态、读取数据流、触发命令下发等。下面介绍 OneNet HTTP API 的基础用法,并以使用 Postman 测试为例,演示如何从云端获取设备数据。

6.1 OneNet 提供的 HTTP API 介绍

OneNet 的 HTTP API 遵循 RESTful 风格,对外统一以 api.heclouds.com 域名提供服务。不同的资源(设备、数据流、数据点、命令等)都有各自的 URL 路径。新版本的 OneNet 也提供了 open.iot.10086.cn 下更严格鉴权的接口(需要使用 Token),但为了简单起见,这里介绍经典的基于 API-Key 的接口,因为操作方便易测且足够满足大部分应用。

常用 API 概览:

  • 获取设备信息:GET http://api.heclouds.com/devices/<设备ID>
  • 获取数据流信息:GET http://api.heclouds.com/devices/<设备ID>/datastreams/<数据流ID>
  • 获取数据点:GET http://api.heclouds.com/devices/<设备ID>/datapoints?datastream_id=<数据流ID>&limit=<n> (APP通过http获取OneNet数据与命令下发〖应用层〗_onenet下发内容-CSDN博客)
    例如获取最新1条数据点,可用 limit=1
  • 批量获取多个数据流的数据点:GET http://api.heclouds.com/devices/<设备ID>/datapoints?datastream_id=temp,humi&limit=1 (多个流用逗号隔开)。
  • 下发命令到设备:POST http://api.heclouds.com/cmds?device_id=<设备ID>,在HTTP Body中写入命令内容(但OneNet的命令接口与MQTT互通需要设备实现特定逻辑,使用Topic更直接,后文详述)。
  • 直接向设备的 MQTT 主题发送消息:OneNet 有相应 API,可通过HTTP发布一条消息到某设备的某主题。如果设备订阅了该主题,就能收到。此接口在OneNet称为HTTP透传发布主题消息。调用方式如:
    POST http://api.heclouds.com/mqtt?topic=<TopicName>&device_id=<设备ID>
    Body中是消息内容文本 (Python Onenet 实现指南 - 51CTO博客)。这种方式本质上等价于服务器端代替我们去发布MQTT消息。

上述 API 调用均需要鉴权。鉴权通过在请求 Header 中加入 api-key 字段实现。api-key可以使用产品的 Master APIKey(具有该产品下所有设备操作权限),或者使用某台设备的 APIKey(只对该设备的数据有权限)。出于安全考虑,App 端通常不直接用Master Key,而是用设备的APIKey来获取该设备的数据。如果只读数据也可以给APIKey配置只读权限。我们的应用只是查看数据和发命令给自己的设备,用设备APIKey即可。

6.2 通过 HTTP 获取设备数据

使用 Postman 测试 GET 请求: 首先在 OneNet 开发者中心找到我们设备的 设备ID设备APIKey(或产品APIKey)。假设设备ID为123456789,数据流ID为temp。我们想获取最新的温度值。可以构造 HTTP GET 请求:

GET http://api.heclouds.com/devices/123456789/datapoints?datastream_id=temp&limit=1
Header:api-key: <设备APIKey>

使用 Postman 或浏览器插件发出请求。如果成功,OneNet会返回一个 JSON 数据。例如:

{"errno": 0,"data": {"count": 1,"datastreams": [{"id": "temp","datapoints": [{"at": "2025-03-10 06:30:00","value": 23.5}]}]},"error": "succ"
}

这里 "errno":0 表示无错误,"data" 下包含我们请求的数据点。count是本次返回的数据点数,datastreams数组列出了请求的各数据流以及数据点列表。可以看到最新数据点的时间戳和值 (APP通过http获取OneNet数据与命令下发〖应用层〗_onenet下发内容-CSDN博客) (APP通过http获取OneNet数据与命令下发〖应用层〗_onenet下发内容-CSDN博客)。App 可以解析此 JSON 提取所需数值。

如果想获取多个数据流的值(如温度和湿度一起),可以把 datastream_id 设为两个ID组合,或者干脆不指定 datastream_id 让其返回设备下所有数据流的最近点。返回格式会有多个 datastreams 条目,要根据 id 匹配。

注意: OneNet 平台在设备通过物模型上报属性后,会把每个属性映射为一个独立的数据流,其 ID 一般就是属性名。因此用以上接口获取属性值是可行的。例如属性 "humi" 也能通过 datastream_id=humi 查询。同理,也可以通过 OneNet Studio 提供的新接口获取设备的影子信息,但那需要 token 方式,不在本次讨论。

解析返回数据: 在 App 端,我们可以使用 JSON 库解析。例如在Android应用中,可以用 org.json 或 Gson 等库将返回字符串解析成对象 (APP通过http获取OneNet数据与命令下发〖应用层〗_onenet下发内容-CSDN博客)。在解析后,就能得到温度值 23.5(数字类型)。我们可以将其显示在 App 界面的文本框中。

周期获取 vs 推送: 由于我们这里使用 HTTP,是一种轮询获取机制。App 需要隔一定时间就发送 GET 请求刷新数据,才能近乎实时显示最新值。可以每隔5秒或10秒请求一次,根据应用需求和流量权衡。如果不想频繁轮询,OneNet 也提供推送机制(通过TCP长连接或MQTT方式),但移动App一般用HTTP轮询简单可靠。

示例:使用 Python 获取数据: 除了 Postman,我们也可以用简单的 Python 脚本测试 API。例如:

import requests
device_id = "123456789"
api_key = "abcdef...你的设备APIKey"
url = f"http://api.heclouds.com/devices/{device_id}/datapoints?datastream_id=temp&limit=1"
headers = {"api-key": api_key}
res = requests.get(url, headers=headers)
data = res.json()
print(data)

这段Python代码发送 GET 请求到 OneNet 数据点 API,获取 JSON 数据并打印 (Python Onenet 实现指南 - 51CTO博客) (Python Onenet 实现指南 - 51CTO博客)。若配置正确,会输出类似上面的 JSON。你可以在 PC 上用这个方法测试设备数据获取是否正常,然后再把逻辑移植到App。

6.3 通过 HTTP 控制设备(命令下发)

App 不仅读取数据,还需能够控制设备。例如用户在手机上按下“打开LED”按钮,我们希望通过 OneNet 让设备收到这个指令。实现方式有两种:

方法A:调用 OneNet 命令下发 API – OneNet 提供专门的命令通道API,即前述的 POST /cmds?device_id=<id> 接口。使用这个接口需要在HTTP body中写命令内容,该内容会通过OneNet内部下发到设备。传统OneNet设备(如使用EDP协议)能直接收到这个命令。但对于MQTT设备,OneNet后台其实会将命令转为 MQTT 消息发送到设备。所以方法A本质也要落到某个主题消息。具体来说,当我们调用/cmds接口发送一条命令字符串,OneNet 平台会将此字符串封装为 MQTT 消息,发送到设备的系统命令主题,即 $sys/{productID}/{deviceName}/cmd/request 等主题(老版OneNet MQTT的做法)。但新版本物模型设备未必使用这个路径,因此方法A适用于不使用自定义Topic的场景。

方法B:直接通过Topic API发送 – 如前面提到的 MQTT HTTP透传接口,可以在HTTP请求中指定发往设备的哪个Topic,这样更灵活。因为我们的设备已经订阅了 $sys/pid/dev/thing/property/set 主题,最自然的是让App通过HTTP直接发布一条消息到此主题。OneNet 有相应文档说明此用法 (Python Onenet 实现指南 - 51CTO博客)。

考虑我们已经采用物模型主题,那使用方法B更直接:App 调用HTTP接口,OneNet立刻把内容推给设备,无需定义其他命令通道。示例:我们希望设置 LED=1,可发送:

POST http://api.heclouds.com/mqtt?topic=$sys/<pid>/<dev>/thing/property/set&device_id=123456789
Header:api-key: <MasterAPIKey或设备APIKey>
Body (application/json):{"id":"app1","params":{"LED":{"value":1}}}

其中 device_id 参数确保消息发往特定设备,topic 参数指定主题。Body 就是设备 set 主题所需的 JSON 格式。我们可以用 Postman 发这个请求尝试。OneNet 返回的响应如果 errno:0 则表示消息已发送 (APP通过http获取OneNet数据与命令下发〖应用层〗_onenet下发内容-CSDN博客)。此时在设备端,ESP8266 会收到与平台UI下发命令相同的内容,通过 UART 通知STM32。STM32 执行后再MQTTPUB回复,平台将转发回复给HTTP调用方(App)。但是HTTP接口是否能直接拿到回复需要查询结果,因为HTTP是短连接并不能等回复。

更简单的做法是,App 下发命令后,可以隔几秒重新 GET 一次设备数据,看看对应状态改变没有。例如,App发送 LED=1 后,设备会执行点亮LED,同时也可以选择上报 LED 状态改变(比如作为一个数据流)。然后App轮询看到 LED状态流已变为1,则表示命令生效。这样就不需要App等待同步响应。

小结: HTTP API 非常强大也相对直观。一般流程是:设备->OneNet (MQTT) 实时上报数据;App->OneNet (HTTP) 请求读取数据,App->OneNet (HTTP) 发送控制、OneNet->设备 (MQTT) 转发控制。OneNet充当了中介,让设备和应用解耦。开发者要关注API使用是否正确,参数是否匹配。此外注意 APIKey 的保密和有效期。MasterKey权限很高,应妥善保存或在服务器端使用,不要放在App内。如果必须在App内调用,可以创建设备级APIKey(OneNet控制台的APIKey管理可添加,只赋予特定资源权限)来代替 MasterKey。

使用 HTTP API 的调试技巧: 善用 Postman 之类工具构造HTTP请求,并查看返回结果。OneNet官方文档详细列出了各接口的URL和返回格式 (最新版Onenet云平台HTTP协议接入上传数据_onenet物联网postman软件-CSDN博客)。当遇到问题时,检查HTTP状态码和返回的 errno、error信息。例如 errno=10可能是api-key无效,errno=6可能是设备未找到等。使用正确的 Content-Type(application/json)和 Header 是必要的,否则OneNet会报输入格式错误。

7. 综合示例:从设备到云端再到手机 App 的完整流程

这一节我们以一个具体的应用场景串起前面的所有环节:使用 STM32F103C8T6 定期采集环境温湿度,通过 ESP8266 MQTT 上传至 OneNet;OneNet 云端存储数据并提供查询;用户使用手机App通过HTTP获取实时温湿度并显示。同时,用户可在App上按下按钮控制远端STM32点亮或熄灭一个指示LED,通过 OneNet 平台的指令下发实现。

7.1 设备端(STM32 + ESP8266)过程

  1. 系统初始化: STM32上电后,初始化 USART、GPIO、传感器接口等。重置ESP8266并配置好WiFi连接和MQTT连接 OneNet(按第4章和第5章流程)。假设成功上线后,STM32订阅了属性设置主题以及上报回复主题。

  2. 采集传感数据: STM32 通过连接的传感器(如 DHT11 温湿度传感器)获取环境温度和湿度。DHT11 通常用单总线协议,可通过定时GPIO读取,本例略去实现细节,只假定我们得到两个变量 float temperaturefloat humidity。初始读取可能得到温度25.0℃,湿度60%。

  3. 上传数据: STM32 将上述值封装 JSON,通过 AT+MQTTPUB 发布至 OneNet。发布内容:

    {"id": "1", "params": { "temp": { "value": 25.0 }, "humi": { "value": 60.0 } } }
    

    OneNet 收到后会回应一个确认到 $sys/.../post/reply,ESP8266 收到打印,STM32读取到 "code":0,表示上报成功。此时在 OneNet 平台,这台设备的 temp 数据流和 humi 数据流各新增了一个数据点 25.0 和 60.0。

  4. 周期运行: STM32 设置一个定时,比如每隔10秒执行一次温湿度采集并上报。这样设备会持续地将环境数据发送到云端,云端形成时间序列数据。在等待间隔时,STM32也保持监听ESP8266串口以捕获可能的下行指令。

  5. 接收控制命令: 当用户在App上按下“打开LED”时,会触发云端下发。具体过程见后文App侧。此时 OneNet 平台会向 $sys/pid/dev/thing/property/set 发送:

    {"id": "100", "params": { "LED": { "value": 1 } } }
    

    ESP8266输出:

    +MQTTSUBRECV:0,"$sys/pid/dev/thing/property/set","{"id":"100","params":{"LED":{"value":1}}}"
    

    STM32 UART收到后,解析出 LED value = 1。它随即设置连接在 PB1(举例)的LED GPIO 输出高点亮 LED。然后构造回复 JSON:

    {"id": "100", "code": 200, "msg": "success"}
    

    并通过 AT+MQTTPUB 发送到 $sys/pid/dev/thing/property/set_reply 主题。OneNet 平台接收到回复,确认设备已执行命令。

  6. 状态上报(可选): STM32 也可以选择在执行命令后,将LED的新状态通过属性上报机制通知平台。例如再发布一次属性:

    {"id":"2","params":{ "LED": { "value": 1 } } }
    

    这样平台上也有 LED 状态的数据流更新。这在需要记录设备状态的应用中很有用。不过若只是瞬时动作也可以不必每次都上报。

  7. 等待其他指令或定期上报: LED 打开后,设备继续每10秒上报温湿度。假如一段时间后,用户在App点击“关闭LED”,流程类似以上,再将 LED value=0 下发,设备熄灭LED并回复。

设备端的整个逻辑可以用伪代码描述如下:

while(1) {if(time_to_sample) {read_temperature_humidity(&temp, &humi);send_mqtt_property_post(temp, humi);reset_timer();}if(uart_received_flag) {parse_uart_buffer();if(received_topic == PROPERTY_SET) {if(cmd.LED.value == 1) {HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);} else {HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);}send_mqtt_set_reply(cmd.id, 200);}clear_uart_flag();}// ... (other tasks)
}

7.2 云端平台过程

  • 当设备上线并订阅主题后,OneNet 将设备标记为“在线”,设备管理列表中可见在线状态。随后每次设备发布数据点,OneNet 平台都会验证数据格式并存储。如果数据对应物模型属性,则在设备详情的属性标签页显示最新值和历史趋势图。开发者中心也可以通过数据浏览API调试看到原始JSON。
  • 平台接收到 thing/property/post 上报,返回 result code=0。如有订阅post/reply的设备则收得到。
  • 平台在设备属性发生变化时,可触发触发器推送(这里没深入)。
  • 当 App 或用户通过平台下发控制时,平台将指令推送至设备的 MQTT 连接。在OneNet Studio界面,如果使用“在线调试”的“设置设备属性”功能填写 LED=1,也会以相同机制发送命令。App 通过HTTP接口发送时,平台收到HTTP请求,立即在后台把消息转发到设备 MQTT连接上的property/set主题。
  • 平台等待设备在超时时间内(比如默认3秒)回应 set_reply。如果收到 code=200,则在平台UI上显示执行成功;若超时未收到,平台可认为设备可能未在线或未执行,这时UI/接口会给出相应反馈(如设备无响应)。
  • 平台将 LED 属性新值存储更新。所以App再查询 LED 状态就会看到value=1。

7.3 移动 App 端过程

  • 初始化: 用户打开手机App(假设已经实现好UI界面,包括显示温湿度的文本和一个LED开关按钮)。App 内可能写死或从用户配置得到设备ID和 APIKey。
  • 获取最新数据: App 启动时调用 OneNet HTTP GET 接口获取温湿度。拿到返回 JSON 后解析出value,例如温度25.0、湿度60.0,更新界面显示“25.0°C, 60%”。App 可以每隔 10秒自动刷新一次,以跟踪变化 (APP通过http获取OneNet数据与命令下发〖应用层〗_onenet下发内容-CSDN博客) (APP通过http获取OneNet数据与命令下发〖应用层〗_onenet下发内容-CSDN博客)。
  • 控制操作: 当用户点击LED开关(比如一个toggle按钮从OFF滑到ON),App捕捉到事件,构造HTTP请求:
    POST http://api.heclouds.com/mqtt?topic=$sys/pid/dev/thing/property/set&device_id=123456789
    Header: api-key: <APIKey>
    Body: {"id":"app1","params":{"LED":{"value":1}}}
    
    并发送。OneNet返回一个 HTTP响应 JSON:
    { "errno": 0, "data": {}, "error": "succ" }
    
    表示平台已将消息发出 (最新版Onenet云平台HTTP协议接入上传数据_onenet物联网postman软件-CSDN博客)(注意,这不代表设备执行成功,只是发送成功)。
  • 等待结果: 为了确认设备是否真的打开LED,App 可以在发送几秒后再次 GET 设备属性或者设备LED状态数据流。由于我们的设备在执行后可能上报LED状态(如果实现了),那么大约1-2秒后,OneNet 平台的 LED 数据流就更新为1,App 下一次拉取会得到 LED value=1,于是可以在UI上将LED状态显示为“已打开”。如果应用需要即时反馈,也可以在按下按钮后,暂时假定成功改变UI状态,但最好在一定时间后核实。
  • 用户观察: App 上看到温湿度在定时刷新,比如逐渐温度变化。用户再次操作LED按钮关闭LED,App发送value=0,下发OneNet。设备执行后LED熄灭。下次App拉数据发现LED状态变0,于是同步UI。

整个流程打通后,我们实现了一个完整的IoT应用:STM32采集环境数据上云 -> 云端存储并提供查询 -> 移动端获取数据显示 -> 移动端发送控制指令 -> 设备执行并反馈,闭环完成。

7.4 常见问题与解答

问1: 为什么 STM32 一直无法连上 OneNet MQTT,AT+MQTTCONN 收到 ERROR 或一直超时?
答: 可能原因很多:

  • 检查产品ID、设备ID、APIKey 是否对应正确 (连接onenet云mqtt报文_183.230.40.96-CSDN博客)。尤其别把设备ID和产品ID弄混。设备ID一般是纯数字,产品ID可能是数字或长度较短字符串。
  • 如果使用 Token 作为密码,要确保 Token 正确生成且未过期 (最新版Onenet云平台HTTP协议接入上传数据_onenet物联网postman软件-CSDN博客)。Token 的 et(过期时间)默认可能很短或需要自行设定较长时间。
  • 端口和服务器地址要匹配。如果用183.230.40.39,端口必须6002;用mqtt.heclouds.com则建议端口1883。若固件不支持域名,可以用IP。
  • MQTTUSERCFG 的 cleansession 参数要与 MQTTCONN 的 clean session 保持一致,否则会连不上。有的固件实现要求这个匹配(例如都用1)。
  • 检查 ESP8266 是否早先有保持的连接没有断开。可以在尝试前 AT+MQTTCLEAN=0 断开旧连接(若支持),或干脆复位模块再连。
  • 确认你的 OneNet 产品的接入协议确实是 MQTT,设备也在MQTT列表里。如果产品是HTTP类型,用MQTT连接可能会被拒绝协议不匹配。

问2: ESP8266 AT 指令总是返回 weird symbolsERROR
答: 如果收到乱码,可能是波特率不对。ESP8266 默认波特率常为115200;确认 STM32 USART 初始化也设为115200 (STM32与物联网01-ESP8266基本操作 - 博客园)。若还是乱码,可以尝试降低ESP8266的波特率来匹配STM32,比如先用串口调试工具连ESP8266发送 AT+UART=9600,8,1,0,0 将其改为9600, 然后STM32也配置9600通信。
如果返回ERROR多出现在发送长命令时,可能是命令格式有误或串口数据丢失。要确保字符串没有拼写错误且包含必要的引号和逗号。此外检查ESP8266接收缓冲是否足够处理长命令(如MQTTPUBRAW发送时注意分两步)。另外,先发的指令没结束响应又发下一个也会引发 ERROR,因此必须串行等待上条命令OK后再发下一条。可以在指令间加入适当延时 (STM32使用esp8266的AT指令连接mqtt服务器,以Thing Cloud为例(标准库和HAL库)_stm32 mqtt at指令-CSDN博客)。

问3: 数据上报成功了,但在 OneNet 平台看不到曲线或数据?
答: 首先,用 OneNet 开发者中心的“设备调试”或API调试工具查看设备是否有数据。如果 MQTT 连接和上报都OK,检查 JSON 格式和数据类型:OneNet 区分数据类型(数值、字符串等),如果物模型里属性定义为数值,你上传的 JSON value必须是数值而非字符串,否则平台可能拒绝入库。另一个可能原因:OneNet Studio需要你先为产品添加**数据流模板(物模型)**才能在可视化中看到图表。如果没定义过数据流,OneNet老平台会自动根据首次上报创建数据流,但新Studio里尽管数据收到了,也许不会显示曲线,除非在物模型里注册该属性。建议提前在产品的“数据流模板”里添加 temp 和 humi 属性。
如果以上都检查过还是无数据,考虑设备APIKey权限。若用Master APIKey上传HTTP数据,要在请求Header带对的 key (最新版Onenet云平台HTTP协议接入上传数据_onenet物联网postman软件-CSDN博客)。对于 MQTT 上报,只要连上成功一般不会有权限问题。可尝试用 MQTT.fx 工具模拟上传看平台表现,以分辨问题出在设备端还是平台端。

问4: HTTP 获取数据时返回 {"errno":10, "error":"key invalid"} 或类似错误?
答: errno=10表示 APIKey 无效或没有权限。请检查HTTP请求Header中的 api-key 是否正确(注意不要拼成 apikey 或 Api-Key,必须全小写中间有连字符) (轻松使用中移物联网平台Onenet,MQTT协议快速接入实验 - ThingsKit)。并确认使用的Key对应设备。若设备ID与APIKey不匹配,也会无权限(比如用A设备的APIKey去查B设备的数据)。可以在 OneNet 控制台的设备管理中点设备详情,看右上角是否可以获取该设备的APIKey,或者使用产品的 Master APIKey尝试。如果Master Key也提示无效,可能是key填错或已失效(OneNet某些操作需要先激活产品)。
另外,如果你的HTTP请求用了 https://open.iot.10086.cn/studio/http 之类的新域名,则不能用APIKey,要改用Token鉴权 (最新版Onenet云平台HTTP协议接入上传数据_onenet物联网postman软件-CSDN博客)。建议使用api.heclouds.com方便。

问5: 移动App能否直接用MQTT而不是HTTP?
答: 当然可以。App 其实也能作为 MQTT 客户端连接 OneNet Broker(用手机流量/WiFi),只要提供正确的产品ID/设备ID/APIKey。但通常手机App不被视为OneNet的“设备”,而是一种应用。如果App以设备身份MQTT接入,会占用一个设备ID,而且OneNet没有针对应用的MQTT通道,只能让App也作为同产品下的“另一设备”加入。这带来管理和安全的复杂度,不如调用HTTP API方便。因此常见实践是:设备用MQTT,App用HTTP。不过OneNet也允许第三方服务器通过MQTT订阅设备数据实现实时推送功能,如果需要,可以研究 OneNet 提供的应用MQTT接口或者结合使用OneNet的MQTT桥接能力。对于本案例,HTTP 足矣,实时性要求不高且实现简单。

问6: STM32 处理 MQTT 下行消息时有时解析不完整,可能丢字符,怎么办?
答: 这可能因为 UART 接收缓冲过小或处理不及时。如果命令JSON较长,而STM32没有用中断/DMAdma持续接收,很可能丢失部分数据。建议开启UART空闲中断,将每次接收的数据放入循环缓冲,然后解析一整帧。也可考虑降低ESP8266的UART发送速度或拆分消息。因为ESP8266收到MQTT消息后,一次性通过串口吐出,对于72MHz MCU还是能处理的,只是要确保接收中断优先级高且处理快。可以简单做法:利用 '\n' 换行判断一条消息结束,然后处理。OneNet的MQTTURC一般一条消息就是一行。

问7: 能否在 OneNet 平台直接让设备把数据转发到我自己的服务器?
答: OneNet 提供数据转发HTTP触发器等功能,可以配置当设备上传数据或事件发生时,平台自动向你的业务服务器发送HTTP POST通知。这属于OneNet更高级的应用功能。对于初学者,先实现基本的云存储和查询较好。如果将来要大规模部署设备,并在自己服务器汇总处理数据,可考虑使用 OneNet OpenAPI 拉取数据,或配置触发器使OneNet推送数据到指定URL。详细可以查阅OneNet开放平台文档中的“数据转发”和“触发器”章节。


至此,我们完整地介绍了 STM32F103C8T6 + ESP8266-01 连接 OneNet 平台并通过 MQTT/HTTP 进行数据通信的流程。从 OneNet 平台准备、硬件连接、固件指令、到STM32代码逻辑、再到应用层接口都进行了说明和示例。希望通过本指南,读者能够搭建起自己的物联网小系统,实现设备数据上云和远程控制。OneNet 平台功能丰富,在掌握上述基础后,可以进一步探索如:数据触发报警、设备分享、更多传感类型接入、以及结合微信小程序等扩展,实现更加完善的物联网应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/31277.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

知识库Dify和cherry无法解析影印pdf word解决方案

近期收到大量读者反馈&#xff1a;上传pdf/图文PDF到Dify、Cherry Studio等知识库时&#xff0c;普遍存在格式错乱、图片丢失、表格失效三大痛点。 在试用的几款知识库中除了ragflow具备图片解析的能力外&#xff0c;其他的都只能解析文本。 如果想要解析扫描件&#xff0c…

Webservice创建

Webservice创建 服务端创建 3层架构 service注解&#xff08;commom模块&#xff09; serviceimpl&#xff08;server&#xff09; 服务端拦截器的编写 客户端拦截器 客户端调用服务端&#xff08;CXF代理&#xff09; 客户端调用服务端&#xff08;动态模式调用&a…

腾讯云低代码开发应用

创建客户端应用 如上所示&#xff0c;登录腾讯云微搭低代码业务控制台&#xff0c;开始搭建企业官网应用 如上所示&#xff0c;在腾讯云微搭低代码业务控制台中&#xff0c;开始创建企业官网应用 如上所示&#xff0c;在腾讯云微搭低代码业务控制台中&#xff0c;开始编辑企业官…

【Java开发指南 | 第三十四篇】IDEA没有Java Enterprise——解决方法

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 1、新建Java项目2、单击项目名&#xff0c;并连续按两次shift键3、在搜索栏搜索"添加框架支持"4、勾选Web应用程序5、最终界面6、添加Tomcat 1、新建Java项目 2、单击项目名&#xff0c;并连续按两次…

深度学习原理与Pytorch实战

深度学习原理与Pytorch实战 第2版 强化学习人工智能神经网络书籍 python动手学深度学习框架书 TransformerBERT图神经网络&#xff1a; 技术讲解 编辑推荐 1.基于PyTorch新版本&#xff0c;涵盖深度学习基础知识和前沿技术&#xff0c;由浅入深&#xff0c;通俗易懂&#xf…

uniapp项目运行失败Error: getaddrinfo *.bspapp.com 文件查找失败uview-ui及推荐MarkDown软件 Typora

一、uniapp项目运行失败Error: getaddrinfo *.bspapp.com 文件查找失败uview-ui 在运行一个uniapp项目时&#xff0c;出现报错 文件查找失败&#xff1a;uview-ui&#xff0c;Error: getaddrinfo ENOTFOUND 960c0a.bspapp.com。hostname异常&#xff0c;报错的详细信息如下&…

什么是vue的keep-alive?它是如何实现的?具体缓存了什么内容?

文章目录 一、keep-alive 的核心作用二、实现原理1. 缓存管理策略2. 核心源码解析&#xff08;Vue 2.x 简化版&#xff09;3. 缓存生命周期 三、缓存的具体内容1. 缓存对象结构2. 具体缓存内容 四、使用示例1. 基础用法2. 配置缓存策略 五、注意事项六、实现流程图解 Vue 的 k…

pytest基础知识

pytest知识了解 pytest的基础知识了解&#xff1a;Python测试框架之pytest详解_lovedingd的博客-CSDN博客_pytest框架 (包含设置断点&#xff0c;pdb&#xff0c;获取最慢的10个用例的执行耗时) pytest-pytest.main()运行测试用例&#xff0c;pytest参数&#xff1a; pytest-…

Liunx(CentOS-6-x86_64)使用Nginx部署Vue项目

一&#xff1a;编译vue项目和上传到linux系统 通过本地编译器编译后的文件 上传服务器后的 二&#xff1a;安装 node&#xff08;版本 v16.20.2&#xff09;和npm&#xff08; 8.19.4或 9.6.5&#xff09; 备注一&#xff1a;安装nodejs就是安装node和npm&#xff0c; su…

分布式锁—Redisson的同步器组件

1.Redisson的分布式锁简单总结 Redisson分布式锁包括&#xff1a;可重入锁、公平锁、联锁、红锁、读写锁。 (1)可重入锁RedissonLock 非公平锁&#xff0c;最基础的分布式锁&#xff0c;最常用的锁。 (2)公平锁RedissonFairLock 各个客户端尝试获取锁时会排队&#xff0c;按照队…

2025年渗透测试面试题总结-字某某动-安全研究实习生(一面)(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 字某某动-安全研究实习生&#xff08;一面&#xff09; 一、岗位认知与方向选择 1. 对公司业务的理解 …

Dify平台部署记录

安装dify项目 官网地址&#xff1a;http://difyai.com/ github地址&#xff1a;https://github.com/langgenius/dify 下载项目&#xff1a; git clone https://github.com/langgenius/dify.git下载过慢&#xff0c;直接访问网页下载zip压缩包&#xff1a; 解压&#xff0c;…

串口数据记录仪DIY,体积小,全开源

作用 产品到客户现场出现异常情况&#xff0c;这个时候就需要一个日志记录仪、黑匣子&#xff0c;可以记录产品的工作情况&#xff0c;当出现异常时&#xff0c;可以搜集到上下文的数据&#xff0c;从而判断问题原因。 之前从网上买过&#xff0c;但是出现过丢数据的情况耽误…

如何用HTML5 Canvas实现电子签名功能✍️

&#x1f916; 作者简介&#xff1a;水煮白菜王&#xff0c;一位资深前端劝退师 &#x1f47b; &#x1f440; 文章专栏&#xff1a; 前端专栏 &#xff0c;记录一下平时在博客写作中&#xff0c;总结出的一些开发技巧和知识归纳总结✍。 感谢支持&#x1f495;&#x1f495;&a…

Uniapp项目运行到微信小程序、H5、APP等多个平台教程

摘要&#xff1a;Uniapp作为一款基于Vue.js的跨平台开发框架&#xff0c;支持“一次开发&#xff0c;多端部署”。本文将手把手教你如何将Uniapp项目运行到微信小程序、H5、APP等多个平台&#xff0c;并解析常见问题。 一、环境准备 在开始前&#xff0c;请确保已安装以下工具…

Python设计模式 - 建造者模式

定义 建造者模式是一种创建型设计模式&#xff0c;主要用于构建包含多个组成部分的复杂对象。它将对象的构建过程与表示分离&#xff0c;使得同样的构建过程可以创建不同的对象表示。 结构 抽象建造者&#xff08;Builder&#xff09;&#xff1a;声明创建产品的各个部件的方…

音乐API

https://neteasecloudmusicapi.vercel.app/docs/#/https://neteasecloudmusicapi.vercel.app/docs/#/ 使用实例 所有榜单内容摘要 说明 : 调用此接口,可获取所有榜单内容摘要 接口地址 : /toplist/detail 调用例子 : /toplist/detail 获取歌单所有歌曲 说明 : 由于网易云…

Jetpack Compose — 入门实践

一、项目中使用 Jetpack Compose 从此节开始,为方便起见,如无特殊说明,Compose 均指代 Jetpack Compose。 开发工具: Android Studio 1.1 创建支持 Compose 新应用 新版 Android Studio 默认创建新项目即为 Compose 项目。 注意:在 Language 下拉菜单中,Kotlin 是唯一可…

【day12】进程切换与调度:linux系统的幕后操控术

【Day12】进程切换与调度&#xff1a;linux系统的幕后操控术 进程优先级进程属性&#xff1a;UID进程属性&#xff1a;PRI和NI进程饥饿 竞争/独立/并行/并发进程切换进程调度&#xff08;O(1)调度算法&#xff09; 进程优先级 进程优先级的本质&#xff1a;衡量进程得到CPU资源…

STM32之BKP

VBAT备用电源。接的时候和主电源共地&#xff0c;正极接在一起&#xff0c;中间连接一个100nf的电容。BKP是RAM存储器。 四组VDD都要接到3.3V的电源上&#xff0c;要使用备用电池&#xff0c;就把电池正极接到VBAT&#xff0c;负极跟主电源共地。 TEMPER引脚先加一个默认的上拉…