#include "app_manager.h" #include "xtell.h" #include "ui.h" #include "rgb.h" #include "event.h" #include "system.h" #include "database.h" #include "../Drivers/lcd.h" // 外部全局变量引用 extern SystemState current_state; extern u32 captured_addr; extern u8 alarm_sensor_slot; extern volatile u16 ms_tick; extern volatile bit alarm_flash_flag; // 传感器存储列表数据库声明 extern Sensor_Slot xdata sensor_list[16]; // 本地私有变量 static u32 alarm_pulse_timer = 0; // 报警震动波形计数器 static u16 last_run_tick = 0; // 记录上一次轮询的 ticks // 声明本应用的生命周期回调函数 static void AlarmApp_OnStart(void); static void AlarmApp_onRun(void); static void AlarmApp_onClose(void); static EventResult AlarmApp_onEvent(SystemEvent *evt); // 实体化定义警报应用控制块 WristbandApp alarm_app = { APP_ID_ALARM, "Alarm", AlarmApp_OnStart, AlarmApp_onRun, AlarmApp_onClose, AlarmApp_onEvent }; /** * @brief AlarmApp 启动回调 */ static void AlarmApp_OnStart(void) { u8 slot; u8 type = 0; u8 zone = 1; current_state = STATE_ALARM; // 系统切入报警状态 alarm_pulse_timer = 0; // 振动计时器清零 last_run_tick = ms_tick; // 比对查出当前触发警报的传感器在数据库中的属性 if (Check_Sensor_ID(captured_addr, &slot)) { type = sensor_list[slot].type; zone = sensor_list[slot].zone; alarm_sensor_slot = slot; } // 渲染显示报警图文界面 UI_ShowAlarmPage(type, zone); // 首次亮起防区特定的警示色彩,起到区分报警硬件的目的 if (type == 0) RGB_Send(0, 180, 0, 0, 180, 0); // 门磁: 红色 (GRB中R=180,G=0) else if (type == 1) RGB_Send(100, 180, 0, 100, 180, 0); // 红外PIR: 黄色 (G=100, R=180) else if (type == 2) RGB_Send(180, 0, 0, 180, 0, 0); // 烟感: 绿色 (G=180) else if (type == 3) RGB_Send(0, 180, 180, 0, 180, 180); // 气感: 紫色 (R=180, B=180) else RGB_Send(0, 0, 180, 0, 0, 180); // 水浸: 蓝色 (B=180) XTELL_LOG("[AlarmApp] Started. Type="); XTELL_LOG_HEX8(type); XTELL_LOG("\r\n"); } /** * @brief AlarmApp 轮询主回调 * @details 包含同步的灯光爆闪和 Truly AMOLED 像素边框闪烁动效, * 以及马达差异化震动波形逻辑的自处理。 */ static void AlarmApp_onRun(void) { u8 type = sensor_list[alarm_sensor_slot].type; u8 flash_light = (ms_tick / 250) % 2; // 250ms 周期亮灭 u16 tick_diff; // 1. 同步控制 RGB 幻彩灯条进行交替爆闪 if (flash_light) { if (type == 0) RGB_Send(0, 180, 0, 0, 180, 0); else if (type == 1) RGB_Send(100, 180, 0, 100, 180, 0); else if (type == 2) RGB_Send(180, 0, 0, 180, 0, 0); else if (type == 3) RGB_Send(0, 180, 180, 0, 180, 180); else RGB_Send(0, 0, 180, 0, 0, 180); } else { RGB_Send(0, 0, 0, 0, 0, 0); } // 2. 控制 Truly AMOLED 屏幕的最外围红色警告框闪烁效果 if (alarm_flash_flag) { LCD_DrawRectBorder(4, 4, 112, 232, COLOR_RED); LCD_DrawRectBorder(6, 6, 108, 228, COLOR_RED); } else { LCD_DrawRectBorder(4, 4, 112, 232, COLOR_BLACK); LCD_DrawRectBorder(6, 6, 108, 228, COLOR_BLACK); } // 3. 计算时间差并执行马达差异化震动状态机控制 if (ms_tick >= last_run_tick) { tick_diff = ms_tick - last_run_tick; } else { tick_diff = 1000 + ms_tick - last_run_tick; } last_run_tick = ms_tick; alarm_pulse_timer += tick_diff; if (alarm_pulse_timer >= 5000) { alarm_pulse_timer = 0; // 5秒一周期 } if (type == 0) { // 门磁警报波形:单次震动 300ms,停 4700ms if (alarm_pulse_timer < 300) MOTOR = 1; else MOTOR = 0; } else if (type == 1) { // PIR 警报波形:震动 300ms,停 200ms,再震动 300ms,停 4200ms if (alarm_pulse_timer < 300) MOTOR = 1; else if (alarm_pulse_timer >= 300 && alarm_pulse_timer < 500) MOTOR = 0; else if (alarm_pulse_timer >= 500 && alarm_pulse_timer < 800) MOTOR = 1; else MOTOR = 0; } else if (type == 2) { // 烟感警报波形:急促短闪三下 200ms-150ms-200ms-150ms-200ms if (alarm_pulse_timer < 200) MOTOR = 1; else if (alarm_pulse_timer >= 200 && alarm_pulse_timer < 350) MOTOR = 0; else if (alarm_pulse_timer >= 350 && alarm_pulse_timer < 550) MOTOR = 1; else if (alarm_pulse_timer >= 550 && alarm_pulse_timer < 700) MOTOR = 0; else if (alarm_pulse_timer >= 700 && alarm_pulse_timer < 900) MOTOR = 1; else MOTOR = 0; } else if (type == 3) { // 燃气报警波形:快频连续四下 if (alarm_pulse_timer < 200) MOTOR = 1; else if (alarm_pulse_timer >= 200 && alarm_pulse_timer < 300) MOTOR = 0; else if (alarm_pulse_timer >= 300 && alarm_pulse_timer < 500) MOTOR = 1; else if (alarm_pulse_timer >= 500 && alarm_pulse_timer < 600) MOTOR = 0; else if (alarm_pulse_timer >= 600 && alarm_pulse_timer < 800) MOTOR = 1; else if (alarm_pulse_timer >= 800 && alarm_pulse_timer < 900) MOTOR = 0; else if (alarm_pulse_timer >= 900 && alarm_pulse_timer < 1100) MOTOR = 1; else MOTOR = 0; } else if (type == 4) { // 水浸警报波形:慢速双长震波 600ms 和 600ms if (alarm_pulse_timer < 600) MOTOR = 1; else if (alarm_pulse_timer >= 600 && alarm_pulse_timer < 900) MOTOR = 0; else if (alarm_pulse_timer >= 900 && alarm_pulse_timer < 1500) MOTOR = 1; else MOTOR = 0; } else { // 缺省状态默认单次 300ms if (alarm_pulse_timer < 300) MOTOR = 1; else MOTOR = 0; } } /** * @brief AlarmApp 退出清理 */ static void AlarmApp_onClose(void) { RGB_Send(0, 0, 0, 0, 0, 0); // 关闭灯条 MOTOR = 0; // 停震 current_state = STATE_NORMAL; XTELL_LOG("[AlarmApp] Closed\r\n"); } /** * @brief AlarmApp 事件拦截处理 (按任意键退出报警) */ static EventResult AlarmApp_onEvent(SystemEvent *evt) { if (evt->key_event != KEY_EVENT_NONE) { AppManager_SwitchToForeground(&clock_app); // 清除报警并切回时钟待机页 return EVENT_HANDLED; } return EVENT_IGNORED; }