基于透传协议开发虚拟光照度探测器

更新时间:2018-05-25 10:07:45

简介

为了让开发者在没有硬件的情况下仍能体验平台的透传协议功能,本示例在Linux系统下实现一个虚拟的光照度探测器。主要功能如下:

  • 光照度值定期5s上报
    定义属性lux标识当前光照度值,类型为整型,取值范围0 ~ 100。

  • 当光照值超过设定阈值时触发告警事件上报
    定义光照过高告警事件OverLuxAlarm,事件参数为当前光照值lux。

  • 通过服务调用设置告警阈值
    定义异步服务SetAlarmThreshold,服务入参为threshold,整形,表示告警阈值。

步骤

产品功能定义

创建光照度探测器产品(此步骤省略),数据格式选择:透传/自定义格式。功能定义如下所示:

image.png | center | 621x298

新增测试设备

image.png | center | 606x295

生成SDK及脚本

生成Linux下的SDK示例

image.png | center | 511x129

根据硬件平台选择相应的参考示例,这里我们选择其他平台。

image.png | center | 514x240

生成好之后点击下载按钮。

image.png | center | 524x128

生成脚本

image.png | center | 521x138

点击自动生成脚本按钮生成脚本。

image.png | center | 535x269

脚本生成好之后需要进行简单验证之后才能提交生效,这里先不做,保留页面等会在回来验证。

SDK修改

将测试设备的激活凭证写入设备

按如下说明修改./sdk-core/inc/common.h文件:

image.png | center | 411x146

编译&运行

进入platform/linux/目录,执行命令make clean && make support=mqtt编译。执行命令./out_mqtt运行示例,日志如下。

image.png | center | 728x393

测试属性上报

set [属性名]=[值]的格式修改设备的属性值,例如set lux=10,再执行post命令上报修改的属性,模拟设备就会把变化的数据通过二进制数据上报到云端。

image.png | center | 714x218

如上报错code=6200,我们需要去提交脚本才能保证二进制数据能被正常解析。这里利用这次上报生成的二进制数据帧用于校验脚本,校验成功后如下所示,提交脚本即可。

image.png | center | 651x414

脚本提交成功后,我们再测试一次属性上报,这回执行set lux=66,再执行post,结果如下,说明脚本已经生效。

image.png | center | 654x213

在云端查看运行状态,说明已经成功上报。至此设备到云的链路已经走通来,接下来我们开始进入需求的功能开发。

image.png | center | 393x235

业务逻辑开发

属性定时上报

实现userHandler函数,放在main函数的while(1)内调用。

void userHandler(void)
{
    Uint8_t lux;
    static Uint32_t last, now;
    sdk_global_t *hsdk = (sdk_global_t *)getSdkObjHandle();

    /* 采集光照度的值,这里随机生成 */
    lux = rand() % 101;  // 取值0~100
    now = hsdk->jiffies;
    if (now - last >= 5000)
    {
        last = now;
        boneSet_lux(lux);   /* 调用设置lux的API */
        bonePostProp();     /* 上报 */
    }
}

Int32_t main(Int32_t argc, char *argv[])
{
    // 此处省略其他代码

    while (1)
    {
        boneSdkRun();

        userHandler();

        usleep(100 * 1000);
    }

重新将代码编译运行之后可以到云端查看属性的上报日志信息如下。说明:由于使用的软件定时器不是很准,上报的时间间隔并非是严格的5s。

image.png | center | 496x230

光照度过高告警上报

默认阈值为99,当超过该值时会触发光照度过高告警。

Uint8_t threshold = 99;    /* 告警阈值 */

void userHandler(void)
{
    Uint8_t lux;
    static Uint32_t last1, last2, now;
    sdk_global_t *hsdk = (sdk_global_t *)getSdkObjHandle();

    /* 采集光照度的值,这里随机生成 */
    lux = rand() % 101;  // 取值0~100
    now = hsdk->jiffies;

    if ((lux > threshold) && (now - last1) > 2000)
    {
        /* 上报事件,为了避免频繁上报,这里约束事件上报间隔最短2s */
        eo_OverLuxAlarm_t oarg;

        oarg.a_lux = lux;
        boneEvntPost_OverLuxAlarm(&oarg);   /* 调用光照过高告警事件API */

        last1 = now;
    }

    if (now - last2 >= 5000)
    {
        last2 = now;
        boneSet_lux(lux);   /* 调用设置lux的API */
        bonePostProp();     /* 上报 */
    }   

}

编译执行后,在云端收到当告警信息如下:

image.png | center | 575x361

云端修改告警阈值

通过云端修改设备上的告警阈值,需要在服务处理接口中添加自己的逻辑代码。

extern Uint8_t threshold;

static Int32_t boneServCall_SetAlarmThreshold(Uint32_t id, Uint8_t *data, Uint16_t length)
{
    Uint8_t len = 0;
    Uint8_t buffer[64] = {0};
    si_SetAlarmThreshold_t *iarg;
    BONE_UNUSED(len);
    BONE_UNUSED(buffer);

    // 1. 解析入参(没有则忽略)
    iarg = (si_SetAlarmThreshold_t*)data;

    // 2. 处理入参(没有则忽略)
    LOG_DBG("threshold = %d\n", iarg->a_threshold);
    threshold = iarg->a_threshold;    // 添加的处理代码

    // 3. 构造出参(没有则忽略)

    // 4. service回复
    return BONE_SUCCESS;
}

编译后运行,通过云端调用服务设置告警阈值。

image.png | center | 513x218

设备端接收日志:

image.png | center | 541x101

在云端查看事件日志,光照度阈值大于89时均上报了事件。

image.png | center | 636x395

至此,基于透传协议的示例已经完成,您可以继续在此平台上的开发之旅。

results matching ""

    No results matching ""