阿里云物联网平台使用教程(三)

教程(一)主要内容为平台介绍、如何注册开通平台账号以及创建产品和设备
教程(二)该平台如何添加自定义功能
教程(三)如何下载设备端代码和SDK以及代码解析、修改和编译运行

一、下载设备端代码和SDK

1.1 设备端代码的下载

我们再产品添加完功能之后,接着想着是能够去操作和使用这些功能,但是如果自己去编写控制是很麻烦的,阿里云物联网平台给我们提供了基本的代码,称之为设备端代码,我们只需要下载下来就可以去操作数据

点击指定产品的“功能定义”,然后点击“生成设备端代码”即可

2.2 SDK的选择和下载

产品和设备到此就已经添加完毕了,接下来就要跟代码打交道,需要在Ubuntu中运行程序操作数据通过阿里云传递到网页端,首先要下载的是SDK。

在设备中集成物联网平台提供的SDK,实现物联网平台接入。设备开发完成,接入物联网平台,设备激活,在物联网平台显示在线。

我们编程主要是使用C语言,所以我们要下载C相关的SDK,但是阿里云提供了不同版本的C SDK,所以我们要根据设备端代码选择合适的SDK,这里我们选择3.2.0版本的SDK。

首先点击物联网平台控制台的“概览”,然后再右上角选择“下载设备SDK”

也可以点击左侧“文档和工具”,选择“设备接入SDK”中“Link SDK”下方的“查看工具包”

然后在当前页面下翻找到“基于设备端SDK开发”,点击“C SDK”

然后点击左侧“3.x”下拉菜单中的“SDK获取”,右侧下翻找到“历史版本清单”,接着点击3.2.0版本右侧的“sdk下载”即可

最终下载好的设备端代码和SDK如图所示

二、代码解析、修改以及编译运行

接下来我们要做的就是在Ubuntu中添加SDK然后运行设备端代码,先将两个下载好的文件进行解压,解压之后的结果如图所示

SDK解压之后是一个文件夹,可以修改名称为memory_control,设备端代码解压完之后就是一个.c程序,暂时不管

接下来将SDK拷贝到Ubuntu中,并进入当前文件夹

在这里需要强调一下,阿里云的SDK对于Ubuntu和内部软件有版本的要求,请确保已安装以下软件,并且版本不低于指定的版本:Ubuntu 16.04 LTS、make-4.1、git-2.7.4、gcc-5.4.0、gcov-5.4.0、lcov-1.12、bash-4.3.48、tar-1.28、cmake3.51、awk4.1.3、sed 4.2.2

如果大家使用我们提供的Ubuntu,只需要安装一下gcov、lcov、cmake即可,其他符合要求,所以需要执行一下命令


接下来需要在SDK中执行make即可(如果是开发板运行的程序,需要打开makefile修改编译工具为交叉编译工具,Ubuntu中默认即可)

执行make进行编译需要一段时间,最终执行完毕如图所示

在当前目录中会多出一个目录文件,名为output,output就是接下来要操作的目录,进入output目录

进入examples目录,在目录中会有示例代码,通过output目录中的Makefile就可以直接编译,所以为了方便,我们可以把解压缩后的设备端代码修改成examples目录下任意文件的名字,这样就不需要修改Makefile,最终生成的可执行文件就是当前.c文件的名字

这里我们将设备端代码命名为mqtt_example.c,将当前目录的mqtt_example.c进行备份,然后将改名后的设备端代码拷贝到examples目录

此时我们已经将SDK和设备端代码都已经成功添加到Ubuntu中了,接下来需要修改设备端代码,将其能够链接到阿里云物联网平台下指定的产品的设备,打开设备端代码

首先要修改的是第21行到27行的代码,指定产品秘钥、设备名称和设备秘钥

产品秘钥需要在阿里云物联网平台控制台寻找,点击左侧“产品”,找到指定产品后点击右侧“查看”(注意每个产品和设备的秘钥都不同,添加自己创建的即可,并且作为公司产品不可外泄秘钥)

在弹出的对话框中可以看到ProductSecret和ProductKey,复制ProductSecret并粘贴到代码中

然后点击左侧“设备”,在指定设备相同的位置点击“查看”

将DeviceName和DeviceSecret复制到代码中


接下来我们可以编译代码并运行了,回到output目录,然后再当前目录下运行make prog,注意是执行make prog而不是make

