ThingsBoard 设备发送RPC 给服务器 (含规则链修改)

一、规则链配置

原本的规则链需要增加转换脚本(这里需要增加RPC发给设备的规则,否则仪表库的控制设备,发数据过去没效果)

  1. 先过滤一个字段
  2. 转换脚本,将RPC数据给到属性
  3. 保存属性
msgType = "POST_ATTRIBUTES_REQUEST";
msg = {"CaptureNow":msg.params};
return {msg: msg, metadata: metadata, msgType: msgType};

在这里插入图片描述

二、源码

这里实现的逻辑

  1. 周期性获取一次 共享属性(共享属性可以通过平台进行建立和修改和删除)
  2. 若这个共享属性为1时,触发一下RPC命令,命令带上false
  3. 服务器收到RPC命令后,因为设置了规则链,会将这个共享属性变成false
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "protocol_examples_common.h"
#include "nvs.h"
#include "nvs_flash.h"

#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"

#include "mqtt_client.h"

#include "cJSON.h"

static const char *TAG = "MQTT_EXAMPLE";

uint8_t mqtt_connect_flag = 0;
esp_mqtt_client_handle_t g_client;

static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
{
    esp_mqtt_client_handle_t client = event->client;

    int msg_id;
    // your_context_t *context = event->context;
    switch (event->event_id) {
        case MQTT_EVENT_CONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
          //  msg_id = esp_mqtt_client_publish(client, "v1/devices/me/telemetry", "{temperature:25}", 0, 1, 0);
          //  ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);

          //  msg_id = esp_mqtt_client_publish(client, "v1/devices/me/attributes", "{humtiti:1.0}", 0, 1,0 );
          //  ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);

         //   msg_id = esp_mqtt_client_subscribe(client, "v1/devices/me/attributes", 1);
         //   ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

			//设备收到的rpc请求
            msg_id = esp_mqtt_client_subscribe(client, "v1/devices/me/rpc/request/+", 1);
            ESP_LOGI(TAG, "sent subscribe device rpc topic successful, msg_id=%d", msg_id);

			//发送rpc后,收到的回复
            msg_id = esp_mqtt_client_subscribe(client, "v1/devices/me/rpc/response/+", 1);
            ESP_LOGI(TAG, "sent subscribe device rpc topic successful, msg_id=%d", msg_id);

         //   msg_id = esp_mqtt_client_publish(client, "v1/devices/me/rpc/response/1",  "{\"params\": false}", 0, 1, 0);
         //   ESP_LOGI(TAG, "sent publish device rpc successful, msg_id=%d", msg_id);

         //   msg_id = esp_mqtt_client_publish(client, "v1/devices/me/rpc/request/1",  "{\"method\": \"getTime\",\"params\": {}}", 0, 1, 0);
        //    ESP_LOGI(TAG, "sent publish device rpc successful, msg_id=%d", msg_id);
			//设备自身请求属性回复
            msg_id = esp_mqtt_client_subscribe(client, "v1/devices/me/attributes/response/+", 1);
            ESP_LOGI(TAG, "sent subscribe attributes successful, msg_id=%d", msg_id);
         //   msg_id = esp_mqtt_client_publish(client, "v1/devices/me/attributes/request/1",  "{ \"sharedKeys\":\"humtiti,shot\"}", 0, 1, 0);
        //    ESP_LOGI(TAG, "sent publish  attributes successful, msg_id=%d", msg_id);

			mqtt_connect_flag = 1;
			g_client = client;


            // msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
           //ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
            break;
        case MQTT_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
			mqtt_connect_flag = 0;
            break;

        case MQTT_EVENT_SUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
            msg_id = esp_mqtt_client_publish(client, "v1/devices/me/rpc/request/1", "{\"method\": \"getDevice\",\"params\": {}}", 0, 0, 0);
            ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
            break;
        case MQTT_EVENT_UNSUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_PUBLISHED:
            ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_DATA:
            ESP_LOGI(TAG, "MQTT_EVENT_DATA");
            printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
            printf("DATA=%.*s\r\n", event->data_len, event->data);
           // msg_id = esp_mqtt_client_publish(client, "v1/devices/me/attributes", "{\"params\": false}", 0, 1, 0);
        	//ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);

			//收到请求的数据
			if(strstr((const char *)event->topic,"me/attributes/response"))
			{
				cJSON * pJson = cJSON_Parse(event->data);
				if(NULL == pJson)
				{
					ESP_LOGI("CJSON", "cJSON_Parse error");
					break;
				}

				ESP_LOGI("CJSON", "cJSON_Parse ok");

				//{"shared":{"CaptureNow":false}}
				cJSON *  pSub = cJSON_GetObjectItem(pJson, "shared");//获取 shared 数据
				if(pSub != NULL)
				{

					//获取 CaptureNow
					cJSON *  pSubSub = cJSON_GetObjectItem(pSub, "CaptureNow");
					if(NULL==pSubSub)
					{
						ESP_LOGI("CJSON", "get CaptureNow error");
					}
					else
					{
						ESP_LOGI("CJSON", "CaptureNow:%d",pSubSub->valueint);

						if(pSubSub->valueint == 1)//等于1时,rpc将属性设置为false
						{

							//这里等待1秒,让你看清楚而已
							vTaskDelay(1000/portTICK_PERIOD_MS);




							int msg_id;
							static uint8_t request_id = 0;
							char request_topic[50];
							char publish_data[100]="{\"method\": \"setCaptureNow\",\"params\": false}";
							sprintf(request_topic,"v1/devices/me/rpc/request/%d",request_id++);
							msg_id = esp_mqtt_client_publish(g_client, request_topic, publish_data, 0, 1, 0);
							ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
						}

					//	ESP_LOGI("CJSON", "temperature:%d",pSubSub->valueint);
					}


				}

				cJSON_Delete(pJson);
			}
			//收到RPC数据请求
			else if(strstr((const char *)event->topic,"rpc/request"))
			{

				cJSON * pJson = cJSON_Parse(event->data);
				if(NULL == pJson)
				{
					ESP_LOGI("CJSON", "cJSON_Parse error");
					break;
				}
				cJSON *  pSub = cJSON_GetObjectItem(pJson, "method");//获取 method
				if(pSub != NULL)
				{
					if(!strcmp(pSub->valuestring,"setThrust"))
					{
						//这里设置数据
						ESP_LOGI(TAG,"rpc/request --->  setThrust");
					}
				}

				cJSON_Delete(pJson);

			}
			//收到RPC数据的回复
			else if(strstr((const char *)event->topic,"rpc/response"))
			{
				ESP_LOGI(TAG,"GET rpc/response");
			}

        	break;
        case MQTT_EVENT_ERROR:
            ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
            break;
    }
    return ESP_OK;
}

