interface_webhook.cpp 6.3 KB

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