编译成功之后的结果如图所示,会发现在当前目录下多个一个名为build的目录文件,这个文件保存的就是最终生成的可执行文件,我们最终设备端代码生成的可执行文件名为mqtt-example

接下来到了激动人心的时刻,运行可执行文件与阿里云建立链接,首先需要打开阿里云的代码调试页面,同样在控制台左侧,点击“监控运维”中的“在线调试”,然后再中间页面中“请选择设备”右侧指定产品和设备,此时发现没有任何数据,是因为还没有建立链接

接下来运行可执行文件mqtt-example,出现如图所示的结果说明链接成功了

接着查看阿里云控制台,发现右侧已经有数据了

我们现在可以在“调试功能”里面选择自己定义的功能,可以获取或者设置属性,例如功能选择“power_LED”,方法为“设置”,下方代码中设置为1,点击“发送指令”,就可以将数据发送正在运行的可执行文件

当然,现在大家还不知道设置的数据到底在哪接收,接下来我们的任务就是看懂设备端代码并且可以操作数据

首先是获取阿里云发送过来的数据,具体函数在380行左右,

函数名为user_property_set_event_handler,

这个函数将从阿里云接收到的数据保存在了第二个参数request里面,并且先输出了这个结果,我们可以自己在当前函数里面写一个打印信息

接着重新编译并通过阿里云发送数据,接收到的信息如下

接下来在当前函数中调用另一个函数app_parse_property对接收的数据进行解析,最终解析得到power_LED的值为1还是0,将值保存在powerled->valueint中

接下来我们给阿里云发数据,在发数据前,我们再控制台可以尝试接收数据,我接收内存空闲数据,最终发送指令得到的结果是0,说明是可以正常接收数据的,只不过没有设置而已

查看代码的主函数,会有一个while循环,循环里面有很多的函数调用,这些函数就是给阿里云发数据的函数,每一个函数的第二个参数就是发送阿里云控制台的具体值

比如我们设置app_post_property_cpu_usage的第二个参数为30,编译运行看一下控制台接收的数据

发现获取到的值就是30,这样我们就搞清楚如何与阿里云进通信了,接下来要做的就是把每一个数据都正确的获取到,需要在Ubuntu设备端代码中编写程序并在主函数调用即可

编写的代码如下:

声明并定义函数

