interface_webhook.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #include "defines.h"
  2. #include "interface_webhook.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 <cJSON.h>
  9. #include <ClassFlowDefineTypes.h>
  10. static const char *TAG = "WEBHOOK";
  11. std::string _webhookURI;
  12. std::string _webhookApiKey;
  13. long _lastTimestamp;
  14. static esp_err_t http_event_handler(esp_http_client_event_t *evt);
  15. void WebhookInit(std::string _uri, std::string _apiKey)
  16. {
  17. _webhookURI = _uri;
  18. _webhookApiKey = _apiKey;
  19. _lastTimestamp = 0L;
  20. }
  21. bool WebhookPublish(std::vector<NumberPost *> *numbers)
  22. {
  23. bool numbersWithError = false;
  24. cJSON *jsonArray = cJSON_CreateArray();
  25. for (int i = 0; i < (*numbers).size(); ++i)
  26. {
  27. string timezw = "";
  28. char buffer[80];
  29. time_t &lastPreValue = (*numbers)[i]->timeStampLastPreValue;
  30. struct tm *timeinfo = localtime(&lastPreValue);
  31. _lastTimestamp = static_cast<long>(lastPreValue);
  32. strftime(buffer, 80, PREVALUE_TIME_FORMAT_OUTPUT, timeinfo);
  33. timezw = std::string(buffer);
  34. cJSON *json = cJSON_CreateObject();
  35. cJSON_AddStringToObject(json, "timestamp", timezw.c_str());
  36. cJSON_AddStringToObject(json, "timestampLong", std::to_string(_lastTimestamp).c_str());
  37. cJSON_AddStringToObject(json, "name", (*numbers)[i]->name.c_str());
  38. cJSON_AddStringToObject(json, "rawValue", (*numbers)[i]->ReturnRawValue.c_str());
  39. cJSON_AddStringToObject(json, "value", (*numbers)[i]->ReturnValue.c_str());
  40. cJSON_AddStringToObject(json, "preValue", (*numbers)[i]->ReturnPreValue.c_str());
  41. cJSON_AddStringToObject(json, "rate", (*numbers)[i]->ReturnRateValue.c_str());
  42. cJSON_AddStringToObject(json, "changeAbsolute", (*numbers)[i]->ReturnChangeAbsolute.c_str());
  43. cJSON_AddStringToObject(json, "error", (*numbers)[i]->ErrorMessageText.c_str());
  44. cJSON_AddItemToArray(jsonArray, json);
  45. if ((*numbers)[i]->ErrorMessage)
  46. {
  47. numbersWithError = true;
  48. }
  49. }
  50. char *jsonString = cJSON_PrintUnformatted(jsonArray);
  51. LogFile.WriteToFile(ESP_LOG_INFO, TAG, "sending webhook");
  52. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "sending JSON: " + std::string(jsonString));
  53. char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
  54. esp_http_client_config_t http_config = {
  55. .url = _webhookURI.c_str(),
  56. .user_agent = "ESP32 Meter reader",
  57. .method = HTTP_METHOD_POST,
  58. .event_handler = http_event_handler,
  59. .buffer_size = MAX_HTTP_OUTPUT_BUFFER,
  60. .user_data = response_buffer};
  61. esp_http_client_handle_t http_client = esp_http_client_init(&http_config);
  62. esp_http_client_set_header(http_client, "Content-Type", "application/json");
  63. esp_http_client_set_header(http_client, "APIKEY", _webhookApiKey.c_str());
  64. ESP_ERROR_CHECK(esp_http_client_set_post_field(http_client, jsonString, strlen(jsonString)));
  65. esp_err_t err = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_perform(http_client));
  66. if (err == ESP_OK)
  67. {
  68. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP request was performed");
  69. int status_code = esp_http_client_get_status_code(http_client);
  70. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP status code: " + std::to_string(status_code));
  71. }
  72. else
  73. {
  74. LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "HTTP request failed");
  75. }
  76. esp_http_client_cleanup(http_client);
  77. cJSON_Delete(jsonArray);
  78. free(jsonString);
  79. return numbersWithError;
  80. }
  81. void WebhookUploadPic(ImageData *Img)
  82. {
  83. LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Starting WebhookUploadPic");
  84. std::string fullURI = _webhookURI + "?timestamp=" + std::to_string(_lastTimestamp);
  85. char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
  86. esp_http_client_config_t http_config = {
  87. .url = fullURI.c_str(),
  88. .user_agent = "ESP32 Meter reader",
  89. .method = HTTP_METHOD_PUT,
  90. .event_handler = http_event_handler,
  91. .buffer_size = MAX_HTTP_OUTPUT_BUFFER,
  92. .user_data = response_buffer};
  93. esp_http_client_handle_t http_client = esp_http_client_init(&http_config);
  94. esp_http_client_set_header(http_client, "Content-Type", "image/jpeg");
  95. esp_http_client_set_header(http_client, "APIKEY", _webhookApiKey.c_str());
  96. esp_err_t err = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_set_post_field(http_client, (const char *)Img->data, Img->size));
  97. err = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_perform(http_client));
  98. if (err == ESP_OK)
  99. {
  100. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP PUT request was performed successfully");
  101. int status_code = esp_http_client_get_status_code(http_client);
  102. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP status code: " + std::to_string(status_code));
  103. }
  104. else
  105. {
  106. LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "HTTP PUT request failed");
  107. }
  108. esp_http_client_cleanup(http_client);
  109. LogFile.WriteToFile(ESP_LOG_INFO, TAG, "WebhookUploadPic finished");
  110. }
  111. static esp_err_t http_event_handler(esp_http_client_event_t *evt)
  112. {
  113. switch (evt->event_id)
  114. {
  115. case HTTP_EVENT_ERROR:
  116. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Error encountered");
  117. break;
  118. case HTTP_EVENT_ON_CONNECTED:
  119. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client connected");
  120. ESP_LOGI(TAG, "HTTP Client Connected");
  121. break;
  122. case HTTP_EVENT_HEADERS_SENT:
  123. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client sent all request headers");
  124. break;
  125. case HTTP_EVENT_ON_HEADER:
  126. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Header: key=" + std::string(evt->header_key) + ", value=" + std::string(evt->header_value));
  127. break;
  128. case HTTP_EVENT_ON_DATA:
  129. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client data recevied: len=" + std::to_string(evt->data_len));
  130. break;
  131. case HTTP_EVENT_ON_FINISH:
  132. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client finished");
  133. break;
  134. case HTTP_EVENT_DISCONNECTED:
  135. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Disconnected");
  136. break;
  137. case HTTP_EVENT_REDIRECT:
  138. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Redirect");
  139. break;
  140. }
  141. return ESP_OK;
  142. }