CODE¶
Warning
The following code should be based on the code in the release code, which may have been updated.
sensing_command.h¶
/**
* @file sensing_command.h
* @author SHUAIWEN CUI (SHUAIWEN001@e.ntu.edu.sg)
* @brief MQTT remote control command handler for sensing modules
* @version 1.0
* @date 2025-01-XX
* @copyright Copyright (c) 2025
*
* @details
* This module handles MQTT commands for controlling online and offline sensing.
* Command format: SENSE,ONLINE or SENSE,OFFLINE with parameters
*
* Supported commands:
* - SENSE,ONLINE,F=频率,D=持续时间
* - SENSE,ONLINE,STOP
* - SENSE,ONLINE,STATUS
* - SENSE,OFFLINE,F=频率,D=采样时长
* - SENSE,OFFLINE,F=频率,D=采样时长,DL=延迟秒
* - SENSE,OFFLINE,F=频率,D=采样时长,TIME=YYMMDDHHMMSS
* - SENSE,OFFLINE,STOP
* - SENSE,OFFLINE,STATUS
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "node_acc_adxl355.h"
#ifdef __cplusplus
extern "C"
{
#endif
/* ============================================================================
* FUNCTION DECLARATIONS
* ============================================================================ */
/**
* @brief Process MQTT sensing command
* @param command Command string (e.g., "SENSE,ONLINE,F=20,D=60")
* @param command_len Length of command string
* @return ESP_OK on success, error code on failure
* @note This function parses and executes the command, then publishes response via MQTT
*/
esp_err_t sensing_command_process(const char *command, int command_len);
/**
* @brief Initialize sensing command handler
* @return ESP_OK on success, error code on failure
* @note Must be called after MQTT is initialized
*/
esp_err_t sensing_command_init(void);
/**
* @brief Set sensor handle for command handler
* @param handle ADXL355 sensor handle
* @return ESP_OK on success, error code on failure
* @note Must be called before processing commands
*/
esp_err_t sensing_command_set_sensor_handle(adxl355_handle_t *handle);
#ifdef __cplusplus
}
#endif
sensing_command.c¶
The implementation includes:
Key Functions¶
- Command Processing
sensing_command_process(): Main entry point for command processingcommand_processing_task(): FreeRTOS task that processes commands from queuehandle_online_command(): Handles ONLINE sensing commands-
handle_offline_command(): Handles OFFLINE sensing commands -
Parameter Parsing
parse_float_param(): Extracts float parameters from command stringparse_int_param(): Extracts integer parameters from command string-
parse_time_param(): Parses TIME parameter in YYMMDDHHMMSS format -
Task Management
offline_sensing_task_wrapper(): Wrapper task for offline sensing with delay support-
online_sensing_stop_task(): Task to auto-stop online sensing after duration -
Response Handling
send_mqtt_response(): Publishes command response via MQTT
Command Queue Structure¶
#define COMMAND_QUEUE_SIZE 5
#define MAX_COMMAND_LENGTH 256
typedef struct
{
char command[MAX_COMMAND_LENGTH];
int command_len;
} command_queue_item_t;
Initialization Flow¶
esp_err_t sensing_command_init(void)
{
// Create command queue
s_command_queue = xQueueCreate(COMMAND_QUEUE_SIZE, sizeof(command_queue_item_t));
// Create command processing task
BaseType_t ret = xTaskCreate(
command_processing_task,
"cmd_processor",
4096, // Stack size
NULL,
5, // Priority
&s_command_task_handle);
return ret == pdPASS ? ESP_OK : ESP_FAIL;
}
Command Processing Flow¶
- Command received via MQTT callback
- Command queued for processing
- Command processing task dequeues and validates
- Command parsed and routed to appropriate handler
- Response published via MQTT
Parameter Parsing Example¶
static esp_err_t parse_float_param(const char *str, const char *prefix, float *value)
{
char search_str[32];
snprintf(search_str, sizeof(search_str), "%s=", prefix);
const char *pos = strstr(str, search_str);
if (pos == NULL)
{
return ESP_ERR_NOT_FOUND;
}
pos += strlen(search_str);
const char *end = strchr(pos, ',');
if (end == NULL)
{
end = pos + strlen(pos);
}
char value_str[64];
size_t len = end - pos;
if (len >= sizeof(value_str))
{
len = sizeof(value_str) - 1;
}
strncpy(value_str, pos, len);
value_str[len] = '\0';
char *parse_end;
*value = strtof(value_str, &parse_end);
if (parse_end == value_str || *parse_end != '\0')
{
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
Online Command Handler¶
static esp_err_t handle_online_command(const char *cmd)
{
// Check for STOP command
if (strstr(cmd, "STOP") != NULL)
{
esp_err_t ret = online_sensing_stop();
send_mqtt_response(ret == ESP_OK ?
"SENSE,OK,ONLINE,STOPPED" :
"SENSE,ERROR,ONLINE,STOP_FAILED");
return ret;
}
// Check for STATUS command
if (strstr(cmd, "STATUS") != NULL)
{
bool is_running = false;
online_sensing_is_running(&is_running);
online_sensing_config_t config;
online_sensing_get_config(&config);
char resp[128];
snprintf(resp, sizeof(resp), "SENSE,STATUS,ONLINE,RUNNING=%s,F=%.2f",
is_running ? "YES" : "NO", config.sampling_frequency_hz);
send_mqtt_response(resp);
return ESP_OK;
}
// Parse F and D parameters
float freq = 0.0f;
float duration = 0.0f;
if (parse_float_param(cmd, "F", &freq) != ESP_OK)
{
send_mqtt_response("SENSE,ERROR,ONLINE,INVALID_FREQ");
return ESP_ERR_INVALID_ARG;
}
if (parse_float_param(cmd, "D", &duration) != ESP_OK)
{
duration = 0.0f; // Default: continuous
}
// Validate and start online sensing
// ... (implementation details)
}
Offline Command Handler¶
static esp_err_t handle_offline_command(const char *cmd)
{
// Check for STOP command
if (strstr(cmd, "STOP") != NULL)
{
bool is_running = false;
offline_sensing_is_running(&is_running);
if (is_running)
{
esp_err_t ret = offline_sensing_stop();
send_mqtt_response(ret == ESP_OK ?
"SENSE,OK,OFFLINE,STOPPED" :
"SENSE,ERROR,OFFLINE,STOP_FAILED");
return ret;
}
// ... (error handling)
}
// Parse parameters (F, D, DL, TIME)
// ... (implementation details)
// Create task for offline sensing with delay support
// ... (task creation)
}
Usage Example¶
// Initialize command handler
esp_err_t ret = sensing_command_init();
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to initialize command handler");
return;
}
// Set sensor handle
ret = sensing_command_set_sensor_handle(&adxl355_handle);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to set sensor handle");
return;
}
// In MQTT message callback
void mqtt_message_callback(esp_mqtt_event_handle_t event)
{
if (strncmp(event->data, "SENSE,", 6) == 0)
{
sensing_command_process(event->data, event->data_len);
}
}