feat: 添加土壤和光照阈值控制,优化状态上报逻辑
This commit is contained in:
10
README.md
10
README.md
@@ -95,7 +95,11 @@ idf.py -p /dev/ttyACM0 flash monitor
|
||||
"lux": "40",
|
||||
"pump": "on",
|
||||
"light": "off",
|
||||
"mode": "auto"
|
||||
"mode": "auto",
|
||||
"soil_on": 35.0,
|
||||
"soil_off": 45.0,
|
||||
"light_on": 100.0,
|
||||
"light_off": 350.0
|
||||
}
|
||||
```
|
||||
|
||||
@@ -103,6 +107,10 @@ idf.py -p /dev/ttyACM0 flash monitor
|
||||
- `pump`:`on/off`
|
||||
- `light`:`on/off`
|
||||
- `mode`:`auto/manual`
|
||||
- `soil_on`:土壤湿度低阈值(低于该值自动开泵)
|
||||
- `soil_off`:土壤湿度高阈值(高于该值自动关泵)
|
||||
- `light_on`:光照低阈值(低于该值自动开灯)
|
||||
- `light_off`:光照高阈值(高于该值自动关灯)
|
||||
|
||||
### WEX -> ESP32
|
||||
|
||||
|
||||
135
main/main.c
135
main/main.c
@@ -83,6 +83,42 @@ static bool s_light_on = false;
|
||||
// 全局变量:自动控制模式使能(true=自动,false=手动)
|
||||
static bool s_auto_control_enabled = true;
|
||||
|
||||
/**
|
||||
* @brief 发布当前完整状态快照(含阈值)到传感器主题
|
||||
*/
|
||||
static esp_err_t publish_telemetry_snapshot(void)
|
||||
{
|
||||
if (!mqtt_control_is_connected())
|
||||
{
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
auto_ctrl_thresholds_t thresholds = {0};
|
||||
auto_ctrl_thresholds_get(&thresholds);
|
||||
|
||||
char telemetry_payload[256] = {0};
|
||||
int len = snprintf(telemetry_payload,
|
||||
sizeof(telemetry_payload),
|
||||
"{\"temp\":\"%s\",\"hum\":\"%s\",\"soil\":\"%s\",\"lux\":\"%s\",\"pump\":\"%s\",\"light\":\"%s\",\"mode\":\"%s\",\"soil_on\":%.1f,\"soil_off\":%.1f,\"light_on\":%.1f,\"light_off\":%.1f}",
|
||||
s_air_temp,
|
||||
s_air_hum,
|
||||
s_soil,
|
||||
s_lux,
|
||||
s_pump_on ? "on" : "off",
|
||||
s_light_on ? "on" : "off",
|
||||
s_auto_control_enabled ? "auto" : "manual",
|
||||
thresholds.pump_on_soil_below_pct,
|
||||
thresholds.pump_off_soil_above_pct,
|
||||
thresholds.light_on_lux_below,
|
||||
thresholds.light_off_lux_above);
|
||||
if (len <= 0 || len >= (int)sizeof(telemetry_payload))
|
||||
{
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
return mqtt_control_publish_sensor(telemetry_payload, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MQTT 控制命令处理函数
|
||||
*
|
||||
@@ -96,6 +132,8 @@ static esp_err_t mqtt_control_command_handler(const mqtt_control_command_t *cmd,
|
||||
{
|
||||
(void)user_ctx;
|
||||
ESP_RETURN_ON_FALSE(cmd != NULL, ESP_ERR_INVALID_ARG, TAG, "cmd is null");
|
||||
esp_err_t final_ret = ESP_OK;
|
||||
bool has_any_control = cmd->has_mode || cmd->has_thresholds || cmd->has_pump || cmd->has_light;
|
||||
|
||||
// 处理模式切换命令
|
||||
if (cmd->has_mode)
|
||||
@@ -107,37 +145,73 @@ static esp_err_t mqtt_control_command_handler(const mqtt_control_command_t *cmd,
|
||||
// 处理阈值更新命令
|
||||
if (cmd->has_thresholds)
|
||||
{
|
||||
ESP_RETURN_ON_ERROR(auto_ctrl_thresholds_set_values(cmd->soil_on_pct,
|
||||
cmd->soil_off_pct,
|
||||
cmd->light_on_lux,
|
||||
cmd->light_off_lux),
|
||||
TAG,
|
||||
"设置阈值失败");
|
||||
ESP_LOGI(TAG,
|
||||
"MQTT 更新阈值: soil_on=%.1f soil_off=%.1f light_on=%.1f light_off=%.1f",
|
||||
cmd->soil_on_pct,
|
||||
cmd->soil_off_pct,
|
||||
cmd->light_on_lux,
|
||||
cmd->light_off_lux);
|
||||
esp_err_t ret = auto_ctrl_thresholds_set_values(cmd->soil_on_pct,
|
||||
cmd->soil_off_pct,
|
||||
cmd->light_on_lux,
|
||||
cmd->light_off_lux);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
ESP_LOGI(TAG,
|
||||
"MQTT 更新阈值: soil_on=%.1f soil_off=%.1f light_on=%.1f light_off=%.1f",
|
||||
cmd->soil_on_pct,
|
||||
cmd->soil_off_pct,
|
||||
cmd->light_on_lux,
|
||||
cmd->light_off_lux);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "设置阈值失败: %s", esp_err_to_name(ret));
|
||||
final_ret = ret;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理水泵控制命令
|
||||
if (cmd->has_pump)
|
||||
{
|
||||
ESP_RETURN_ON_ERROR(io_device_control_set_pump(cmd->pump_on), TAG, "MQTT 控制水泵失败");
|
||||
s_pump_on = cmd->pump_on;
|
||||
ESP_LOGI(TAG, "MQTT 控制水泵: %s", cmd->pump_on ? "on" : "off");
|
||||
esp_err_t ret = io_device_control_set_pump(cmd->pump_on);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
s_pump_on = cmd->pump_on;
|
||||
ESP_LOGI(TAG, "MQTT 控制水泵: %s", cmd->pump_on ? "on" : "off");
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "MQTT 控制水泵失败: %s", esp_err_to_name(ret));
|
||||
final_ret = ret;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理补光灯控制命令
|
||||
if (cmd->has_light)
|
||||
{
|
||||
ESP_RETURN_ON_ERROR(io_device_control_set_light(cmd->light_on), TAG, "MQTT 控制补光灯失败");
|
||||
s_light_on = cmd->light_on;
|
||||
ESP_LOGI(TAG, "MQTT 控制补光灯: %s", cmd->light_on ? "on" : "off");
|
||||
esp_err_t ret = io_device_control_set_light(cmd->light_on);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
s_light_on = cmd->light_on;
|
||||
ESP_LOGI(TAG, "MQTT 控制补光灯: %s", cmd->light_on ? "on" : "off");
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "MQTT 控制补光灯失败: %s", esp_err_to_name(ret));
|
||||
final_ret = ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
// 任何控制指令处理后都立即上报最新状态(含阈值)作为回复。
|
||||
if (has_any_control)
|
||||
{
|
||||
esp_err_t pub_ret = publish_telemetry_snapshot();
|
||||
if (pub_ret != ESP_OK)
|
||||
{
|
||||
ESP_LOGW(TAG, "控制后立即上报失败: %s", esp_err_to_name(pub_ret));
|
||||
if (final_ret == ESP_OK)
|
||||
{
|
||||
final_ret = pub_ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return final_ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -542,27 +616,10 @@ void app_main(void)
|
||||
if (telemetry_elapsed_ms >= BOTANY_MQTT_TELEMETRY_PERIOD_MS)
|
||||
{
|
||||
telemetry_elapsed_ms = 0;
|
||||
if (mqtt_control_is_connected())
|
||||
esp_err_t pub_ret = publish_telemetry_snapshot();
|
||||
if (pub_ret != ESP_OK && pub_ret != ESP_ERR_INVALID_STATE)
|
||||
{
|
||||
char telemetry_payload[128] = {0};
|
||||
int len = snprintf(telemetry_payload,
|
||||
sizeof(telemetry_payload),
|
||||
"{\"temp\":\"%s\",\"hum\":\"%s\",\"soil\":\"%s\",\"lux\":\"%s\",\"pump\":\"%s\",\"light\":\"%s\",\"mode\":\"%s\"}",
|
||||
s_air_temp,
|
||||
s_air_hum,
|
||||
s_soil,
|
||||
s_lux,
|
||||
s_pump_on ? "on" : "off",
|
||||
s_light_on ? "on" : "off",
|
||||
s_auto_control_enabled ? "auto" : "manual");
|
||||
if (len > 0 && len < (int)sizeof(telemetry_payload))
|
||||
{
|
||||
esp_err_t pub_ret = mqtt_control_publish_sensor(telemetry_payload, 0, 0);
|
||||
if (pub_ret != ESP_OK)
|
||||
{
|
||||
ESP_LOGW(TAG, "传感器上报失败: %s", esp_err_to_name(pub_ret));
|
||||
}
|
||||
}
|
||||
ESP_LOGW(TAG, "周期状态上报失败: %s", esp_err_to_name(pub_ret));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user