void get_data()  
{  
    FILE *fp_disk, *fp_mem;  
  
    char cmd_disk[] = "df -l | grep /dev/sda";  
    char cmd_mem[] = "free -m | grep Mem";  
  
    fp_disk = popen(cmd_disk, "r");  
    if(fp_disk == NULL)  
    {  
        perror("fail to popen");  
        exit(1);  
    }  
  
    fp_mem = popen(cmd_mem, "r");  
    if(fp_mem == NULL)  
    {  
        perror("fail to popen");  
        exit(1);  
    }  
  
    char buf_disk[128] = "";  
    fgets(buf_disk, 128, fp_disk);  
    printf("buf_disk = %s\n", buf_disk);  
  
    char buf_mem[128] = "";  
    fgets(buf_mem, 128, fp_mem);  
    printf("buf_mem = %s\n", buf_mem);  
  
    sscanf(buf_disk, "%*s %ld %ld", &msg.DISK_total, &msg.DISK_used_space);  
    msg.DISK_used_percentage = (float)msg.DISK_used_space/(float)msg.DISK_total*100;  
  
    sscanf(buf_mem, "%*s %d %d", &msg.RAM_total, &msg.RAM_used);  
    msg.RAM_free = msg.RAM_total - msg.RAM_used;  
  
    printf("磁盘总量:%.0fG, 磁盘已用:%.2fG,磁盘使用率:%.2f%%\n", \  
        (float)msg.DISK_total/1024/1024, (float)msg.DISK_used_space/1024/1024,\  
        (float)msg.DISK_used_space/(float)msg.DISK_total*100);  
  
    printf("内存总量:%.0fM, 内存占用:%.2fM, 内存空闲:%.2fM\n", \  
        (float)msg.RAM_total, (float)msg.RAM_used, (float)msg.RAM_free);  
  
    //**************************cpu********************************  
    FILE *fp1, *fp2;  
  
    char cmd[] = "cat /proc/stat";  
  
    fp1 = popen(cmd, "r");  
    if(fp1 == NULL)  
    {  
        perror("fail to popen");  
        exit(1);  
    }  
  
    fp2 = popen(cmd, "r");  
    if(fp1 == NULL)  
    {  
        perror("fail to popen");  
        exit(1);  
    }  
  
    char buf1[128] = "";  
    char buf2[128] = "";  
  
    fgets(buf1, 128, fp1);  
    fgets(buf2, 128, fp2);  
      
    printf("%s\n", buf1);  
    printf("%s\n", buf2);  
      
    int data1[10];  
    int data2[10];  
    sscanf(buf1, "%*s %d %d %d %d %d %d %d %d %d %d", &data1[0], &data1[1], &data1[2], &data1[3], &data1[4],\  
            &data1[5], &data1[6], &data1[7], &data1[8], &data1[9]);  
    sscanf(buf2, "%*s %d %d %d %d %d %d %d %d %d %d", &data2[0], &data2[1], &data2[2], &data2[3], &data2[4],\  
            &data2[5], &data2[6], &data2[7], &data2[8], &data2[9]);  
  
    int sum1 = 0, sum2 = 0;  
    int totalCpuTime;  
    int i;  
    for(i = 0; i <= 9; i++)  
    {  
        sum1 += data1[i];  
    }  
  
    sleep(1);  
  
    for(i = 0; i <= 9; i++)  
    {  
        sum2 += data2[i];  
    }  
  
    totalCpuTime = sum2 - sum1;  
    printf("totalCpuTime = %d\n", totalCpuTime);  
  
    int sum3 = 0, sum4 = 0;  
    int idle;  
    for(i = 0; i <=3; i++)  
    {  
        sum3 += data1[i];  
    }  
  
    for(i = 0; i <=3; i++)  
    {  
        sum4 += data2[i];  
    }  
  
    idle = sum4 - sum3;  
    printf("idle = %d\n", idle);  
  
    msg.pcpu = 100 * (float)(totalCpuTime - idle) / (float)totalCpuTime;  
    printf("cpu使用率:%.2f%%\n", msg.pcpu);  
  
    fclose(fp_mem);  
    fclose(fp_disk);  
    fclose(fp1);  
    fclose(fp2);  
}  

将函数在主函数里面调用并给指定功能赋值传参

/** 
 * @brief main函数 
 */  
