属性、服务、事件
设备可以使用物模型功能,实现属性上报(如上报设备状态)、事件上报(上报设备异常或错误)和服务调用(通过云端调用设备提供的服务)。
概念 | 解释 |
---|---|
属性 | 示设备支持的某个可读、或者可读可写的参数,例如灯的亮度。 |
服务 | 表示一个设备支持的功能,例如让一个设备重启。 |
事件 | 是设备主动上报的某种情况发生的信息,例如有人在撬锁时智能锁可以上报一个暴力撬锁的事件到云端进行报警。 |
实现说明
所有上行消息(即:从设备端到物联网平台)的传递, 都以接口调用的方式提供,SDK在接口中将消息封装后,统一发送到云平台。
所有下行消息(即:从物联网平台到设备端)的传递, 都以用户注册回调的方式实现,SDK收到云平台下发的消息后,通过回调函数通知到用户侧。
注:如果存在子设备的话,子设备的消息由网关统一进行收发。
API列表
以下是API列表及简要说明 (详见iot_demo\include\iot_subdevice.h
和iot_demo\include\iot_client.h
)。
接口名 | 说明 |
---|---|
IotClient_UploadEvents | 上报事件 |
IotClient_SubDeviceUploadEvents | 子设备上报事件 |
IotClient_UploadProperties | 上报属性 |
IotClient_SubDeviceUploadProperties | 子设备上报属性 |
cbGetProperties | 获取属性回调 |
cbSetProperties | 设置属性回调 |
cbCallServices | 调用服务回调 |
cbUploadResponses | 上报属性和事件回调 |
例程讲解及集成示例
注册回调
请参考"C-SDK-认证与连接.md"。
设备属性上报
// 将要上报的属性构造为Json格式
cJSON *params = cJSON_CreateObject();
cJSON_AddNumberToObject(params, "WorkMode", 1);
// 申请一个字符数组用于保存此次会话ID
char *mid = malloc(UUID_LEN);
memset(mid, 0, UUID_LEN);
// 调用接口进行属性上报
int ret = IotClient_UploadProperties(params, &mid);
IotLogInfo("upload properties mid:%s", mid);
if (ret != 0) {
IotLogInfo("post value error:%d", ret);
}
free(mid);
设备事件上报
// 将要上报的属性构造为Json格式
cJSON *params = cJSON_CreateObject();
cJSON_AddNumberToObject(params, "WorkMode", 1);
// 申请一个字符数组用于保存此次会话ID
char *mid = malloc(UUID_LEN);
memset(mid, 0, UUID_LEN);
// 调用接口进行事件上报
int ret = IotClient_UploadEvents(params, "system.msg.transform.upload", &mid);
IotLogInfo("upload events mid:%s", mid);
if (ret != 0) {
IotLogInfo("post value error:%d", ret);
}
free(mid);
设备属性获取
int cbGetProperties(cJSON *inParams, cJSON *outParams) {
// 判断是否为子设备
if (cJSON_HasObjectItem(inParams, "subDevices")) {
cJSON *sub_device = cJSON_GetObjectItem(inParams, "subDevices");
if (cJSON_IsTrue(sub_device)) {
// 用户侧在此自行实现子设备的标识处理
}
}
cJSON *params = inParams->child;
if (!params) {
return -1;
}
// 依次获取每个属性类型(可能有多个,存储在Json Array中)
while (params) {
char *key = params->valuestring;
if (!key) {
break;
}
if (!strcmp("PowerSwitch", key)) {
// 模拟获取当前属性值,此处由用户侧自行实现
cJSON_AddBoolToObject(outParams, key, true);
} else if (!strcmp("WorkMode", key)) {
// 模拟获取当前属性值,此处由用户侧自行实现
cJSON_AddNumberToObject(outParams, key, 1);
}
params = params->next;
}
return 0;
}
设备属性设置
int cbSetProperties(cJSON *inParams, char **msg) {
// 判断是否为子设备
if (cJSON_HasObjectItem(inParams, "subDevices")) {
cJSON *sub_device = cJSON_GetObjectItem(inParams, "subDevices");
if (cJSON_IsTrue(sub_device)) {
inParams = cJSON_GetObjectItem(inParams, "params");
// 此处由用户自行实现子设备的标识处理
goto Finish;
}
}
cJSON *params = inParams->child;
if (params == NULL) {
return -1;
}
// 依次获取每个属性类型(可能有多个,存储在Json Object中)
char *key = params->string;
if (!strcmp("PowerSwitch", key)) {
if (cJSON_False != params->type && cJSON_True != params->type) {
return -1;
}
// 模拟设置当前属性值,此处由用户侧自行实现
IotLogInfo("setProperties PowerSwitch:%d", params->valueint);
} else if (!strcmp("WorkMode", key)) {
if (cJSON_Number != params->type) {
return -1;
}
// 模拟设置当前属性值,此处由用户侧自行实现
IotLogInfo("setProperties WorkMode:%d", params->valueint);
}
// 写入设置结果
*msg = "set properties ok";
return 0;
}
设备自定义服务
int cbCallServices(cJSON *inParams, cJSON *outParams, char **msg) {
// 判断是否为子设备
if (cJSON_HasObjectItem(inParams, "subDevices")) {
cJSON *sub_device = cJSON_GetObjectItem(inParams, "subDevices");
if (cJSON_IsTrue(sub_device)) {
IotLogInfo("Invoke subdevice service!");
// 此处由用户自行实现子设备的标识处理
}
}
char *identifier = inParams->child->valuestring;
if (!identifier) {
return -1;
}
// 依次获取每个服务类型
if (!strcmp("AdjustTemperature", identifier)) {
cJSON *paramsJson = cJSON_GetObjectItem(inParams, "params");
if (!paramsJson) {
return -1;
}
cJSON *tmpJson = paramsJson->child;
// 模拟设置当前服务,此处由用户侧自行实现
while (tmpJson) {
char *key = tmpJson->string;
if (!key) {
break;
}
IotLogInfo("key1=%s", key);
if (!strcmp("Up", key)) {
if (tmpJson->type == cJSON_Number) {
IotLogInfo("Up=%d", tmpJson->valueint);
}
} else if (!strcmp("Down", key)) {
if (tmpJson->type == cJSON_Number) {
IotLogInfo("Down=%d", tmpJson->valueint);
}
}
tmpJson = tmpJson->next;
}
} else if (!strcmp("AdjustFanSpeed", identifier)) {
cJSON *paramsJson = cJSON_GetObjectItem(inParams, "params");
if (!paramsJson) {
return -1;
}
cJSON *tmpJson = paramsJson->child;
// 模拟设置当前服务,此处由用户侧自行实现
while (tmpJson) {
char *key = tmpJson->string;
if (!key) {
break;
}
IotLogInfo("key1=%s", key);
if (!strcmp("Up", key)) {
if (tmpJson->type == cJSON_Number) {
IotLogInfo("Up=%d", tmpJson->valueint);
}
} else if (!strcmp("Down", key)) {
if (tmpJson->type == cJSON_Number) {
IotLogInfo("Down=%d", tmpJson->valueint);
}
}
tmpJson = tmpJson->next;
}
}
if (outParams) {
cJSON_AddBoolToObject(outParams, "status", 1);
}
// 写入设置结果
*msg = "call service ok";
return 0;
}