RT-Thread 软件包-IoT-OneNET①

本文介绍了RT-Thread针对中国移动OneNET平台的软件包,包括包的结构、获取方式、使用方法、示例代码以及注意事项,重点强调了断线重连、自定义响应等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RT-Thread 软件包-IoT-OneNET①

在这里插入图片描述

OneNET

中文页 | English

1、介绍

OneNET 平台是中国移动基于物联网产业打造的生态平台,具有高并发可用、多协议接入、丰富 API 支持、数据安全存储、快速应用孵化等特点,同时,OneNET 平台还提供全方位支撑,加速用户产品的开发速度。

OneNET 软件包是 RT-Thread 针对 OneNET 平台连接做的的适配,通过这个软件包,可以让设备在 RT-Thread 上非常方便的连接 OneNet 平台,完成数据的发送、接收、设备的注册和控制等功能。

软件包具有以下优点:

  • 断线重连
  • 自动注册
  • 自定义响应函数
  • 自定义 topic 和 topic 对应的回调函数
  • 上传二进制数据

更多介绍请查看详细介绍

1.1 目录结构

OneNET
│   README.md                       // 软件包使用说明
│   SConscript                      // RT-Thread 默认的构建脚本
├───docs 
│   └───figures                     // 文档使用图片
│   │   api.md                      // API 使用说明
│   │   introduction.md             // 软件包详细介绍
│   │   principle.md                // 实现原理
│   │   README.md                   // 文档结构说明
│   │   samples.md                  // 软件包示例
│   │   user-guide.md               // 使用说明
│   │   port.md                     // 移植说明文档
│   └───version.md                  // 版本
├───ports                           // 移植文件                 
│   └───onenet_port.c               // 移植文件模板
├───samples                         // 示例代码
│   └───onenet_sample.c             // 软件包应用示例代码
├───inc                             // 头文件
└───src                             // 源文件

1.2 许可证

OneNET package 遵循 GUN GPL 许可,详见 LICENSE 文件。

1.3 依赖

2、获取方式

使用 OneNET package 需要在 RT-Thread 的包管理中选中它,具体路径如下:

RT-Thread online packages
    IoT - internet of things  --->
        IoT Cloud  --->
            [*] OneNET: China Mobile OneNet cloud SDK for RT-Thread

进入 onenet 软件包的配置菜单按下图所示配置,里面的信息依据自己的产品和设备的实际情况填写

--- OneNET: China Mobile OneNet cloud SDK for RT-Thread                            
    [ ]   Enable OneNET sample                                                  
    [*]   Enable support MQTT protocol                                                 
    [ ]   Enable OneNET automatic register device (NEW)                             
    (35936966) device id                                                             
    (201807171718) auth info
    (H3ak5Bbl0NxpW3QVVe33InnPxOg=) api key                                              
    (156418) product id                                                                 
    (dVZ=ZjVJvGjXIUDsbropzg1a8Dw=) master/product apikey (NEW)                       
        version (latest)  --->

Enable OneNET sample :开启 OneNET 示例代码

Enable support MQTT protocol :开启 MQTT 协议连接 OneNET 支持

Enable OneNET automatic register device :开启 OneNET 自动注册设备功能

device id :配置云端创建设备时获取的 设备ID

auth info :配置云端创建产品时 用户自定义的鉴权信息 (每个产品的每个设备唯一)

api key :配置云端创建设备时获取的 APIkey

product id :配置云端创建产品时获取的 产品ID

master/product apikey :配置云端创建产品时获取的 产品APIKey

配置完成后让 RT-Thread 的包管理器自动更新,或者使用 pkgs --update 命令更新包到 BSP 中。

3、使用 OneNET 软件包

  • 详细的示例介绍,请参考 示例文档

  • 如何从零开始使用,请参考 用户手册

  • 完整的 API 文档,请参考 API 手册

  • OneNET 软件包工作原理,请参考 工作原理

  • OneNET 软件包移植,请参考 移植手册

  • 更多详细介绍文档位于 /docs 文件夹下,使用软件包进行开发前请务必查看

