一、概述
此文档主要用于说明智能家居设备接入物联云平台的操作流程和方法。列举具体的网关产品及其下的家居网关设备,和相关的子设备产品及其下的灯开关设备为例子,具体说明网关设备和子设备的配置以及具体的技术实现,以帮助指导第三方系统开发人员独立完成子设备接入网关的配置和开发工作。
二、名词解释:
- 网关程序(XCG):预装在智能家居网关里的应用程序,会将智能家居网关以一个网关设备的身份接入到IoT平台,并提供子设备对接能力;
- PTP:指网关子设备接入物联云平台的协议转换程序;
- PID:ProductID的缩写,每个产品的唯一ID;
- 物模型:指物联云平台通过将事物抽象出来的一个描述事物的数据模型,表现为属性、事件、服务三种形态;
- 管理台:物联云平台提供给平台租户使用的物联管理云平台,其中涵盖了产品创建、设备接入、设备调试、OTA等管理功能;
三、流程说明
四、操作步骤
前提条件:
拥有管理台网址;
在管理台该企业下拥有相应的账号密码;
登录的账号拥有【设备中心】/【开发平台】模块权限;
XCG程序和X-SEP程序(需要提供交叉编译工具链给物联云平台编译);
3.1创建网关产品
1、在浏览器输入管理台网址,使用账号密码进行登录,进入管理台;
2、在【设备中心】模块的下拉菜单中,点击【产品管理】功能,进入产品列表,通过创建产品功能进行创建;
(1)选择网关产品所属产品类目,需选择智能家居–>网关产品类目;
(2)填写产品信息。(注意:其中节点类型须选择网关类型,协议版本号须选择V6.0),填写完成后即可完成产品创建;
编号 | 说明 |
---|---|
① | 产品名称,根据业务填写,这里示例命名为网关 |
② | 此处创建网关产品,节点类型对应选择网关类型 |
③ | 目前网关类型产品只支持V6.0协议 |
3.2创建子设备产品
1、在【设备中心】模块的下拉菜单中,点击<创建产品>功能,进入创建产品流程;
(1)选择子设备产品所属产品类目,本文示例为灯开关子设备产品,选择了在智慧家居分类下选择电工照明-单键开关、插座的产品类目;
(2)填写子设备产品信息(其中节点类型须选择子设备类型,协议版本号与网关产品保持一致),填写完成后按照指引,点击下一步完成产品的创建。
编号 | 说明 |
---|---|
① | 产品名称,根据业务填写,这里示例命名为开关 |
② | 此处创建的产品为子设备产品,节点类型相应选择子设备 |
③ | 连网方式根据子设备产品实际接入网络情况选择,此处示例开关产品连网方式为Zigbee设备 |
④ | 子设备产品协议版本号与其关联的网关产品的协议版本号保持一致,此处示例网关产品接入协议为V6.0,故子设备产品协议版本号也为V6.0 |
3.3产品设置
将上述创建的网关产品和子设备产品进行产品设置,这里以网关产品为例
1、在【设备中心】模块的下拉菜单中,通过<最近浏览>功能,找到上述刚创建的网关产品,也可通过【产品管理】菜单,进入产品列表,通过搜索产品名称,找到创建的产品,点击进入产品详情页面;
2、进入产品详情页面中,在详情信息中找到网关产品和子设备产品的产品ID和产品密钥,找到之后需要记录,在设备接入开发配置过程中会使用到这两个参数(若详情信息中没有产品ID,则需要通过右上角的<排序配置>按钮将产品ID展示出来);
编号 | 说明 |
---|---|
① | 在产品详情中找到产品ID信息; |
② | 在产品详情中产品名称下点击<产品密钥>功能,展示该产品的产品密钥; |
3、点击产品详情页左下角<产品设置>→<功能设置>功能,勾选【设备管理】和【设备授权】中的选项,使产品下的设备能够允许设备多个管理员、允许用户授权设备、允许设备自行授权,并且在订阅设备中选择<允许多用户订阅设备>选项;
编号 | 说明 |
---|---|
① | 在产品详情下左下角,悬浮<产品设置>,展示产品设置菜单; |
② | 点击<功能设置>,进入功能设置配置页面; |
③ | 勾选【设备管理】、【设备授权】中的选项,包括<允许设备多个管理员>、<允许用户授权设备>、<允许设备自行授权> |
④ | 选择【订阅设备】中的<允许多用户订阅设备> |
3.4创建网关授权证书
1、在【设备中心】模块的下拉菜单中,点击<证书管理>功能,进入网关授权管理列表;
2、点击网关授权列表上方的<添加证书>,填写证书名称并选择证书关联的产品。
注意:这里证书创建必须由系统管理员来创建,以更好地规范和管理证书。
3、此处的证书是给网关产品及其子设备产品使用,所以证书关联的产品应包括网关产品及其所有子设备产品,如果后续该网关下有新增的子设备产品,也需要关联至网关同一证书下;
4、证书创建之后,证书相应的证书ID和证书密钥也相应生成,在网关授权证书列表可查询到,记录证书ID和证书密钥(即Cid和Ckey),在设备接入开发配置过程中将会使用;
5、同时刚创建的证书是启用的状态,在网关产品及其子设备产品在使用该证书过程中,证书须保持启用状态;
3.5设备接入开发配置
3.5.1启动XCG
配置网关参数
- XCG的参数可以在配置文件settings.ini中进行配置,并且配置文件settings.ini中的配置值优先级高于程序中的参数常量值。配置文件settings.ini中的配置项说明如下:
配置项名称 | 配置项所属段 | 默认值 | 是否必须 | 说明 |
---|---|---|---|---|
EmbedPTPServer | Application | true | 否 | 是否启动内部的PTP Broker |
PTPServerPort | Application | 23883 | 否 | 设置内部的PTP Broker端口 |
LogPath | Application | “” | 否 | 设置日志文件输出目录,目录结尾要带斜杠。默认是””,当前目录下 |
RunMode | Application | 0 | 否 | 网关程序运行模式:0-单网关或主网关;1-子网关;2-单网关内网模式 |
SlaverAllow | Application | 0 | 否 | 主网关模式时标记是否允许挂载子网关:0-不允许 1-允许。注意:多网关主从模式组网同一个网络只允许一个主网关挂载子网关 |
IsOfficial | Application | false | 否 | 是否连接正式平台:true-连接正式平台;false-连接测试平台 |
UnPairDirectDel | Application | 0 | 否 | 设置子设备取消配时处理模式:0-只取消配对,不删除子设备数据;1-取消配对,删除子设备所有数据,并通知PTP删除对应子设备;其他:不取消配对,只通知PTP删除对应子设备(PTP通知设备离开时再取消配对) |
DetectedMode | Application | 5 | 否 | 设备发现版本:5-V5;6-V6 |
LogFileSize | Application | 1048576 | 否 | 日志文件大小,默认1M |
LogFileCount | Application | 2 | 否 | 日志文件数量,默认2,最大5 |
LogLevel | Application | 100 | 否 | 日志级别,级别定义:0-ERROR、1-WARNING、2-INFO、3-DEBUG、100-VERBOS |
APIHost | Application | “” | 否 | API地址,例如:http://api2.xlink.cn |
CMHost | Application | “” | 否 | CM地址,例如:mqtt.xlink.cn |
CMSSL | Application | false | 否 | CM是否使用ssl连接 |
CMPort | Application | 1883 | 否 | CM连接端口 |
PairingOnOff | Application | 1 | 否 | 设备配对开关:1-打开;0-关闭 |
FirmwareVer | Application | 3 | 否 | 网关固件版本号 |
NoDevHMode | Application | 0 | 否 | 在子设备激活或上线时发现云端设备不存在处理策略:0-删除该子设备;1-重新激活该子设备 |
SNuseMAC | Application | 0 | 否 | 序列号使用MAC设置:0-不设置;1-设置(网关和子设备都设置);2-只是网关设置 |
UseInner | Application | 1 | 否 | 是否使用内网功能:0-不使用;1-使用 |
SubStateInit | Application | 0 | 否 | 子设备初始状态设置:0-按保存的最后设备状态进行设置;1-设置为默认状态(0),该状态下设备不上线 |
DBPath | Application | “” | 否 | 设置DB文件输出目录,目录结尾不带斜杠。默认是””,当前目录下。 |
IfrName | User | “eth0” | 否 | 设置指定获取的网卡名称Interface name |
DeviceSN | User | “” | 否 | 网关序列号SN,可让用户自己配置网关SN,该配置项优先级最高。 |
GatewayMac | User | “” | 否 | 网关mac,可让用户自己配置网关MAC,该配置项优先级最高 |
ProductID | User | “” | 是 | 网关的产品ID,可从云平台上配置获取 |
ProductKey | User | “” | 是 | 网关的产品Key,可从云平台上配置获取 |
CertificationID | User | “” | 是 | 网关的证书ID,可从云平台上配置获取 |
CertificationKey | User | “” | 是 | 网关的证书Key,可从云平台上配置获取 |
CategoryId | Category | “” | 否 | 网关默认分组设置,配置格式请参看附录 |
TriggerId | Trigger | “” | 否 | 网关默认触发器设置,配置格式请参看附录 |
- 配置文件主要修改网关设备的pid、pkey,以及cid、ckey,其他配置项如无需要保持默认
[User]
ProductID=1603bcc0b7e503e91603bcc0b7e5b601
ProductKey=212d0f19ce1700bcaaf8ee9175d54364
CertificationID=6066daf4d8af2f7fbc41f28f
CertificationKey=210a194f-3d47-4304-94d1-166f3f0894f6
启动
- 打开目录下的XCG程序xlink-gw-core-cpp。如果成功连接云端,点击管理台(设备中心-网关)可以看到这台网关设备的信息。
3.5.2 创建PTP程序
- PTP所涉及到的通信协议可以参考文档《Xlink IoT Gateway X-PTP协议 V2.0.2.pdf》。以下段落以c语言的PTP demo为例,模拟一个虚拟的开关设备,说明如何创建一个PTP程序。示例程序通过ubuntu18.04.1编译运行。
3.5.3 连接XCG MQTT
- C语言连接MQTT,需要相关的库支持,这里选择pahomqtt。
连接参数如下:
参数名称 | 参考值 | 说明 |
---|---|---|
ip | 127.0.0.1 | 需要连接的网关ip,ptp和xcg一般放在同一设备下 |
port | 23883 | 连接xcg端口,可以在xcg配置文件里的PTPServerPort字段修改 |
clientID | mqtt客户id,可以随即生成 | |
keepAliveInterval | 60 | mqtt保持连接时间 |
username | 保持空 | |
password | 保持空 |
#define MQTT_BROKER_ADDRESS "tcp://localhost:23883" // local broker ip
char g_ptp_id[MAC_MAX]={""};
char g_ptp_cliet_id[MAC_MAX]={""};
char g_ptpo_cliet_id[MAC_MAX]={""};
int main(int argc, char **argv)
{
sprintf(g_ptp_id,"%s",getrandommac());
fprintf(stderr, "mqtt init..../n");
sprintf(g_ptp_cliet_id,"%s_samplePTP",g_ptp_id);
mqttClientInit_cg(MQTT_BROKER_ADDRESS,g_ptp_cliet_id);
sprintf(g_ptpo_cliet_id,"%s_samplePTPO",g_ptp_id);
mqttClientInit_cgo(MQTT_BROKER_ADDRESS,g_ptpo_cliet_id);
fprintf(stderr, "mqtt init....end/n");
}
3.5.4 子设备上线
int send_devices()
{
char topic_devices[100]={""};
sprintf(topic_devices,"$xlink/ptp/%s/devices",g_ptp_id);
char ptp_payload[200]="{/"devices/":[{/"mac/":/"12348765/",/"product_id/": /"1603bec0b80003e91603bec0b8006a01/",/"state/":1,/"push/":false}]}";
int len = strlen(ptp_payload);
fprintf(stderr,"PTP->XCG devices:playload:[%s],len:[%d]",ptp_payload,len);
mqttPublishTopic_cgo(topic_devices,ptp_payload);
return OK;
}
void ptp_devices_public_TopicHandler(const char *topicPayload)
{
printf("XCG->PTP devices_public: %s/n", topicPayload);
send_devices();
}
- 这里的PTP程序模拟了一个虚拟的开关设备。当PTP收到devices_public消息时,将开关设备返回。
主题
- $xlink/ptp/{ptp_id}/devices_public
- $xlink/ptp/{ptp_id}/devices
payload
- mac:虚拟一个开关设备的mac
- product_id:开关设备的PID,在产品创建章节有记录
- state:设备状态,这里1代表在线
- push:不推送
3.5.5 上报子设备数据
int send_device_sync()
{
char topic_sync[100]={""};
sprintf(topic_sync,"$xlink/ptp/%s/device/sync",g_ptp_id);
char ptp_payload[300]="{/"devices/":[{/"mac/":/"12348765/",/"product_id/": /"1603bec0b80003e91603bec0b8006a01/",/"state/":1,/"push/":false,/"datapoints/":[{/"index/":0,/"value/":1},{/"index/":1,/"value/":30},{/"index/":2,/"value/":50},{/"index/":3,/"value/":80}]}]}";
int len = strlen(ptp_payload);
fprintf(stderr,"PTP->XCG device sync:playload:[%s],len:[%d]",ptp_payload,len);
mqttPublishTopic_cgo(topic_sync,ptp_payload);
return OK;
}
void ptpo_gwevent_TopicHandler(const char *topicPayload)
{
printf("XCG->PTPO ptpo_gwevent: %s/n", topicPayload);
int gwcode=-1;
char szparam1[PARAM_MAX] = {0};
cJSON* cjson = cJSON_Parse(topicPayload);
if(cjson == NULL){
printf("json parse error...");
return;
}
cJSON *item= cJSON_GetObjectItem(cjson,"gwcode");
if(item != NULL)
{
gwcode=item->valueint;
printf("gwcode_str:%d",gwcode);
}
item= cJSON_GetObjectItem(cjson,"param1");
if(item != NULL)
{
strncpy(szparam1,item->valuestring,PARAM_MAX);
printf("param1_str:%s",szparam1);
if(gwcode==1){
//
send_device_sync();
}
if(gwcode == 5)
{
//调整本地时间(szparam1);
}
else if(gwcode == 6)
{
//ptp is remove by xcg
gw_send_keepalive_now = 1;
}
else if(gwcode == 7)
{
//ptpo is remove by xcg
gw_send_keepalive_now = 1;
}
}
cJSON_Delete(cjson);
}
主题
- $xlink/ptpo/{ptp_id}/gwevent
- $xlink/ptp/{ptp_id}/device/sync
payload
- index0:表示物模型里的电源开关,这里设为1,表示打开。
- index1:表示物模型里的剩余电量,这里设为30。
- index2:表示物模型里的信号强度,这里设为50。
- index3:表示物模型里的电量状态,这里设为80。
3.5.6 接收子设备数据
int send_ptpo_optresult(char* msgid,char* devicemac,char* devicepid,int code,char* desc)
{
char topic_optresult[100]={""};
sprintf(topic_optresult,"$xlink/ptpo/%s/optresult",g_ptp_id);
char ptp_payload[200]={""};
sprintf(ptp_payload,XLINK_PTPO_OPTRESULT_PAYLOAD,msgid,devicemac,devicepid,code,desc);
int len = strlen(ptp_payload);
fprintf(stderr,"PTPO->XCG optresult:playload:[%s],len:[%d]",ptp_payload,len);
mqttPublishTopic_cgo(topic_optresult,ptp_payload);
return OK;
}
void ptp_device_set_TopicHandler(const char *topicPayload)
{
printf("XCG->PTP set: %s/n", topicPayload);
int msgid;
char szmac[MAC_MAX] = {0};
char szpid[PRODUCT_MAX] = {0};
cJSON* cjson = cJSON_Parse(topicPayload);
if(cjson == NULL){
printf("json parse error...");
return;
}
cJSON *item= cJSON_GetObjectItem(cjson,"msg_id");
if(item != NULL)
{
msgid=item->valueint;
}
item= cJSON_GetObjectItem(cjson,"mac");
if(item != NULL)
{
strncpy(szmac,item->valuestring,MAC_MAX);
}
item= cJSON_GetObjectItem(cjson,"product_id");
if(item != NULL)
{
strncpy(szpid,item->valuestring,MAC_MAX);
}
send_ptpo_optresult(msgid,szmac,szpid,1,"suc");
}
当在后台或app改变开关设备物模型的值时,ptp会收到device/set消息。这里将收到的数据打印,并返回一个应答。
主题
- $xlink/ptpo/{ptp_id}/optresult
- $xlink/ptp/{ptp_id}/device/set
3.5.7 启动PTP
1、程序编写完成后,启动PTP程序,如果成功连接上ptp,则可以在管理台查看这台虚拟开关设备信息
2、点击MAC地址,可进入设备详情页,查看设备的详情信息
3、返回网关产品下的网关设备详情中,切换<网关子设备>,可以看到开关产品下的设备
3.6.设备调试
3.6.1网关设备调试
1、在设备接入开发配置之后,第三方系统开发人员可【设备中心/开发平台】模块的产品列表找到网关产品并进入其详情页,找到【设备调试】功能,来调试网关产品的设备和子设备产品的设备,设备调试页面会根据网关产品的设备接入协议版本展示相应的调试页面。这里以家居网关和灯开关设备做示例。
3.6.2子设备调试
1、第三方系统开发人员可通过网关产品的设备调试页面,点击<子设备调试>进入子设备产品的设备调试页面进行调试。这里以家居网关和灯开关为示例;
2、进入子设备调试页面后,设备调试页面会根据子设备产品的设备接入协议版本展示相应的调试页面。
注意:
- 若灯开关设备还未关联至家居网关设备下,通过<开启配网模式>,配置相应的入网参数,使云端向家居网关设备下发topic指令,使家居网关设备进入配网状态;
- 同时灯开关设备也需要打开配网模式,使其发现并连入家居网关设备,通过家居网关设备顺利上云;
3.6.3调试日志
1、若调试过程中发生不一致情况,可通过设备日志查看错误日志,结合日志帮助第三方系统开发者定位问题;
3.6.4调试建议
第三方系统开发者可从以下几个方面去调试:
- 可检查设备的属性值是否与设备实时的值一致;
- 可调整设备实时值,并刷新属性列表,检查属性值是否正确变化;
- 可编辑属性值,点击<确定>将属性值下发至设备端,检查设备实际值是否与下发的属性值保持一致;
五、XCG & PTP Demo 程序下载
资源名称 | 下载地址 |
---|---|
XCG程序(Ubuntu) | 点此下载 |
PTP Demo | 点此下载 |