static void mqtt_app_start(void)
{
    esp_mqtt_client_config_t mqtt_cfg = {

      //.uri = CONFIG_BROKER_URL,
    	    .host = "192.168.82.94",            //MQTT服务器IP
    		//.uri = "mqtt://192.168.82.94:1883",
    	    .event_handle = mqtt_event_handler, //MQTT事件
    	    .port=1883,                         //端口
    	    .username = "U4G6ESZucf0faN6gWaut",                //用户名
			.client_id = "f10220b0-3707-11ec-a7ab-0d2f8ea1e2e0",
    	       // .password = "public",               //密码
        // .user_context = (void *)your_context
    };

    ESP_LOGI(TAG, "uri:%s\r\nusername:%s\r\nclient_id:%s\r\n",mqtt_cfg.uri,mqtt_cfg.username,mqtt_cfg.client_id);

    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
    esp_mqtt_client_start(client);
}


static void get_attr_task(void *arg)
{
	//vTaskDelay(5000 / portTICK_PERIOD_MS);
	for(;;)
	{
		if(mqtt_connect_flag == 1)
		{
			vTaskDelay(5000 / portTICK_PERIOD_MS);

			//{"sharedKeys":"CaptureNow"}
			int msg_id;
			static uint8_t request_id = 0;
			char request_topic[50];
			char publish_data[100]="{\"sharedKeys\":\"CaptureNow\"}";
			sprintf(request_topic,"v1/devices/me/attributes/request/%d",request_id++);
			msg_id = esp_mqtt_client_publish(g_client, request_topic, publish_data, 0, 1, 0);
			ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);

		}
		vTaskDelay(1000 / portTICK_PERIOD_MS);
	}
}

