From 93bc94a0eed09df78c9d156765c80a7d087e661f Mon Sep 17 00:00:00 2001 From: Wang Beihong Date: Wed, 22 Apr 2026 19:54:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=97=A8=E6=9C=AA=E5=85=B3?= =?UTF-8?q?=E8=B6=85=E6=97=B6=E5=91=8A=E8=AD=A6=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=8A=B6=E6=80=81=E7=BB=93=E6=9E=84=E4=BB=A5?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=97=A8=E7=A3=81=E5=91=8A=E8=AD=A6=E5=92=8C?= =?UTF-8?q?=E5=BC=80=E9=97=A8=E6=97=B6=E9=95=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ main/main.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 44e2f16..7467aec 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,8 @@ | fire_danger | boolean | true/false | 火焰危险判定 | | human_present | boolean | true/false | 人体存在状态 | | door_closed | boolean | true/false | 门磁状态(true=关门) | +| door_alarm | boolean | true/false | 门未关超时告警状态 | +| door_open_seconds | number | s | 当前连续开门时长 | | fan_on | boolean | true/false | 风扇继电器状态 | | light_on | boolean | true/false | 照明继电器状态 | | cool_on | boolean | true/false | 制冷继电器状态 | @@ -207,6 +209,7 @@ - th_temp_l = 15.0 - th_hum_h = 70.0 - th_gas_h = 20.0 +- door_open_alarm_seconds = 60 ### 7. 下发示例 @@ -239,3 +242,4 @@ - 命令下发后,以上报主题 agri/env/data 的最新数据作为状态确认 - 建议上位机做字段容错:新增字段应忽略,缺失字段使用默认显示 - 当前固件未提供独立 ACK 主题,建议在上位机侧做超时重发策略 +- 门磁告警建议以 door_alarm 与 door_open_seconds 组合显示,door_alarm=true 时突出提示用户 diff --git a/main/main.cpp b/main/main.cpp index 0933e13..0b3d3be 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -59,6 +59,7 @@ static const gpio_num_t kDataPin = GPIO_NUM_14; #define HX711_STABLE_SAMPLES 15 #define TWDT_NORMAL_TIMEOUT_MS 5000 #define TWDT_UI_INIT_TIMEOUT_MS 120000 +#define DOOR_OPEN_ALARM_SECONDS 60 typedef struct { @@ -75,6 +76,8 @@ typedef struct bool fire_danger; bool human_present; bool door_closed; + bool door_alarm; + uint32_t door_open_seconds; bool fan_on; bool light_on; bool cool_on; @@ -263,19 +266,53 @@ static void ui_init_task(void *arg) static void status_task(void *arg) { (void)arg; + TickType_t door_open_start_ticks = 0; + bool door_alarm_active = false; + for (;;) { human_door_state_t io_state{}; if (human_door_read(&io_state) == ESP_OK) { 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) { xSemaphoreTake(s_env_data_lock, portMAX_DELAY); s_env_data.human_present = io_state.human_present; 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); } } @@ -568,6 +605,8 @@ static void mqtt_publish_task(void *arg) cJSON_AddBoolToObject(root, "fire_danger", local_data.fire_danger); cJSON_AddBoolToObject(root, "human_present", local_data.human_present); 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, "light_on", local_data.light_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_hum_h = 70.0f; // 湿度高于 70% 通风 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 ESP_ERROR_CHECK(wifi_connect_init());