Este capítulo descreve como enviar e receber mensagens por meio de tópicos MQTT e como implementar um dispositivo usando o método de programação Device-Modelling no Ubuntu.
Instale o ambiente de desenvolvimento local
Instale o Ubuntu 16.04
O ambiente de compilação para esta experiência rápida é Ubuntu16.04 em um host 64-bit. Este ambiente não foi verificado em outras versões do Linux. Recomendamos que você instale a versão de lançamento compatível com a Alibaba Cloud para evitar problemas de compatibilidade.
Se estiver usando o sistema operacional Windows, recomendamos instalar o VMWare Virtualbox.
Em seguida, instale a versão Desktop de 64 bits do Ubuntu 16.04.x LTS. Link para baixe: http://releases.ubuntu.com/16.04
Instale os softwares pré-requisitos
O ambiente de desenvolvimento e compilação deste SDK utiliza os seguintes softwares: 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, mingw-5.3.1
Use o comando a seguir para instale os softwares necessários:
$ sudo apt-get install -y build-essential make git gcc
Desenvolva por meio do Hacklab Web IDE
Caso não pretenda instale o Ubuntu em seu PC ou notebook, você também pode desenvolver para os dispositivos diretamente pelo ambiente Hacklab Web IDE fornecido pela Alibaba Cloud IoT Platform. O Hacklab Web IDE é um ambiente de desenvolvimento Linux na nuvem que já possui todos os softwares necessários instalados. Se você tiver uma conta Alibaba Cloud, faça login no Hacklab Web IDE e inicie o desenvolvimento pelo navegador.
Acesse o dispositivo usando tópicos MQTT
Crie produtos e dispositivos
Use sua conta Alibaba Cloud para fazer login na Alibaba Cloud IoT Platform e crie produtos. Como você implementará as funções do produto diretamente por meio de tópicos MQTT, certifique-se de selecione “Basic version” ao criar o produto.
Após crie um produto, crie um dispositivo específico. A Alibaba Cloud IoT Platform gerará informações de identidade para o dispositivo.
Se não estiver familiarizado com a criação de produtos na nuvem, aprenda como crie produtos e dispositivos na Alibaba Cloud IoT Platform.
Implemente as funções do produto
Entenda a estrutura do diretório raiz do SDK
Após baixe o Link Kit SDK, a estrutura do diretório de nível superior será a seguinte:
$ ls
build-rules Config.in examples LICENSE make.settings project.mk sdk-c.mk win_board_conf.mk CMakeLists.txt Config.linkkit include makefile prebuilt README.txt src win.makefile
Modifique a identificação do dispositivo
Obtenha o ProductKey e o Product Secret de um produto clique em nos botões 'copy' indicados na imagem abaixo:
Obtenha o DeviceName e o DeviceSecret de um dispositivo clique em nos botões 'copy' indicados na imagem abaixo:
Abra o arquivo ./examples/mqtt/mqtt-example.c e edite o trecho de código a seguir para substituir os valores de PRODUCT_KEY/PRODUCT_SECRET/DEVICE_NAME/DEVICE_SECRET:
#include "iot_import.h"
#include "iot_export.h"
#include "app_entry.h"
#define PRODUCT_KEY "a1MZxOdcBnO"
#define PRODUCT_SECRET "h4I4dneEFp7EImTv"
#define DEVICE_NAME "test_01"
#define DEVICE_SECRET "t9GmMf2jb3LgWfXBaZD2r3aJrfVWBv56"
Inicialize o dispositivo e estabeleça uma conexão
O trecho de código a seguir descreve brevemente o processo de inicialização e estabelecimento de conexão do dispositivo:
int mqtt_client(void)
{
...
...
/* Enter the device identity information before attempting to establish an MQTT connection to the server*/
if (0 ! = IOT_SetupConnInfo(__product_key, __device_name, __device_secret, (void **)&pconn_info)) {
EXAMPLE_TRACE("AUTH request failed!") ;
rc = -1;
goto do_exit;
}
/* Initialize MQTT parameter */
...
...
Tente estabelecer uma conexão MQTT com o servidor
pclient = IOT_MQTT_Construct(&mqtt_params);
if (NULL == pclient) {
EXAMPLE_TRACE("MQTT construct failed");
rc = -1;
goto do_exit;
}
Relate dados para a nuvem
Os seguintes tópicos estão definidos no arquivo de exemplo:
#define TOPIC_UPDATE "/"PRODUCT_KEY"/"DEVICE_NAME"/update"
#define TOPIC_ERROR "/"PRODUCT_KEY"/"DEVICE_NAME"/update/error"
#define TOPIC_GET "/"PRODUCT_KEY"/"DEVICE_NAME"/get"
#define TOPIC_DATA "/"PRODUCT_KEY"/"DEVICE_NAME"/data"
/* topic format definitions*/
#define TOPIC_UPDATE_FMT "/%s/%s/update"
#define TOPIC_ERROR_FMT "/%s/%s/update/error"
#define TOPIC_GET_FMT "/%s/%s/get"
#define TOPIC_DATA_FMT "/%s/%s/data"
A Alibaba Cloud IoT Platform gera, por padrão, os 3 tópicos a seguir para um produto “Basic Edition”:
Os trechos de código a seguir mostram como enviar dados para o tópico ‘UPDATE’:
/* Initialize topic information */
memset(&topic_msg, 0x0, sizeof(iotx_mqtt_topic_info_t));
strcpy(msg_pub, "update: hello! start!") ;
topic_msg.qos = IOTX_MQTT_QOS1;
topic_msg.retain = 0;
topic_msg.dup = 0;
topic_msg.payload = (void *)msg_pub;
topic_msg.payload_len = strlen(msg_pub);
rc = IOT_MQTT_Publish(pclient, TOPIC_UPDATE, &topic_msg);
if (rc < 0) {
IOT_MQTT_Destroy(&pclient);
EXAMPLE_TRACE("error occur when publish");
rc = -1;
goto do_exit;
}
EXAMPLE_TRACE("\n publish message: \n topic: %s\n payload: \%s\n rc = %d", TOPIC_UPDATE, topic_msg.payload, rc);
Inscreva-se e processe dados da nuvem
O programa de exemplo se inscreve no tópico TOPIC_DATA e especifica o manipulador ao receber dados do tópico:
rc = IOT_MQTT_Subscribe(pclient, TOPIC_DATA, IOTX_MQTT_QOS1, _demo_message_arrive, NULL);
if (rc < 0) {
IOT_MQTT_Destroy(&pclient);
EXAMPLE_TRACE("IOT_MQTT_Subscribe() failed, rc = %d", rc);
rc = -1;
goto do_exit;
}
IOT_MQTT_Yield(pclient, 200);
HAL_SleepMs(2000);
...
...
Na função _demo_message_arrive(), os dados são simplesmente impressos:
static void _demo_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
{
iotx_mqtt_topic_info_pt ptopic_info = (iotx_mqtt_topic_info_pt) msg->msg;
/* print topic name and topic message */
EXAMPLE_TRACE("----");
EXAMPLE_TRACE("packetId: %d", ptopic_info->packet_id);
EXAMPLE_TRACE("Topic: '%.*s' (Length: %d)",
ptopic_info->topic_len,
ptopic_info->ptopic,
ptopic_info->topic_len);
EXAMPLE_TRACE("Payload: '%.*s' (Length: %d)",
ptopic_info->payload_len,
ptopic_info->payload,
ptopic_info->payload_len);
EXAMPLE_TRACE("----");
}
O trecho de código a seguir tenta enviar dados para este tópico:
do {
cnt++;
msg_len = snprintf(msg_pub, sizeof(msg_pub), "{\"attr_name\":\"temperature\", \"attr_value\":\"%d\"}", cnt);
...
...
rc = IOT_MQTT_Publish(pclient, TOPIC_DATA, &topic_msg);
if (rc < 0) {
EXAMPLE_TRACE("error occur when publish");
rc = -1;
break;
}
EXAMPLE_TRACE("packet-id=%u, publish topic msg=%s", (uint32_t)rc, msg_pub);
Como o exemplo se inscreve no tópico TOPIC_DATA, ele receberá os dados de volta após enviá-los à plataforma IoT.
Compile o programa de exemplo
Execute o seguinte comando no diretório de nível superior do SDK:
make distclean
make
Após a conclusão bem-sucedida da compilação, o programa de exemplo será gerado no diretório output/release/bin do caminho atual:
$ tree output/release
output/release/
+-- bin
...
...
| +-- mqtt-example
...
...
Observe os dados
Execute o seguinte comando:
$ ./output/release/bin/mqtt-example
Localize o produto especificado no console da Alibaba Cloud IoT Platform e visualize as mensagens relatadas pelo dispositivo no Log Service. Você pode clique em aqui para aprender como visualize os dados relatados pelo dispositivo na nuvem.
Você também pode ver os dados da nuvem impressos pelo programa de exemplo no console Linux:
_demo_message_arrive|166 :: ----
_demo_message_arrive|167 :: packetId: 35641
_demo_message_arrive|171 :: Topic: '/a1ExpAkj9Hi/Example1/data' (Length: 26)
_demo_message_arrive|175 :: Payload: '{"attr_name":"temperature", "attr_value":"1"}' (Length: 45)
_demo_message_arrive|176 :: ----
Desenvolvendo produtos por Device Modelling
Crie produtos e dispositivos
Crie produtos na Alibaba Cloud IoT Platform e utilize os diversos serviços oferecidos nela. Os links de ajuda para criação de produtos na Alibaba Cloud IoT Platform são:
Neste exemplo, crie um produto que suporte as seguintes funções:
-
Propriedade LightSwitch
Identificador: LightSwitch
Tipo de dados: enum
Valores: 0 e 1
Tipo de leitura/gravação: leitura e gravação
-
Serviço Custom
Identificador: Custom
Método de chamada: Assíncrono
Parâmetro de entrada: {Identificador: transparency, Tipo de dados: int32, Faixa de valores: 0 ~ 100}
Parâmetro de saída: {Identificador: Contrastratio, Tipo de dados: int32, Faixa de valores: 0 ~ 100}
-
Evento
Identificador: Error
Tipo de evento: Informação
Parâmetro de saída: {Identificador: Errorcode, Tipo de dados: enum, Faixa de valores: 0, 1}
Após a definição do produto, a plataforma IoT gera um arquivo de descrição TSL no formato JSON para este produto.
Implemente as funções do produto
Insira a tríade do dispositivo na rotina
Substitua o certificado (ProductKey/ProductSecret/DeviceName/DeviceSecret) em ./examples/linkkit/linkkit_example_solo.c pelos dados do dispositivo gerado na plataforma IoT.
#define PRODUCT_KEY "a1csED27mp7"
#define PRODUCT_SECRET "VuULINCrtTAzCSzp"
#define DEVICE_NAME "AdvExample1"
#define DEVICE_SECRET "3xGoxtWRscxPAoMxnJnjocZbNfmCTRi0"
Compile e execute um programa
Execute o seguinte comando no diretório de nível superior do SDK:
$ make distclean
$ make
Após a conclusão bem-sucedida da compilação, o programa de exemplo para o produto Pro-Edition será gerado no diretório output/release/bin do caminho atual, com o nome linkkit-example-solo.
Execute o seguinte comando no diretório de nível superior do SDK:
$ ./output/release/bin/linkkit-example-solo
Observe os dados
O programa de exemplo relata periodicamente os valores da propriedade LightSwitch para a nuvem. Verifique a propriedade na plataforma IoT.
Relate propriedades
Este programa de exemplo invoca a função user_post_property para relatar propriedades. O exemplo percorre ciclicamente o relato de payloads de várias situações. Note que esta função tenta enviar algumas propriedades inválidas para a plataforma IoT; o objetivo é familiarizar os desenvolvedores com os códigos de erro retornados pela plataforma. Remova-as ao implementar sua própria lógica:
void user_post_property(void)
{
static int example_index = 0;
int res = 0;
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
char *property_payload = "NULL";
if (example_index == 0) {
Relato típico de atributo
/* Typical Example */
property_payload = "{\"LightSwitch\":1}";
example_index++;
}else if(...) {
...
...
}
res = IOT_Linkkit_Report(user_example_ctx->master_devid, ITM_MSG_POST_PROPERTY,
(unsigned char *)property_payload, strlen(property_payload));
EXAMPLE_TRACE("Post Property Message ID: %d", res);
}
Os logs impressos durante o relato típico de atributo são os seguintes:
[inf] dm_msg_request(218): DM Send Message, URI: /sys/a1csED27mp7/AdvExample1/thing/event/property/post, Payload: {"id":"1","version":"1.0","params":{"LightSwitch":1},"method":"thing.event.property.post"}
[dbg] MQTTPublish(319): ALLOC: (160) / [224] @ 0x1da41a0
[inf] MQTTPublish(378): Upstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/event/property/post'
[inf] MQTTPublish(379): Upstream Payload:
A seguinte mensagem é enviada para a nuvem:
> {
> "id": "1",
> "version": "1.0",
> "params": {
> "LightSwitch": 1
> },
> "method": "thing.event.property.post"
> }
[inf] dm_client_publish(106): Publish Result: 0
[dbg] alcs_observe_notify(105): payload:{"id":"1","version":"1.0","params":{"LightSwitch":1},"method":"thing.event.property.post"}
[dbg] CoAPResourceByPath_get(176): Found the resource: /sys/a1csED27mp7/AdvExample1/thing/event/property/post
[inf] dm_server_send(76): Send Observe Notify Result 0
[dbg] dm_msg_cache_insert(79): dmc list size: 0
user_post_property. 431: Post Property Message ID: 1
[dbg] iotx_mc_cycle(1774): PUBLISH
[inf] iotx_mc_handle_recv_PUBLISH(1549): Downstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/event/property/post_reply'
[inf] iotx_mc_handle_recv_PUBLISH(1550): Downstream Payload:
A seguinte resposta é recebida da nuvem:
< {
< "code": 200,
< "data": {
< },
< "id": "1",
< "message": "success",
< "method": "thing.event.property.post",
< "version": "1.0"
< }
[dbg] iotx_mc_handle_recv_PUBLISH(1555): Packet Ident : 00000000
[dbg] iotx_mc_handle_recv_PUBLISH(1556): Topic Length : 60
[dbg] iotx_mc_handle_recv_PUBLISH(1560): Topic Name : /sys/a1csED27mp7/AdvExample1/thing/event/property/post_reply
[dbg] iotx_mc_handle_recv_PUBLISH(1563): Payload Len/Room : 104 / 4935
[dbg] iotx_mc_handle_recv_PUBLISH(1564): Receive Buflen : 5000
[dbg] iotx_mc_handle_recv_PUBLISH(1575): delivering msg ...
[dbg] iotx_mc_deliver_message(1291): topic be matched
[inf] dm_msg_proc_thing_event_post_reply(258): Event Id: property
[dbg] dm_msg_response_parse(167): Current Request Message ID: 1
[dbg] dm_msg_response_parse(168): Current Request Message Code: 200
[dbg] dm_msg_response_parse(169): Current Request Message Data: {}
[dbg] dm_msg_response_parse(174): Current Request Message Desc: success
[dbg] dm_ipc_msg_insert(87): dm msg list size: 0, max size: 50
[dbg] dm_msg_cache_remove(142): Remove Message ID: 1
[inf] _iotx_linkkit_event_callback(219): Receive Message Type: 30
[inf] _iotx_linkkit_event_callback(221): Receive Message: {"id":1,"code":200,"devid":0,"payload":{}}
[dbg] _iotx_linkkit_event_callback(476): Current Id: 1
[dbg] _iotx_linkkit_event_callback(477): Current Code: 200
[dbg] _iotx_linkkit_event_callback(478): Current Devid: 0
O log da função de callback:
user_report_reply_event_handler. 300: Message Post Reply Received, Devid: 0, Message ID: 1, Code: 200, Reply: {}
Processe uma solicitação de configuração de propriedade
Quando uma solicitação de configuração de propriedade for recebida no código de exemplo, a seguinte função de callback será chamada:
static int user_property_set_event_handler(const int devid, const char *request, const int request_len)
{
int res = 0;
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
EXAMPLE_TRACE("Property Set Received, Devid: %d, Request: %s", devid, request);
Na função, o valor da propriedade é simplesmente enviado de volta para a plataforma IoT, que atualize o registro de propriedade do dispositivo:
res = IOT_Linkkit_Report(user_example_ctx->master_devid, ITM_MSG_POST_PROPERTY,
(unsigned char *)request, request_len);
EXAMPLE_TRACE("Post Property Message ID: %d", res);
return 0;
}
Visualize o valor defina na plataforma IoT nos logs do dispositivo:
[dbg] iotx_mc_cycle(1774): PUBLISH
[inf] iotx_mc_handle_recv_PUBLISH(1549): Downstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/service/property/set'
[inf] iotx_mc_handle_recv_PUBLISH(1550): Downstream Payload:
A solicitação de configuração de propriedade recebida da nuvem é a seguinte:
< {
< "method": "thing.service.property.set",
< "id": "161430786",
< "params": {
< "LightSwitch": 1
< },
< "version": "1.0.0"
< }
[dbg] iotx_mc_handle_recv_PUBLISH(1555): Packet Ident : 00000000
[dbg] iotx_mc_handle_recv_PUBLISH(1556): Topic Length : 55
[dbg] iotx_mc_handle_recv_PUBLISH(1560): Topic Name : /sys/a1csED27mp7/AdvExample1/thing/service/property/set
[dbg] iotx_mc_handle_recv_PUBLISH(1563): Payload Len/Room : 113 / 4940
[dbg] iotx_mc_handle_recv_PUBLISH(1564): Receive Buflen : 5000
[dbg] iotx_mc_handle_recv_PUBLISH(1575): delivering msg ...
[dbg] iotx_mc_deliver_message(1291): topic be matched
[inf] dm_msg_proc_thing_service_property_set(93): thing/service/property/set
[dbg] dm_msg_request_parse(142): Current Request Message ID: 161430786
[dbg] dm_msg_request_parse(143): Current Request Message Version: 1.0.0
[dbg] dm_msg_request_parse(144): Current Request Message Method: thing.service.property.set
[dbg] dm_msg_request_parse(145): Current Request Message Params: {"LightSwitch":1}
[dbg] dm_ipc_msg_insert(87): dm msg list size: 0, max size: 50
[inf] dm_msg_response(274): Send URI: /sys/a1csED27mp7/AdvExample1/thing/service/property/set_reply, Payload: {"id":"161430786","code":200,"data":{}}
[dbg] MQTTPublish(319): ALLOC: (100) / [164] @ 0x154f1f0
[inf] MQTTPublish(378): Upstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/service/property/set_reply'
[inf] MQTTPublish(379): Upstream Payload:
The following log is printed when the user_property_set_event_handler recebe a solicitação de configuração de atributo:
user_property_set_event_handler. 160: Property Set Received, Devid: 0, Request: {"LightSwitch":1}
Nota: Quando um produto real receber configurações de propriedade, os desenvolvedores devem analisar a propriedade e processá-la adequadamente, em vez de simplesmente enviar o valor de volta para a plataforma IoT.
Relate um evento
A função user_post_event() no programa de exemplo serve para enviar eventos à plataforma IoT. Novamente, ela gera vários eventos inválidos e os envia à plataforma; remova-os e envie eventos apenas quando um evento for realmente acionado:
void user_post_event(void)
{
static int example_index = 0;
int res = 0;
user_example_ctx_t *user_example_ctx = user_example_get_ctx();
char *event_id = "Error";
char *event_payload = "NULL";
if (example_index == 0) {
...
//Report the event to the cloud
res = IOT_Linkkit_TriggerEvent(user_example_ctx->master_devid, event_id, strlen(event_id),
event_payload, strlen(event_payload));
EXAMPLE_TRACE("Post Event Message ID: %d", res);
}
O evento relatado para a nuvem é o seguinte:
> {
> "id": "1",
> "version": "1.0",
> "params": {
> "ErrorCode": 0
> },
> "method": "thing.event.Error.post"
> }
[inf] dm_client_publish(106): Publish Result: 0
[dbg] alcs_observe_notify(105): payload:{"id":"1","version":"1.0","params":{"ErrorCode":0},"method":"thing.event.Error.post"}
[inf] dm_server_send(76): Send Observe Notify Result 0
[dbg] dm_msg_cache_insert(79): dmc list size: 0
user_post_event. 470: Post Event Message ID: 1
[dbg] iotx_mc_cycle(1774): PUBLISH
[inf] iotx_mc_handle_recv_PUBLISH(1549): Downstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/event/Error/post_reply'
[inf] iotx_mc_handle_recv_PUBLISH(1550): Downstream Payload:
A resposta recebida da nuvem é a seguinte:
< {
< "code": 200,
< "data": {
< },
< "id": "1",
< "message": "success",
< "method": "thing.event.Error.post",
< "version": "1.0"
< }
[dbg] iotx_mc_handle_recv_PUBLISH(1555): Packet Ident : 00000000
[dbg] iotx_mc_handle_recv_PUBLISH(1556): Topic Length : 57
[dbg] iotx_mc_handle_recv_PUBLISH(1560): Topic Name : /sys/a1csED27mp7/AdvExample1/thing/event/Error/post_reply
[dbg] iotx_mc_handle_recv_PUBLISH(1563): Payload Len/Room : 101 / 4938
[dbg] iotx_mc_handle_recv_PUBLISH(1564): Receive Buflen : 5000
[dbg] iotx_mc_handle_recv_PUBLISH(1575): delivering msg ...
[dbg] iotx_mc_deliver_message(1291): topic be matched
[inf] dm_msg_proc_thing_event_post_reply(258): Event Id: Error
[dbg] dm_msg_response_parse(167): Current Request Message ID: 1
[dbg] dm_msg_response_parse(168): Current Request Message Code: 200
[dbg] dm_msg_response_parse(169): Current Request Message Data: {}
[dbg] dm_msg_response_parse(174): Current Request Message Desc: success
[dbg] dm_ipc_msg_insert(87): dm msg list size: 0, max size: 50
[dbg] dm_msg_cache_remove(142): Remove Message ID: 1
[inf] _iotx_linkkit_event_callback(219): Receive Message Type: 31
[inf] _iotx_linkkit_event_callback(221): Receive Message: {"id":1,"code":200,"devid":0,"eventid":"Error","payload":"success"}
[dbg] _iotx_linkkit_event_callback(513): Current Id: 1
[dbg] _iotx_linkkit_event_callback(514): Current Code: 200
[dbg] _iotx_linkkit_event_callback(515): Current Devid: 0
[dbg] _iotx_linkkit_event_callback(516): Current EventID: Error
[dbg] _iotx_linkkit_event_callback(517): Current Message: success
O seguinte log é impresso para a função de callback do usuário user_trigger_event_reply_event_handler:
user_trigger_event_reply_event_handler. 310: Trigger Event Reply Received, Devid: 0, Message ID: 1, Code: 200, EventID: Error, Message: success
Chamada de serviço
No programa de exemplo, quando uma solicitação de chamada de serviço for recebida, a seguinte função de callback será invocada:
static int user_service_request_event_handler(const int devid, const char *serviceid, const int serviceid_len,
const char *request, const int request_len,
char **response, int *response_len)
{
int contrastratio = 0, to_cloud = 0;
cJSON *root = NULL, *item_transparency = NULL, *item_from_cloud = NULL;
EXAMPLE_TRACE("Service Request Received, Devid: %d, Service ID: %.*s, Payload: %s", devid, serviceid_len,
serviceid,
request);
/* Parse Root */
root = cJSON_Parse(request);
if (root == NULL || ! cJSON_IsObject(root)) {
EXAMPLE_TRACE("JSON Parse Error");
return -1;
}
Processe o serviço recebido com o ID de Serviço Custom, atribua o valor do parâmetro de entrada do serviço +1 ao parâmetro de saída e retorne-o para a nuvem.
if (strlen("Custom") == serviceid_len && memcmp("Custom", serviceid, serviceid_len) == 0) {
...
contrastratio = item_transparency->valueint + 1;
...
HAL_Snprintf(*response, *response_len, response_fmt, contrastratio);
*response_len = strlen(*response);
} else if (strlen("SyncService") == serviceid_len && memcmp("SyncService", serviceid, serviceid_len) == 0) {
...
...
}
cJSON_Delete(root);
return 0;
}
Neste ponto, visualize o seguinte log no lado do dispositivo:
[dbg] iotx_mc_cycle(1774): PUBLISH
[inf] iotx_mc_handle_recv_PUBLISH(1549): Downstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/service/Custom'
[inf] iotx_mc_handle_recv_PUBLISH(1550): Downstream Payload:
A seguinte solicitação de chamada de serviço é recebida da nuvem, com o parâmetro de entrada transparency:
< {
< "method": "thing.service.Custom",
< "id": "161445548",
< "params": {
< "transparency": 5
< },
< "version": "1.0.0"
< }
[dbg] iotx_mc_handle_recv_PUBLISH(1555): Packet Ident : 00000000
[dbg] iotx_mc_handle_recv_PUBLISH(1556): Topic Length : 49
[dbg] iotx_mc_handle_recv_PUBLISH(1560): Topic Name : /sys/a1csED27mp7/AdvExample1/thing/service/Custom
[dbg] iotx_mc_handle_recv_PUBLISH(1563): Payload Len/Room : 96 / 4946
[dbg] iotx_mc_handle_recv_PUBLISH(1564): Receive Buflen : 5000
[dbg] iotx_mc_handle_recv_PUBLISH(1575): delivering msg ...
[dbg] iotx_mc_deliver_message(1291): topic be matched
[inf] dm_msg_proc_thing_service_request(224): Service Identifier: Custom
[dbg] dm_msg_request_parse(142): Current Request Message ID: 161445548
[dbg] dm_msg_request_parse(143): Current Request Message Version: 1.0.0
[dbg] dm_msg_request_parse(144): Current Request Message Method: thing.service.Custom
[dbg] dm_msg_request_parse(145): Current Request Message Params: {"transparency":5}
[dbg] dm_ipc_msg_insert(87): dm msg list size: 0, max size: 50
[inf] _iotx_linkkit_event_callback(219): Receive Message Type: 18
[inf] _iotx_linkkit_event_callback(221): Receive Message: {"id":"161445548","devid":0,"serviceid":"Custom","payload":{"transparency":5}}
[dbg] _iotx_linkkit_event_callback(300): Current Id: 161445548
[dbg] _iotx_linkkit_event_callback(301): Current Devid: 0
[dbg] _iotx_linkkit_event_callback(302): Current ServiceID: Custom
[dbg] _iotx_linkkit_event_callback(303): Current Payload: {"transparency":5}
A função de chamada do usuário user_service_request_event_handler é chamada:
user_service_request_event_handler. 99: Service Request Received, Devid: 0, Service ID: Custom, Payload: {"transparency":5}
user_service_request_event_handler. 116: transparency: 5
[dbg] iotx_dm_send_service_response(280): Current Service Response Payload, Length: 19, Payload: {"Contrastratio":6}
[dbg] dm_mgr_upstream_thing_service_response(1275): Current Service Name: thing/service/Custom_reply
[inf] dm_msg_response(274): Send URI: /sys/a1csED27mp7/AdvExample1/thing/service/Custom_reply, Payload: {"id":"161445548","code":200,"data":{"Contrastratio":6}}
[dbg] MQTTPublish(319): ALLOC: (111) / [175] @ 0x85a1a0
[inf] MQTTPublish(378): Upstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/service/Custom_reply'
[inf] MQTTPublish(379): Upstream Payload:
Na função de callback, adicione 1 ao valor de transparency, atribua o valor a Contrastratio e relate-o para a nuvem:
> {
> "id": "161445548",
> "code": 200,
> "data": {
> "Contrastratio": 6
> }
> }
[inf] dm_client_publish(106): Publish Result: 0
[dbg] alcs_observe_notify(105): payload:{"id":"161445548","code":200,"data":{"Contrastratio":6}}
[inf] dm_server_send(76): Send Observe Notify Result 0
Isso conclui as descrições de serviços, atributos e eventos na versão avançada da rotina de item único.