void app_main()
{
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    ESP_ERROR_CHECK(example_connect());

    ESP_LOGI(TAG, "[APP] Startup..");
    ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
    ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());

    esp_log_level_set("*", ESP_LOG_INFO);
    esp_log_level_set("MQTT_CLIENT", ESP_LOG_VERBOSE);
    esp_log_level_set("TRANSPORT_TCP", ESP_LOG_VERBOSE);
    esp_log_level_set("TRANSPORT_SSL", ESP_LOG_VERBOSE);
    esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE);
    esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE);

	//这个是用来每1秒获取一下数据而已
	xTaskCreate(get_attr_task, "get_attr", 2048, NULL, configMAX_PRIORITIES-2, NULL);

    mqtt_app_start();
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Thingsboard RPC是一个在Thingsboard IoT平台上实现的远程过程调用(RPC)协议。该协议可以通过设备端和服务器端之间的消息传递实现远程操作和数据交换。 通过使用RPC协议,设备端可以请求并获取从Thingsboard服务器发送的数据、设备配置信息及指令等内容。同时,服务器端也可以通过RPC协议向设备发送命令控制和操作指令,实现对设备进行远程配置和调试。 Thingsboard RPC通过 WebSocket通信方式实现低延迟的双向通信,并提供多种安全认证机制,如基于令牌的认证和 OAuth 2.0授权认证,以确保通信的安全性和保密性。 由于其灵活性和可扩展性,Thingsboard RPC被广泛用于各种物联网设备连接和数据交互场景,尤其在智能家居、工业生产监控和智能交通等领域得到了广泛应用。 ### 回答2: Thingsboard RPC是一种客户端与Thingsboard服务器之间实现远程过程调用(RPC)的方法。将RPC作为通讯协议可以让设备在向云平台发送指令时变得更加方便易用。它提供了从Thingsboard服务器设备发送指令的方法,这些指令可以让设备执行命令、控制参数、查询状态等一系列操作。 在Thingsboard系统中,RPC是基于MQTT协议实现的,这使得在设备服务器之间进行指令通讯变得更加轻松。对于开发者来讲,使用Thingsboard RPC可以更加方便的编写客户端软件,通过依赖Thingsboard中现有的一些API,实现与设备之间的通信。 Thingsboard RPC的作用十分重要,因为它可以降低设备与云平台之间的耦合性,让设备可以更加自由的与不同的云平台相连接。使用RPC设备只需要实现特定的通讯协议,然后就可以与Thingsboard建立通讯路,在云平台上实现远程过程调用。 总的来说,使用Thingsboard RPC可以使设备与云平台之间的通讯更加高效、且易于管理,同时也可以让开发者更加方便的实现针对设备的应用程序。这是一种十分有效的通讯方法,有助于促进IoT设备在各具特色的云平台上实现海量连接。 ### 回答3: Thingsboard RPC是一种在Thingsboard IoT平台上运行的远程过程调用(RPC)协议,它使用了基于HTTP的RESTful API,支持在设备和应用程序之间进行双向通信以及控制和监视设备。 首先,Thingsboard RPC协议主要用于远程控制设备。通过在Thingsboard服务器上定义RPC方法,您可以在物联网设备中远程调用这些方法。这些方法可以用于控制物联网设备上的功能,例如打开闸门、控制灯光等。这种远程控制可以通过HTTP和MQTT协议完成。 其次,Thingsboard RPC还提供了一种机制来监视物联网设备。通过在设备上定义RPC方法,您可以定期将设备状态更新并发送到Thingsboard服务器。这种状态更新可帮助监视设备运行状况,例如检测设备的电量和温度等,以及发现潜在的故障或其他问题。 此外,Thingsboard RPC还可以帮助您构建复杂的工作流程,以便实现更高级别的控制。通过结合Thingsboard规则引擎和RPC方法,您可以自动化执行流程,例如将安全告警发送给工程师或将数据记录到数据库中。 总而言之,Thingsboard RPC是一个功能强大的远程过程调用协议,可以帮助您控制和监视物联网设备,并实现自动化工作流程。它是Thingsboard IoT平台成功的关键之一,也是许多物联网应用程序所必需的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值