diff --git a/CMakeLists.txt b/CMakeLists.txt index 851d1488eca..2518b0be093 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,7 @@ set(LIBRARY_SRCS libraries/RainMaker/src/RMakerType.cpp libraries/RainMaker/src/RMakerQR.cpp libraries/RainMaker/src/RMakerUtils.cpp + libraries/RainMaker/src/AppInsights.cpp libraries/SD_MMC/src/SD_MMC.cpp libraries/SD/src/SD.cpp libraries/SD/src/sd_diskio.cpp diff --git a/libraries/Insights/src/Insights.cpp b/libraries/Insights/src/Insights.cpp index 0ec65e86727..49de5b2035a 100644 --- a/libraries/Insights/src/Insights.cpp +++ b/libraries/Insights/src/Insights.cpp @@ -49,13 +49,18 @@ ESPInsightsClass::~ESPInsightsClass(){ end(); } -bool ESPInsightsClass::begin(const char *auth_key, const char *node_id, uint32_t log_type, bool alloc_ext_ram){ +bool ESPInsightsClass::begin(const char *auth_key, const char *node_id, uint32_t log_type, bool alloc_ext_ram, bool use_default_transport){ if(!initialized){ if(log_type == 0xFFFFFFFF){ log_type = (ESP_DIAG_LOG_TYPE_ERROR | ESP_DIAG_LOG_TYPE_WARNING | ESP_DIAG_LOG_TYPE_EVENT); } esp_insights_config_t config = {.log_type = log_type, .node_id = node_id, .auth_key = auth_key, .alloc_ext_ram = alloc_ext_ram}; - esp_err_t err = esp_insights_init(&config); + esp_err_t err = ESP_OK; + if (use_default_transport) { + err = esp_insights_init(&config); + } else { + err = esp_insights_enable(&config); + } if (err != ESP_OK) { log_e("Failed to initialize ESP Insights, err:0x%x", err); } diff --git a/libraries/Insights/src/Insights.h b/libraries/Insights/src/Insights.h index b950b937b14..d572c35a012 100644 --- a/libraries/Insights/src/Insights.h +++ b/libraries/Insights/src/Insights.h @@ -90,7 +90,7 @@ class ESPInsightsClass ESPInsightsClass(); ~ESPInsightsClass(); - bool begin(const char *auth_key, const char *node_id = NULL, uint32_t log_type = 0xFFFFFFFF, bool alloc_ext_ram = false); + bool begin(const char *auth_key, const char *node_id = NULL, uint32_t log_type = 0xFFFFFFFF, bool alloc_ext_ram = false, bool use_default_transport = true); void end(); bool send(); const char * nodeID(); diff --git a/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino b/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino index 4594fbb75af..f68a3c7dccb 100644 --- a/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino +++ b/libraries/RainMaker/examples/RMakerSwitch/RMakerSwitch.ino @@ -2,6 +2,7 @@ #include "RMaker.h" #include "WiFi.h" #include "WiFiProv.h" +#include "AppInsights.h" #define DEFAULT_POWER_MODE true const char *service_name = "PROV_1234"; @@ -88,6 +89,9 @@ void setup() RMaker.enableSchedule(); RMaker.enableScenes(); + // Enable ESP Insights. Insteads of using the default http transport, this function will + // reuse the existing MQTT connection of Rainmaker, thereby saving memory space. + initAppInsights(); RMaker.start(); diff --git a/libraries/RainMaker/src/AppInsights.cpp b/libraries/RainMaker/src/AppInsights.cpp new file mode 100644 index 00000000000..591f5e65dcc --- /dev/null +++ b/libraries/RainMaker/src/AppInsights.cpp @@ -0,0 +1,81 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include +#if defined(CONFIG_ESP_INSIGHTS_ENABLED) && defined(CONFIG_ESP_RMAKER_WORK_QUEUE_TASK_STACK) +#include "Arduino.h" +#include "AppInsights.h" +#include "Insights.h" +#include +#include +#include +#include +#include + +extern "C" { + bool esp_rmaker_mqtt_is_budget_available(); +} + +#define INSIGHTS_TOPIC_SUFFIX "diagnostics/from-node" +#define INSIGHTS_TOPIC_RULE "insights_message_delivery" + +static void _rmakerCommonEventHandler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +{ + if (event_base != RMAKER_COMMON_EVENT) { + return; + } + esp_insights_transport_event_data_t data; + switch(event_id) { + case RMAKER_MQTT_EVENT_PUBLISHED: + memset(&data, 0, sizeof(data)); + data.msg_id = *(int *)event_data; + esp_event_post(INSIGHTS_EVENT, INSIGHTS_EVENT_TRANSPORT_SEND_SUCCESS, &data, sizeof(data), portMAX_DELAY); + break; + default: + break; + } +} + +static int _appInsightsDataSend(void *data, size_t len) +{ + char topic[128]; + int msg_id = -1; + if (data == NULL) { + return 0; + } + char *node_id = esp_rmaker_get_node_id(); + if (!node_id) { + return -1; + } + if (esp_rmaker_mqtt_is_budget_available() == false) { + return ESP_FAIL; + } + esp_rmaker_create_mqtt_topic(topic, sizeof(topic), INSIGHTS_TOPIC_SUFFIX, INSIGHTS_TOPIC_RULE); + esp_rmaker_mqtt_publish(topic, data, len, RMAKER_MQTT_QOS1, &msg_id); + return msg_id; +} + +bool initAppInsights(uint32_t log_type, bool alloc_ext_ram) +{ + char *node_id = esp_rmaker_get_node_id(); + esp_insights_transport_config_t transport; + transport.userdata = NULL; + transport.callbacks.data_send = _appInsightsDataSend; + transport.callbacks.init = NULL; + transport.callbacks.deinit = NULL; + transport.callbacks.connect = NULL; + transport.callbacks.disconnect = NULL; + esp_insights_transport_register(&transport); + esp_event_handler_register(RMAKER_COMMON_EVENT, ESP_EVENT_ANY_ID, _rmakerCommonEventHandler, NULL); + return Insights.begin(NULL, node_id, log_type, alloc_ext_ram, false); +} +#else +bool initAppInsights(uint32_t log_type, bool alloc_ext_ram) +{ + return false; +} +#endif diff --git a/libraries/RainMaker/src/AppInsights.h b/libraries/RainMaker/src/AppInsights.h new file mode 100644 index 00000000000..ddb32f1e266 --- /dev/null +++ b/libraries/RainMaker/src/AppInsights.h @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "sdkconfig.h" +#include "Arduino.h" +#include + +bool initAppInsights(uint32_t log_type = 0xffffffff, bool alloc_ext_ram = false);