添加门未关超时告警功能,更新状态结构以支持门磁告警和开门时长

This commit is contained in:
Wang Beihong
2026-04-22 19:54:39 +08:00
parent e446b7515c
commit 93bc94a0ee
2 changed files with 46 additions and 1 deletions

View File

@@ -117,6 +117,8 @@
| fire_danger | boolean | true/false | 火焰危险判定 | | fire_danger | boolean | true/false | 火焰危险判定 |
| human_present | boolean | true/false | 人体存在状态 | | human_present | boolean | true/false | 人体存在状态 |
| door_closed | boolean | true/false | 门磁状态true=关门) | | door_closed | boolean | true/false | 门磁状态true=关门) |
| door_alarm | boolean | true/false | 门未关超时告警状态 |
| door_open_seconds | number | s | 当前连续开门时长 |
| fan_on | boolean | true/false | 风扇继电器状态 | | fan_on | boolean | true/false | 风扇继电器状态 |
| light_on | boolean | true/false | 照明继电器状态 | | light_on | boolean | true/false | 照明继电器状态 |
| cool_on | boolean | true/false | 制冷继电器状态 | | cool_on | boolean | true/false | 制冷继电器状态 |
@@ -207,6 +209,7 @@
- th_temp_l = 15.0 - th_temp_l = 15.0
- th_hum_h = 70.0 - th_hum_h = 70.0
- th_gas_h = 20.0 - th_gas_h = 20.0
- door_open_alarm_seconds = 60
### 7. 下发示例 ### 7. 下发示例
@@ -239,3 +242,4 @@
- 命令下发后,以上报主题 agri/env/data 的最新数据作为状态确认 - 命令下发后,以上报主题 agri/env/data 的最新数据作为状态确认
- 建议上位机做字段容错:新增字段应忽略,缺失字段使用默认显示 - 建议上位机做字段容错:新增字段应忽略,缺失字段使用默认显示
- 当前固件未提供独立 ACK 主题,建议在上位机侧做超时重发策略 - 当前固件未提供独立 ACK 主题,建议在上位机侧做超时重发策略
- 门磁告警建议以 door_alarm 与 door_open_seconds 组合显示door_alarm=true 时突出提示用户

View File

@@ -59,6 +59,7 @@ static const gpio_num_t kDataPin = GPIO_NUM_14;
#define HX711_STABLE_SAMPLES 15 #define HX711_STABLE_SAMPLES 15
#define TWDT_NORMAL_TIMEOUT_MS 5000 #define TWDT_NORMAL_TIMEOUT_MS 5000
#define TWDT_UI_INIT_TIMEOUT_MS 120000 #define TWDT_UI_INIT_TIMEOUT_MS 120000
#define DOOR_OPEN_ALARM_SECONDS 60
typedef struct typedef struct
{ {
@@ -75,6 +76,8 @@ typedef struct
bool fire_danger; bool fire_danger;
bool human_present; bool human_present;
bool door_closed; bool door_closed;
bool door_alarm;
uint32_t door_open_seconds;
bool fan_on; bool fan_on;
bool light_on; bool light_on;
bool cool_on; bool cool_on;
@@ -263,19 +266,53 @@ static void ui_init_task(void *arg)
static void status_task(void *arg) static void status_task(void *arg)
{ {
(void)arg; (void)arg;
TickType_t door_open_start_ticks = 0;
bool door_alarm_active = false;
for (;;) for (;;)
{ {
human_door_state_t io_state{}; human_door_state_t io_state{};
if (human_door_read(&io_state) == ESP_OK) if (human_door_read(&io_state) == ESP_OK)
{ {
set_var_hum_status(io_state.human_present ? "有人" : "无人"); set_var_hum_status(io_state.human_present ? "有人" : "无人");
set_var_door_status(io_state.door_closed ? "关闭" : "开启");
uint32_t door_open_seconds = 0;
if (io_state.door_closed)
{
door_open_start_ticks = 0;
door_alarm_active = false;
set_var_door_status("关闭");
}
else
{
if (door_open_start_ticks == 0)
{
door_open_start_ticks = xTaskGetTickCount();
}
door_open_seconds = (uint32_t)((xTaskGetTickCount() - door_open_start_ticks) * portTICK_PERIOD_MS / 1000U);
if (door_open_seconds >= DOOR_OPEN_ALARM_SECONDS)
{
if (!door_alarm_active)
{
ESP_LOGW(TAG, "Door left open too long: %us", (unsigned)door_open_seconds);
}
door_alarm_active = true;
set_var_door_status("未关告警");
}
else
{
set_var_door_status("开启");
}
}
if (s_env_data_lock) if (s_env_data_lock)
{ {
xSemaphoreTake(s_env_data_lock, portMAX_DELAY); xSemaphoreTake(s_env_data_lock, portMAX_DELAY);
s_env_data.human_present = io_state.human_present; s_env_data.human_present = io_state.human_present;
s_env_data.door_closed = io_state.door_closed; s_env_data.door_closed = io_state.door_closed;
s_env_data.door_alarm = door_alarm_active;
s_env_data.door_open_seconds = door_open_seconds;
xSemaphoreGive(s_env_data_lock); xSemaphoreGive(s_env_data_lock);
} }
} }
@@ -568,6 +605,8 @@ static void mqtt_publish_task(void *arg)
cJSON_AddBoolToObject(root, "fire_danger", local_data.fire_danger); cJSON_AddBoolToObject(root, "fire_danger", local_data.fire_danger);
cJSON_AddBoolToObject(root, "human_present", local_data.human_present); cJSON_AddBoolToObject(root, "human_present", local_data.human_present);
cJSON_AddBoolToObject(root, "door_closed", local_data.door_closed); cJSON_AddBoolToObject(root, "door_closed", local_data.door_closed);
cJSON_AddBoolToObject(root, "door_alarm", local_data.door_alarm);
cJSON_AddNumberToObject(root, "door_open_seconds", local_data.door_open_seconds);
cJSON_AddBoolToObject(root, "fan_on", local_data.fan_on); cJSON_AddBoolToObject(root, "fan_on", local_data.fan_on);
cJSON_AddBoolToObject(root, "light_on", local_data.light_on); cJSON_AddBoolToObject(root, "light_on", local_data.light_on);
cJSON_AddBoolToObject(root, "cool_on", local_data.cool_on); cJSON_AddBoolToObject(root, "cool_on", local_data.cool_on);
@@ -619,6 +658,8 @@ extern "C" void app_main(void)
s_env_data.th_temp_l = 15.0f; // 低于 15度 制热 s_env_data.th_temp_l = 15.0f; // 低于 15度 制热
s_env_data.th_hum_h = 70.0f; // 湿度高于 70% 通风 s_env_data.th_hum_h = 70.0f; // 湿度高于 70% 通风
s_env_data.th_gas_h = 20.0f; // 气体浓度高于 20% 通风 s_env_data.th_gas_h = 20.0f; // 气体浓度高于 20% 通风
s_env_data.door_alarm = false;
s_env_data.door_open_seconds = 0;
// 1. 初始化 Wi-Fi // 1. 初始化 Wi-Fi
ESP_ERROR_CHECK(wifi_connect_init()); ESP_ERROR_CHECK(wifi_connect_init());