4、注意事项

  • 未启用自动注册功能,在 menuconfig 选项中配置的 device idapi keyproduct idauth info 等信息需要和 OneNET 云端新建产品和新建设备时获取的信息一致。
  • 启用自动注册功能后,需要阅读移植手册并完成移植工作。
  • 初始化 OneNET package 之前需要设备联网成功

示例代码

…\bsp\stm32\stm32l452-st-nucleo\board\board.c

/*
 * File      : onenet_http.c
 * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Change Logs:
 * Date           Author       Notes
 * 2018-04-24     chenyong     first version
 */
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>

#include <cJSON_util.h>
#include <webclient.h>

#include <onenet.h>

#define DBG_ENABLE
#define DBG_COLOR
#define DBG_SECTION_NAME    "onenet.http"
#if ONENET_DEBUG
#define DBG_LEVEL           DBG_LOG
#else
#define DBG_LEVEL           DBG_INFO
#endif /* ONENET_DEBUG */

#include <rtdbg.h>

#define ONENET_SEND_DATA_LEN           1024
#define ONENET_HEAD_DATA_LEN           256
#define ONENET_CON_URI_LEN             256
#define ONENET_RECV_RESP_LEN           1024
#define ONENET_TIME_BUF_LEN            24
#define ONENET_HTTP_HEAD_LEN           1024

#if WEBCLIENT_SW_VERSION_NUM < 0x20000
#error "Please upgrade the webclient version "
#endif

