interface_influxdb.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #ifdef ENABLE_INFLUXDB
  2. #include "interface_influxdb.h"
  3. #include "esp_log.h"
  4. #include <time.h>
  5. #include "ClassLogFile.h"
  6. #include "esp_http_client.h"
  7. #include "time_sntp.h"
  8. #include "../../include/defines.h"
  9. static const char *TAG = "INFLUXDB";
  10. /**
  11. * @brief Buffer to store the HTTP response.
  12. *
  13. * This character array is used to store the output of an HTTP response.
  14. * The size of the buffer is defined by the constant MAX_HTTP_OUTPUT_BUFFER.
  15. */
  16. char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
  17. /**
  18. * @brief HTTP event handler callback function.
  19. *
  20. * This function handles various HTTP client events and logs appropriate messages.
  21. *
  22. * @param evt Pointer to the HTTP client event structure.
  23. * @return esp_err_t ESP_OK on success.
  24. *
  25. * Event types handled:
  26. * - HTTP_EVENT_ERROR: Logs an error message when an HTTP error is encountered.
  27. * - HTTP_EVENT_ON_CONNECTED: Logs a message when the HTTP client successfully connects.
  28. * - HTTP_EVENT_HEADERS_SENT: Logs a message when all request headers are sent.
  29. * - HTTP_EVENT_ON_HEADER: Logs the received header key and value.
  30. * - HTTP_EVENT_ON_DATA: Logs the length of the received data.
  31. * - HTTP_EVENT_ON_FINISH: Logs a message when the HTTP client finishes the request.
  32. * - HTTP_EVENT_DISCONNECTED: Logs a message when the HTTP client disconnects.
  33. * - HTTP_EVENT_REDIRECT: Logs a message when an HTTP redirect occurs.
  34. */
  35. static esp_err_t http_event_handler(esp_http_client_event_t *evt)
  36. {
  37. switch(evt->event_id)
  38. {
  39. case HTTP_EVENT_ERROR:
  40. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Error encountered");
  41. break;
  42. case HTTP_EVENT_ON_CONNECTED:
  43. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client connected");
  44. ESP_LOGI(TAG, "HTTP Client Connected");
  45. break;
  46. case HTTP_EVENT_HEADERS_SENT:
  47. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client sent all request headers");
  48. break;
  49. case HTTP_EVENT_ON_HEADER:
  50. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Header: key=" + std::string(evt->header_key) + ", value=" + std::string(evt->header_value));
  51. break;
  52. case HTTP_EVENT_ON_DATA:
  53. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client data recevied: len=" + std::to_string(evt->data_len));
  54. break;
  55. case HTTP_EVENT_ON_FINISH:
  56. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client finished");
  57. break;
  58. case HTTP_EVENT_DISCONNECTED:
  59. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Disconnected");
  60. break;
  61. case HTTP_EVENT_REDIRECT:
  62. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Redirect");
  63. break;
  64. }
  65. return ESP_OK;
  66. }
  67. /**
  68. * @brief Initializes the InfluxDB connection with version 1 settings.
  69. *
  70. * This function sets up the connection parameters for InfluxDB version 1.
  71. *
  72. * @param _influxDBURI The URI of the InfluxDB server.
  73. * @param _database The name of the database to connect to.
  74. * @param _user The username for authentication.
  75. * @param _password The password for authentication.
  76. */
  77. void InfluxDB::InfluxDBInitV1(std::string _influxDBURI, std::string _database, std::string _user, std::string _password) {
  78. version = INFLUXDB_V1;
  79. influxDBURI = _influxDBURI;
  80. database = _database;
  81. user = _user;
  82. password = _password;
  83. }
  84. /**
  85. * @brief Initializes the InfluxDB client with version 2 settings.
  86. *
  87. * This function sets up the InfluxDB client to use InfluxDB version 2 by
  88. * configuring the URI, bucket, organization, and token.
  89. *
  90. * @param _influxDBURI The URI of the InfluxDB server.
  91. * @param _bucket The bucket name to store data in.
  92. * @param _org The organization name associated with the bucket.
  93. * @param _token The authentication token for accessing the InfluxDB server.
  94. */
  95. void InfluxDB::InfluxDBInitV2(std::string _influxDBURI, std::string _bucket, std::string _org, std::string _token) {
  96. version = INFLUXDB_V2;
  97. influxDBURI = _influxDBURI;
  98. bucket = _bucket;
  99. org = _org;
  100. token = _token;
  101. }
  102. /**
  103. * @brief Establishes an HTTP connection to the InfluxDB server.
  104. *
  105. * This function configures and initializes an HTTP client to connect to the InfluxDB server.
  106. * It sets up the necessary parameters such as the URL, event handler, buffer size, and user data.
  107. * Depending on the InfluxDB version, it also configures the authentication type and credentials.
  108. *
  109. * @note This function destroys any existing HTTP client before initializing a new one.
  110. *
  111. * @param None
  112. * @return None
  113. */
  114. void InfluxDB::connectHTTP() {
  115. esp_http_client_config_t config = {};
  116. config.url = influxDBURI.c_str();
  117. config.event_handler = http_event_handler;
  118. config.buffer_size = MAX_HTTP_OUTPUT_BUFFER;
  119. config.user_data = response_buffer;
  120. switch (version) {
  121. case INFLUXDB_V1:
  122. config.auth_type = HTTP_AUTH_TYPE_BASIC;
  123. config.username = user.c_str();
  124. config.password = password.c_str();
  125. break;
  126. case INFLUXDB_V2:
  127. break;
  128. }
  129. InfluxDBdestroy();
  130. httpClient = esp_http_client_init(&config);
  131. if (!httpClient) {
  132. LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to initialize HTTP client");
  133. } else {
  134. LogFile.WriteToFile(ESP_LOG_INFO, TAG, "HTTP client initialized successfully");
  135. }
  136. }
  137. /**
  138. * @brief Destroys the InfluxDB instance by cleaning up the HTTP client.
  139. *
  140. * This function checks if the HTTP client is initialized. If it is, it cleans up the HTTP client
  141. * and logs the cleanup action. The HTTP client pointer is then set to NULL.
  142. */
  143. void InfluxDB::InfluxDBdestroy() {
  144. if (httpClient) {
  145. esp_http_client_cleanup(httpClient);
  146. LogFile.WriteToFile(ESP_LOG_INFO, TAG, "HTTP client cleaned up");
  147. httpClient = NULL;
  148. }
  149. }
  150. /**
  151. * @brief Publishes data to an InfluxDB instance.
  152. *
  153. * This function sends a measurement, key, and content to an InfluxDB server.
  154. * It supports both InfluxDB v1 and v2 APIs.
  155. *
  156. * @param _measurement The measurement name to publish.
  157. * @param _key The key associated with the measurement.
  158. * @param _content The content or value to publish.
  159. * @param _timeUTC The timestamp in UTC. If greater than 0, it will be included in the payload.
  160. *
  161. * The function logs the process and handles HTTP communication with the InfluxDB server.
  162. * It constructs the appropriate API URI based on the InfluxDB version and sends the data
  163. * using an HTTP POST request.
  164. */
  165. void InfluxDB::InfluxDBPublish(std::string _measurement, std::string _key, std::string _content, long int _timeUTC) {
  166. std::string apiURI;
  167. std::string payload;
  168. char nowTimestamp[21];
  169. connectHTTP();
  170. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBPublish - Key: " + _key + ", Content: " + _content + ", timeUTC: " + std::to_string(_timeUTC));
  171. if (_timeUTC > 0)
  172. {
  173. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Timestamp (UTC): " + std::to_string(_timeUTC));
  174. sprintf(nowTimestamp,"%ld000000000", _timeUTC); // UTC
  175. payload = _measurement + " " + _key + "=" + _content + " " + nowTimestamp;
  176. }
  177. else
  178. {
  179. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "no timestamp given");
  180. payload = _measurement + " " + _key + "=" + _content;
  181. }
  182. payload.shrink_to_fit();
  183. LogFile.WriteToFile(ESP_LOG_INFO, TAG, "sending line to influxdb:" + payload);
  184. esp_err_t err;
  185. switch (version) {
  186. case INFLUXDB_V1:
  187. apiURI = influxDBURI + "/write?db=" + database;
  188. apiURI.shrink_to_fit();
  189. esp_http_client_set_url(httpClient, apiURI.c_str());
  190. esp_http_client_set_method(httpClient, HTTP_METHOD_POST);
  191. esp_http_client_set_header(httpClient, "Content-Type", "text/plain");
  192. esp_http_client_set_post_field(httpClient, payload.c_str(), payload.length());
  193. err = esp_http_client_perform(httpClient);
  194. if (err == ESP_OK) {
  195. LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Data published successfully: " + payload);
  196. } else {
  197. LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to publish data: " + std::string(esp_err_to_name(err)));
  198. }
  199. break;
  200. case INFLUXDB_V2:
  201. apiURI = influxDBURI + "/api/v2/write?org=" + org + "&bucket=" + bucket;
  202. apiURI.shrink_to_fit();
  203. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "apiURI: " + apiURI);
  204. esp_http_client_set_url(httpClient, apiURI.c_str());
  205. esp_http_client_set_method(httpClient, HTTP_METHOD_POST);
  206. esp_http_client_set_header(httpClient, "Content-Type", "text/plain");
  207. std::string _zw = "Token " + token;
  208. esp_http_client_set_header(httpClient, "Authorization", _zw.c_str());
  209. esp_http_client_set_post_field(httpClient, payload.c_str(), payload.length());
  210. err = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_perform(httpClient));
  211. if (err == ESP_OK) {
  212. LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Data published successfully: " + payload);
  213. } else {
  214. LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Failed to publish data: " + std::string(esp_err_to_name(err)));
  215. }
  216. break;
  217. }
  218. }
  219. #endif //ENABLE_INFLUXDB