添加 SU03T 自动语音告警功能,更新状态处理以支持温湿度、火灾和门状态的自动告警
This commit is contained in:
150
main/main.cpp
150
main/main.cpp
@@ -61,6 +61,7 @@ static const gpio_num_t kDataPin = GPIO_NUM_14;
|
||||
#define TWDT_NORMAL_TIMEOUT_MS 5000
|
||||
#define TWDT_UI_INIT_TIMEOUT_MS 120000
|
||||
#define DOOR_OPEN_ALARM_SECONDS 60
|
||||
#define SU03T_AUTO_ALERT_INTERVAL_MS (180000U)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -419,6 +420,77 @@ static void su03t_reply_double_value(uint8_t reply_msgno, double value, const ch
|
||||
ESP_LOGI(TAG, "SU03T TX %s msgno=0x%02X value=%.3f", label, reply_msgno, value);
|
||||
}
|
||||
|
||||
static void su03t_reply_code(uint8_t reply_msgno, const char *label)
|
||||
{
|
||||
esp_err_t ret = su03t_send_frame(reply_msgno, NULL, 0);
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
ESP_LOGW(TAG, "SU03T TX %s failed: %s", label, esp_err_to_name(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "SU03T TX %s msgno=0x%02X", label, reply_msgno);
|
||||
}
|
||||
|
||||
static void su03t_auto_alert_task(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
int64_t last_temp_ms = 0;
|
||||
int64_t last_humi_ms = 0;
|
||||
int64_t last_fire_ms = 0;
|
||||
int64_t last_door_ms = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
bool fire_danger = false;
|
||||
bool door_closed = true;
|
||||
float humidity = 0.0f;
|
||||
float temp = 0.0f;
|
||||
float th_hum_h = 70.0f;
|
||||
float th_temp_h = 35.0f;
|
||||
|
||||
if (s_env_data_lock)
|
||||
{
|
||||
xSemaphoreTake(s_env_data_lock, portMAX_DELAY);
|
||||
fire_danger = s_env_data.fire_danger;
|
||||
door_closed = s_env_data.door_closed;
|
||||
humidity = s_env_data.humidity;
|
||||
temp = s_env_data.temp;
|
||||
th_hum_h = s_env_data.th_hum_h;
|
||||
th_temp_h = s_env_data.th_temp_h;
|
||||
xSemaphoreGive(s_env_data_lock);
|
||||
}
|
||||
|
||||
const int64_t now_ms = esp_timer_get_time() / 1000;
|
||||
|
||||
if (temp >= th_temp_h && (now_ms - last_temp_ms) >= SU03T_AUTO_ALERT_INTERVAL_MS)
|
||||
{
|
||||
su03t_reply_double_value(0x10, (double)temp, "auto_temp_high");
|
||||
last_temp_ms = now_ms;
|
||||
}
|
||||
|
||||
if (humidity >= th_hum_h && (now_ms - last_humi_ms) >= SU03T_AUTO_ALERT_INTERVAL_MS)
|
||||
{
|
||||
su03t_reply_double_value(0x11, (double)humidity, "auto_humi_high");
|
||||
last_humi_ms = now_ms;
|
||||
}
|
||||
|
||||
if (fire_danger && (now_ms - last_fire_ms) >= SU03T_AUTO_ALERT_INTERVAL_MS)
|
||||
{
|
||||
su03t_reply_code(0x12, "auto_fire_alarm");
|
||||
last_fire_ms = now_ms;
|
||||
}
|
||||
|
||||
if (!door_closed && (now_ms - last_door_ms) >= SU03T_AUTO_ALERT_INTERVAL_MS)
|
||||
{
|
||||
su03t_reply_code(0x13, "auto_door_open");
|
||||
last_door_ms = now_ms;
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
}
|
||||
|
||||
/* 函数: su03t_rx_callback
|
||||
* 作用: 执行模块内与函数名对应的业务逻辑。
|
||||
* 重点: 关注输入合法性、返回码与并发安全。
|
||||
@@ -442,11 +514,31 @@ static void su03t_rx_callback(const su03t_frame_t *frame, void *user_ctx)
|
||||
double reply_value = 0.0;
|
||||
uint8_t reply_msgno = 0;
|
||||
const char *reply_label = NULL;
|
||||
bool reply_code_only = false;
|
||||
bool need_reply = false;
|
||||
|
||||
bool human_present = false;
|
||||
bool door_closed = true;
|
||||
bool fan_on = false;
|
||||
bool light_on = false;
|
||||
bool cool_on = false;
|
||||
bool hot_on = false;
|
||||
bool auto_mode = false;
|
||||
float co2 = 0.0f;
|
||||
|
||||
if (s_env_data_lock)
|
||||
{
|
||||
xSemaphoreTake(s_env_data_lock, portMAX_DELAY);
|
||||
|
||||
human_present = s_env_data.human_present;
|
||||
door_closed = s_env_data.door_closed;
|
||||
fan_on = s_env_data.fan_on;
|
||||
light_on = s_env_data.light_on;
|
||||
cool_on = s_env_data.cool_on;
|
||||
hot_on = s_env_data.hot_on;
|
||||
auto_mode = s_env_data.auto_mode;
|
||||
co2 = s_env_data.co2;
|
||||
|
||||
switch (cmd->id)
|
||||
{
|
||||
case SU03T_VOICE_CMD_ASK_TEMP:
|
||||
@@ -485,6 +577,54 @@ static void su03t_rx_callback(const su03t_frame_t *frame, void *user_ctx)
|
||||
reply_label = "weight";
|
||||
need_reply = true;
|
||||
break;
|
||||
case SU03T_VOICE_CMD_ASK_HUM:
|
||||
reply_msgno = human_present ? 0x1A : 0x1B;
|
||||
reply_label = human_present ? "human_present" : "human_absent";
|
||||
need_reply = true;
|
||||
reply_code_only = true;
|
||||
break;
|
||||
case SU03T_VOICE_CMD_ASK_DOOR:
|
||||
reply_msgno = door_closed ? 0x0D : 0x0C;
|
||||
reply_label = door_closed ? "door_closed" : "door_open";
|
||||
need_reply = true;
|
||||
reply_code_only = true;
|
||||
break;
|
||||
case SU03T_VOICE_CMD_ASK_FAN:
|
||||
reply_msgno = fan_on ? 0x14 : 0x15;
|
||||
reply_label = fan_on ? "fan_on" : "fan_off";
|
||||
need_reply = true;
|
||||
reply_code_only = true;
|
||||
break;
|
||||
case SU03T_VOICE_CMD_ASK_LIGHT:
|
||||
reply_msgno = light_on ? 0x20 : 0x21;
|
||||
reply_label = light_on ? "light_on" : "light_off";
|
||||
need_reply = true;
|
||||
reply_code_only = true;
|
||||
break;
|
||||
case SU03T_VOICE_CMD_ASK_COOL:
|
||||
reply_msgno = cool_on ? 0x16 : 0x17;
|
||||
reply_label = cool_on ? "cool_on" : "cool_off";
|
||||
need_reply = true;
|
||||
reply_code_only = true;
|
||||
break;
|
||||
case SU03T_VOICE_CMD_ASK_HOT:
|
||||
reply_msgno = hot_on ? 0x18 : 0x19;
|
||||
reply_label = hot_on ? "hot_on" : "hot_off";
|
||||
need_reply = true;
|
||||
reply_code_only = true;
|
||||
break;
|
||||
case SU03T_VOICE_CMD_ASK_CONTROL:
|
||||
reply_msgno = auto_mode ? 0x1C : 0x1D;
|
||||
reply_label = auto_mode ? "mode_auto" : "mode_manual";
|
||||
need_reply = true;
|
||||
reply_code_only = true;
|
||||
break;
|
||||
case SU03T_VOICE_CMD_ASK_RICE:
|
||||
reply_msgno = (co2 >= CO2_SPOILAGE_THRESHOLD_PPM) ? 0x1F : 0x1E;
|
||||
reply_label = (co2 >= CO2_SPOILAGE_THRESHOLD_PPM) ? "rice_spoilage" : "rice_good";
|
||||
need_reply = true;
|
||||
reply_code_only = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -492,9 +632,16 @@ static void su03t_rx_callback(const su03t_frame_t *frame, void *user_ctx)
|
||||
}
|
||||
|
||||
if (need_reply)
|
||||
{
|
||||
if (reply_code_only)
|
||||
{
|
||||
su03t_reply_code(reply_msgno, reply_label);
|
||||
}
|
||||
else
|
||||
{
|
||||
su03t_reply_double_value(reply_msgno, reply_value, reply_label);
|
||||
}
|
||||
}
|
||||
|
||||
su03t_voice_handle_frame(frame);
|
||||
}
|
||||
@@ -922,6 +1069,9 @@ extern "C" void app_main(void)
|
||||
// 独立任务:继电器状态同步到 UI
|
||||
xTaskCreate(relay_status_task, "relay_status_task", 4096, NULL, 5, NULL);
|
||||
|
||||
// 独立任务:SU03T 自动语音告警(默认 3 分钟节流)
|
||||
xTaskCreate(su03t_auto_alert_task, "su03t_auto_alert", 4096, NULL, 5, NULL);
|
||||
|
||||
// 独立任务:MQTT 定时发布传感器数据
|
||||
xTaskCreate(mqtt_publish_task, "mqtt_publish_task", 4096 * 2, NULL, 5, NULL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user