int main(int argc, char **argv)  
{  
    int res = 0;  
    int cnt = 0;  
    iotx_linkkit_dev_meta_info_t master_meta_info;  
    int dynamic_register = 0, post_reply_need = 0;  
    memset(&g_user_example_ctx, 0, sizeof(user_example_ctx_t));  
  
#ifdef ATM_ENABLED  
    if (IOT_ATM_Init() < 0) {  
        EXAMPLE_TRACE("IOT_ATM_Init failed!\n");  
        return -1;  
    }  
#endif  
  
    memset(&master_meta_info, 0, sizeof(iotx_linkkit_dev_meta_info_t));  
    memcpy(master_meta_info.product_key, g_product_key, strlen(g_product_key));  
    memcpy(master_meta_info.product_secret, g_product_secret, strlen(g_product_secret));  
    memcpy(master_meta_info.device_name, g_device_name, strlen(g_device_name));  
    memcpy(master_meta_info.device_secret, g_device_secret, strlen(g_device_secret));  
  
    IOT_SetLogLevel(IOT_LOG_DEBUG);  
  
    /* 注册回调函数 */  
    IOT_RegisterCallback(ITE_STATE_EVERYTHING, user_sdk_state_dump);  
    IOT_RegisterCallback(ITE_CONNECT_SUCC, user_connected_event_handler);  
    IOT_RegisterCallback(ITE_DISCONNECTED, user_disconnected_event_handler);  
    IOT_RegisterCallback(ITE_SERVICE_REQUEST, user_service_request_event_handler);  
    IOT_RegisterCallback(ITE_PROPERTY_SET, user_property_set_event_handler);  
    IOT_RegisterCallback(ITE_REPORT_REPLY, user_report_reply_event_handler);  
    IOT_RegisterCallback(ITE_TRIGGER_EVENT_REPLY, user_trigger_event_reply_event_handler);  
    IOT_RegisterCallback(ITE_TIMESTAMP_REPLY, user_timestamp_reply_event_handler);  
    IOT_RegisterCallback(ITE_INITIALIZE_COMPLETED, user_initialized);  
    IOT_RegisterCallback(ITE_FOTA, user_fota_event_handler);  
    IOT_RegisterCallback(ITE_CLOUD_ERROR, user_cloud_error_handler);  
    IOT_RegisterCallback(ITE_DYNREG_DEVICE_SECRET, dynreg_device_secret);  
  
    /* 选择上线方式(是否使用动态注册) */  
    dynamic_register = 0;  
    IOT_Ioctl(IOTX_IOCTL_SET_DYNAMIC_REGISTER, (void *)&dynamic_register);  
  
    /* 是否需用属性、事件上报(设置)应答 */  
    post_reply_need = 1;  
    IOT_Ioctl(IOTX_IOCTL_RECV_EVENT_REPLY, (void *)&post_reply_need);  
  
    do {  
        g_user_example_ctx.master_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_MASTER, &master_meta_info);  
        if (g_user_example_ctx.master_devid >= 0) {  
            break;  
        }  
        EXAMPLE_TRACE("IOT_Linkkit_Open failed! retry after %d ms\n", 2000);  
        HAL_SleepMs(2000);  
    } while (1);  
  
    do {  
        res = IOT_Linkkit_Connect(g_user_example_ctx.master_devid);  
        if (res >= 0) {  
            break;  
        }  
        EXAMPLE_TRACE("IOT_Linkkit_Connect failed! retry after %d ms\n", 5000);  
        HAL_SleepMs(5000);  
    } while (1);  
  
    while (1) {  
        IOT_Linkkit_Yield(EXAMPLE_YIELD_TIMEOUT_MS);  
  
        /* Post Proprety Example */  
        if ((cnt % 20) == 0) {  
            get_data();  
            app_post_property_PowerLed(EXAMPLE_MASTER_DEVID, 1);  
            app_post_property_DISK_used_percentage(EXAMPLE_MASTER_DEVID, msg.DISK_used_percentage);  
            app_post_property_DISK_used_space(EXAMPLE_MASTER_DEVID, (float)msg.DISK_used_space/1024/1024);  
            app_post_property_DISK_total(EXAMPLE_MASTER_DEVID, (float)msg.DISK_total/1024/1024);  
            app_post_property_RAM_free(EXAMPLE_MASTER_DEVID, (float)msg.RAM_free);  
            app_post_property_RAM_used(EXAMPLE_MASTER_DEVID, (float)msg.RAM_used);  
            app_post_property_RAM_total(EXAMPLE_MASTER_DEVID, (float)msg.RAM_total);  
            app_post_property_cpu_usage(EXAMPLE_MASTER_DEVID, msg.pcpu);  
            app_post_property_cpu_temperature(EXAMPLE_MASTER_DEVID, 30);  
        }  
  
        cnt++;  
  
        HAL_SleepMs(200);  
    }  
  
    IOT_Linkkit_Close(g_user_example_ctx.master_devid);  
    IOT_SetLogLevel(IOT_LOG_NONE);  
  
    return 0;  
}  

注意:由于是在虚拟机运行Ubuntu,所以无法获取cpu温度,所以在这里将温度固定设置为30

接下来编译代码并运行,通过阿里云控制台接收数据

除了可以在这里查看以外,还可以实时查看设备数据,在指定设备中点击“物模型数据”,下方就可以实时查看数据的变化


备注:

于作者水平,难免有理解和描述上有疏漏或者错误的地方,欢迎共同交流;部分参考已经在正文和参考文献中列表注明,但仍有可能有疏漏的地方,有任何侵权或者不明确的地方,欢迎指出,必定及时更正或者删除;文章供于学习交流,转载注明出处。

深圳SEO优化公司遵义百度爱采购多少钱梅州高端网站设计价格三明高端网站设计多少钱喀什网站排名优化公司邵阳百度竞价包年推广多少钱盘锦优秀网站设计推荐丹东百度标王推荐固原至尊标王营口优秀网站设计广东百度标王报价晋中营销网站推荐抚州网络营销多少钱亳州seo优化哪家好郑州网站推广方案报价丽江企业网站建设推荐莱芜网站推广价格乌海建站推荐桂林网站关键词优化推荐濮阳推广网站唐山网页制作公司和田网站设计霍邱关键词按天计费多少钱莆田建站公司广元网络广告推广哪家好张北关键词按天收费多少钱漯河阿里店铺运营公司甘南网站建设设计公司双龙设计网站价格包头seo优化多少钱芜湖网站优化推广多少钱歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化