#define WEBCLIENT_HEADER_ADD(session, fmt, ...)                                                         \
    do                                                                                                  \
    {                                                                                                   \
        if (webclient_header_fields_add(session, fmt, ##__VA_ARGS__) < 0)                               \
        {                                                                                               \
            LOG_E("webclient add header failed!");                                                      \
            goto __exit;                                                                                \
        }                                                                                               \
    } while(0);                                                                                         \

extern struct rt_onenet_info onenet_info;

static rt_err_t onenet_upload_data(char *send_buffer)
{
    struct webclient_session *session = RT_NULL;
    char *buffer = send_buffer;
    char *URI = RT_NULL;
    rt_err_t result = RT_EOK;

    RT_ASSERT(send_buffer);

    URI = ONENET_CALLOC(1, ONENET_CON_URI_LEN);
    if (URI == RT_NULL)
    {
        LOG_E("OneNet Send data failed! No memory for URI buffer!");
        result = -RT_ENOMEM;
        goto __exit;
    }

    rt_snprintf(URI, ONENET_CON_URI_LEN, "http://api.heclouds.com/devices/%s/datapoints?type=3", onenet_info.device_id);

    session = webclient_session_create(ONENET_HTTP_HEAD_LEN);
    if (session == RT_NULL)
    {
        result = -RT_ERROR;
        goto __exit;
    }

    WEBCLIENT_HEADER_ADD(session, "api-key: %s\r\n", onenet_info.api_key);
    WEBCLIENT_HEADER_ADD(session, "Content-Length: %d\r\n", strlen(buffer));
    WEBCLIENT_HEADER_ADD(session, "Content-Type: application/octet-stream\r\n");

    if (webclient_post(session, URI, buffer, strlen(buffer)) != 200)
    {
        result = -RT_ERROR;
        goto __exit;
    }

    LOG_D("buffer : %.*s", strlen(buffer), buffer);

__exit:
    if (session)
    {
        webclient_close(session);
    }
    if (URI)
    {
        ONENET_FREE(URI);
    }

    return result;
}


static rt_err_t onenet_get_string_data(const char *ds_name, const char *str, char **out_buff)
{
    rt_err_t result = RT_EOK;
    cJSON *root = RT_NULL;

    RT_ASSERT(ds_name);
    RT_ASSERT(str);
    RT_ASSERT(out_buff);

    root = cJSON_CreateObject();
    if (!root)
    {
        LOG_E("onenet publish string data failed! cJSON create object error return NULL!");
        return -RT_ENOMEM;
    }

    cJSON_AddStringToObject(root, ds_name, str);

    /* render a cJSON structure to buffer */
    *out_buff = cJSON_PrintUnformatted(root);
    if (!(*out_buff))
    {
        LOG_E("onenet publish string data failed! cJSON print unformatted error return NULL!");
        result = -RT_ENOMEM;
        goto __exit;
    }

__exit:
    if (root)
    {
        cJSON_Delete(root);
    }

    return result;
}

static rt_err_t onenet_get_digit_data(const char *ds_name, const double digit, char **out_buff)
{
    rt_err_t result = RT_EOK;
    cJSON *root = RT_NULL;

    RT_ASSERT(ds_name);
    RT_ASSERT(out_buff);

    root = cJSON_CreateObject();
    if (!root)
    {
        LOG_E("onenet publish digit data failed! cJSON create object error return NULL!");
        return -RT_ENOMEM;
    }

    cJSON_AddNumberToObject(root, ds_name, digit);

    /* render a cJSON structure to buffer */
    *out_buff = cJSON_PrintUnformatted(root);
    if (!(*out_buff))
    {
        LOG_E("onenet publish digit data failed! cJSON print unformatted error return NULL!");
        result = -RT_ENOMEM;
        goto __exit;
    }

__exit:
    if (root)
    {
        cJSON_Delete(root);
    }

    return result;
}

/**
 * upload digit data to OneNET cloud.
 *
 * @param   ds_name     datastream name
 * @param   digit       digit data
 *
 * @return  0 : upload data success
 *         -5 : no memory
 */
rt_err_t onenet_http_upload_digit(const char *ds_name, const double digit)
{
    char *send_buffer = RT_NULL;
    rt_err_t result = RT_EOK;

    RT_ASSERT(ds_name);

    /* get JSON format data */
    result = onenet_get_digit_data(ds_name, digit, &send_buffer);
    if (result < 0)
    {
        goto __exit;
    }

    /* send data to cloud by HTTP */
    result = onenet_upload_data(send_buffer);
    if (result < 0)
    {
        goto __exit;
    }

__exit:
    if (send_buffer)
    {
        cJSON_free(send_buffer);
    }

    return result;
}

/**
 * upload string data to OneNET cloud.
 *
 * @param   ds_name     datastream name
 * @param   str         string data
 *
 * @return  0 : upload data success
 *         -5 : no memory
 */
rt_err_t onenet_http_upload_string(const char *ds_name, const char *str)
{
    char *send_buffer = RT_NULL;
    rt_err_t result = RT_EOK;

    RT_ASSERT(ds_name);
    RT_ASSERT(str);

    /* get JSON format data */
    result = onenet_get_string_data(ds_name, str, &send_buffer);
    if (result < 0)
    {
        goto __exit;
    }

    /* send data to cloud by HTTP */
    result = onenet_upload_data(send_buffer);
    if (result < 0)
    {
        goto __exit;
    }

__exit:
    if (send_buffer)
    {
        cJSON_free(send_buffer);
    }

    return result;
}

#ifdef ONENET_USING_AUTO_REGISTER
static rt_err_t response_register_handlers(const unsigned char *rec_buf, const size_t length)
{
    cJSON *root = RT_NULL;
    cJSON *item = RT_NULL;
    cJSON *itemid = RT_NULL;
    cJSON *itemapikey = RT_NULL;

    RT_ASSERT(rec_buf);

    LOG_D("response is %.*s", length, rec_buf);

    root = cJSON_Parse((char *)rec_buf);
    if (!root)
    {
        LOG_E("onenet register device failed! cJSON Parse data error return NULL!");
        return -RT_ENOMEM;
    }

    item = cJSON_GetObjectItem(root, "errno");
    if (item->valueint == 0)
    {
        itemid = cJSON_GetObjectItem(root->child->next, "device_id");
        itemapikey = cJSON_GetObjectItem(root->child->next, "key");

        onenet_port_save_device_info(itemid->valuestring, itemapikey->valuestring);
    }
    else
    {
        LOG_E("onenet register device failed! errno is %d", item->valueint);
        return -RT_ERROR;
    }

    return RT_EOK;

}



#endif /* ONENET_USING_AUTO_REGISTER */







维护人:

缘起: RT_Thread款优秀的国产RTOS,我大概两年前就了解到了RT_Thread,但是本人从事是物联网嵌入式WIFI模块二次开发,当时RT_Thread还不支持直接对WIFI模块二次开发,仅支持MCU+AT指令方式控制WIFI模块间接连云(如ESP8266),近来了解到RT_Thread已经支持WIFI模块二次开发,目前支持联盛德W60x,RealTek的RTL8710系列,于是终于按捺不住内心的冲动,决定先从个简单的RGB三色灯项目入手,深入自己物联网之旅。本项目仅支持中国移动onenet平台,之后会陆续增加各个主流云平台的支持。 RT_Thread简介 [RT-Thread](https://www.rt-thread.org)是个集实时操作系统(RTOS)内核、中间件组件和开发者社区于体的技术平台,由熊谱翔先生带领并集合开源社区力量开发而成,RT-Thread也是个组件完整丰富、高度可伸缩、简易开发、超低功耗、高安全性的物联网操作系统。RT-Thread具备IoT OS平台所需的所有关键组件,例如GUI、网络协议栈、安全传输、低功耗组件等等。经过11年的累积发展,RT-Thread已经拥有个国内最大的嵌入式开源社区,同时被广泛应用于能源、车载、医疗、消费电子等多个行业,累积装机量超过2亿台,成为国人自主开发、国内最成熟稳定和装机量最大的开源RTOS。 W60X简介 W60X系列Wi-Fi SoC芯片是由国内联盛德公司研发,目前要有W600和W601两款芯片,本项目采用W600,W600是款支持多接口、多协议的无线局域网 IEEE802.11n(1T1R)的 SoC 芯片。适用于智能家 电、智能家居、无线音视频、智能玩具、医疗监护、工业控制等物联网应用领域。 (1) 为什么选择W600? 次偶然的会议上,我了解到了W600的存在,号称在华为Hilink项目上,有客户使用esp8266没有通过华为的认证,而使用W600通过了华为认证,原来我以为在wifi性价比的道路上除了乐鑫ESP8266和瑞昱RTL8710,恐难有敌手,于是开始对W600另眼相看,便开始某宝疯狂搜索,发现了款9.9元基于W600的[TB_01开发板](https://item.taobao.com/item.htm?spm=a230r.1.14.19... TB-01 是星通智联开发款基于联盛德 W600 的超小体积核心开发板,该开发板引出了芯片的所有IO,并且内置LDO和UART传输芯片,只需根 Micro USB 数据线与电脑连接即可使用,支持键下载,外设拥有5个环形LED和2颗按键,调试操作极其方便。 RGB_LED项目简介 本文是关于RGB三色灯项目,基于RT_Thread提供的onenet-v1.0.0 packages连接中国移动onenet平台,packages中支持http和mqtt两种方式连接onenet,本项目采用mqtt方式连接,同时修改数据上报逻辑,原有组件包是每次回复单个数据点的数据,修改后支持次性上报所有数据点,同时调整mqtt数据上报处理逻辑,解决连续两次调用数据发送接口,仅有第次发出去的问题。 文档 如下是相关的文档教程, 方便大家使用. [TB_01官方资料](http://docs.thingsturn.com/product/) [Keil下RT_Thread W600 开发环境配置](http://docs.thingsturn.com/development/soc/start/) [W600固件烧录指南](http://docs.thingsturn.com/application_note/downlo... github地址:https://github.com/solitary-sand/rt_thread_w600_ap... 作者:叶孤沙 (qq 2985672336) QQ交流群:906015840 (备注:物联网项目交流)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

华为奋斗者精神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值