device to server websocket communcation
Posted: Fri Jul 14, 2023 3:40 pm
Hey everyone, I have been working with the websocket aspect of the ESP and I am running into an issue. I have created an http server that performs various tasks, but the issue I am having is getting the html page to update without having to refresh it. Currenly i have created an html table on the server and an LVGL table on the device. When i click an element on the html table, it updates the device(such as changing the element from green to red, vise versa). Thus, my server to device works perfectly. Now I want to be able to click the element on the lvgl table and have the server update its html table. I've tried a couple ways but am not having any luck. The html changes its own element when i click on it using a javascript function called changeElement(rowID) (rowID being the row that was clicked). its very straightforward. the lvgl table changes its element using lvgl functions but mainly an eventHandler when a certain element is clicked. Again, everything works for the server to device but I cannot figure out how to get it to communicate from device to server. I can provide code snippits if requested, if anyone has any information or can point me in the right directly that would be greatly appreciated. Here is my websocket handler:
and here is my lvgl table event handler:
Code: Select all
static esp_err_t handle_ws_req_2(httpd_req_t *req) {
if (req->method == HTTP_GET) {
ESP_LOGI(TAG, "Handshake done 2, the new connection was opened");
return ESP_OK;
}
httpd_ws_frame_t ws_pkt;
uint8_t *buf = NULL;
memset(&ws_pkt, 0, sizeof(httpd_ws_frame_t));
ws_pkt.type = HTTPD_WS_TYPE_TEXT;
esp_err_t ret = httpd_ws_recv_frame(req, &ws_pkt, 0);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "httpd_ws_recv_frame failed to get frame len with %d", ret);
return ret;
}
if (ws_pkt.len) {
buf = (uint8_t *)calloc(1, ws_pkt.len + 1);
if (buf == NULL) {
ESP_LOGE(TAG, "Failed to calloc memory for buf");
return ESP_ERR_NO_MEM;
}
ws_pkt.payload = buf;
ret = httpd_ws_recv_frame(req, &ws_pkt, ws_pkt.len);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "httpd_ws_recv_frame failed to recv frame with %d", ret);
return ret;
}
buf[ws_pkt.len] = '\0';
// Handle the received message
char *message = (char *)buf;
// Prepare the response message
snprintf((char *)response_data, sizeof(response_data), "%s", "Success");
httpd_ws_frame_t resp_pkt;
memset(&resp_pkt, 0, sizeof(httpd_ws_frame_t));
resp_pkt.type = HTTPD_WS_TYPE_TEXT;
resp_pkt.len = strlen((char *)response_data);
resp_pkt.payload = (uint8_t *)response_data;
int sockfd = httpd_req_to_sockfd(req);
ret = httpd_ws_send_frame_async(req->handle, sockfd, &resp_pkt);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "httpd_ws_send_frame failed to send frame with %d", ret);
free(buf);
return ret;
}
// Extract and store the rowId and newState
int rowId;
char newState[50];
if (sscanf(message, "{\"rowId\":%d, \"newState\":\"%[^\"]\"}", &rowId, newState) != 2) {
ESP_LOGE(TAG, "Failed to extract rowId and newState from the received message");
free(buf);
return ESP_FAIL;
}
ESP_LOGI(TAG, "Received rowId: %d, newState: %s", rowId, newState);
// Perform the necessary operations based on the received message
// ...
// Flop the elements (red/green)
if (!flopElement(bit_table, rowId)) {
ESP_LOGE(TAG, "Failed to flop elements");
free(buf);
return ESP_FAIL;
}
// Get the updated state of the elements
const char *state = getElementState(bit_table, rowId);
if (state == NULL) {
ESP_LOGE(TAG, "Failed to get elements state");
free(buf);
return ESP_FAIL;
}
ESP_LOGI(TAG, "Received message: %s", message);
// Prepare the response message
snprintf((char *)response_data, sizeof(response_data), "%s", state);
}
free(buf);
return ESP_OK;
}
Code: Select all
void tableEventHandler_2(lv_event_t * event)
{
lv_obj_t* obj = lv_event_get_target(event);
lv_table_t *table = (lv_table_t *)obj;
lv_event_code_t code = lv_event_get_code(event);
if(code == LV_EVENT_PRESSED)
{
uint16_t row, col = 0;
lv_table_get_selected_cell(obj, &row, &col);
triggeredrow = row;
// cout << row << endl;
// cout << col << endl;
const char* currentValue = lv_table_get_cell_value(obj, row, col);
// cout << currentValue << endl;
if (row <= 3000 && col <= 3000)
{
uint16_t currentIndex = 0;
uint16_t nextIndex = 0;
for (uint16_t i = 0; i < sizeof(alarmDescriptions) / sizeof(alarmDescriptions[0]); i++)
{
if (strcmp(currentValue, alarmDescriptions[i]) == 0)
{
currentIndex = i;
break;
}
}
if (currentIndex % 2 == 0) {
nextIndex = currentIndex + 1;
} else {
nextIndex = currentIndex - 1;
}
const char* nextValue = alarmDescriptions[nextIndex];
// cout << row << endl;
// cout << col << endl;
lv_table_set_cell_value(obj, row, col, nextValue);
tap_is_triggered = true;
cout << "triggered Row" <<triggeredrow << endl;
// Invoke the bit_table_handler to update the HTML table
// httpd_req_t *get_req = httpd_req_from_sockfd(httpd_ws_get_fd(req->handle));
// handle_ws_req_2(get_req);
// handle_ws_req_2(req);
// WHERE I WANT THE SERVER TO GET THE DATA FROM
}
else{
cout<< "row is past 3000, meaning it is probably 65535, thus an invalid input"<< endl;
return;
}
// sendMessage(rowId);
}
}