diff --git a/bsp/inc/bsp_bmp390.h b/bsp/inc/bsp_bmp390.h index 787ac44..5a7fef7 100644 --- a/bsp/inc/bsp_bmp390.h +++ b/bsp/inc/bsp_bmp390.h @@ -13,6 +13,13 @@ #define CHECK_EVT_START (0x0001 << 0) #define MOTOR_STOP_EVT (0x0001 << 1) +#define AUTO_CLOSE_CHECK_EVT (0x0001 << 2) +#define AUTO_CLOSE_TIMEOUT_EVT (0x0001 << 3) + +#define AUTO_CLOSE_NO_FLOW_THRESHOLD 30 +#define AUTO_CLOSE_CHECK_INTERVAL_MS (5 * 60 * 1000) +#define AUTO_CLOSE_CHECK_COUNT 6 +#define AUTO_CLOSE_TOTAL_TIME_MS (30 * 60 * 1000) void PRESS_LowPower(void); @@ -117,5 +124,9 @@ void bmp3_delay_us(uint32_t period, void *intf_ptr); */ void bmp3_check_rslt(const char api_name[], int8_t rslt); +// 新增延时关阀功能相关函数声明 +uint8_t isNoFlowDetected(void); +void startAutoCloseTimer(void); +void stopAutoCloseTimer(void); #endif diff --git a/bsp/inc/bsp_valve.h b/bsp/inc/bsp_valve.h index 04152fb..1455f1f 100644 --- a/bsp/inc/bsp_valve.h +++ b/bsp/inc/bsp_valve.h @@ -33,17 +33,11 @@ extern tmosTaskID vavle_task_id; #define VAVLE_LOW_VBAT_LED_OFF_EVT (0x0001 << 10) // 浣庣數鍘婰ED鍏抽棴浜嬩欢 -// 瀹氭椂鍏抽榾鐩稿叧浜嬩欢 #define VAVLE_TIMER_CLOSE_EVT (0x0001 << 11) // 瀹氭椂鍏抽榾浜嬩欢 -#define VAVLE_TIMER_CLOSE_START_EVT (0x0001 << 12) // 瀹氭椂鍏抽榾寮濮嬩簨浠 #define VALVE_LOW_VBAT_ALARM_PERIOD_MS (1600 * 60 * 10) #define VALVE_DECT_PERIOD_MS (1600 * 60 * 10) -// 瀹氭椂鍏抽榾榛樿鏃堕棿锛堝崟浣嶏細鍒嗛挓锛夛紝鍙互鏍规嵁闇姹傝皟鏁 -#define VALVE_TIMER_CLOSE_DEFAULT_MIN 30 -// 瀹氭椂鍏抽榾鏈澶ф椂闂达紙鍗曚綅锛氬垎閽燂級 -#define VALVE_TIMER_CLOSE_MAX_MIN 360 #define CHARGE_TIME_MS (1500) @@ -64,7 +58,9 @@ typedef enum kCmdCloseVavle, kCmdOpenVavle, kCmdData, - kCmdTimerCloseVavle, // 鏂板瀹氭椂鍏抽榾鍛戒护 + kCmdTimerClose = 0x05, // 璁剧疆瀹氭椂鍏抽榾 + kCmdCancelTimer = 0x06, // 鍙栨秷瀹氭椂鍏抽榾 + kCmdQueryTimer = 0x07, // 鏌ヨ瀹氭椂鍣ㄧ姸鎬 } TeFrameCmd; typedef struct __attribute__((packed)) @@ -114,13 +110,18 @@ typedef struct __attribute__((packed)) uint8_t humi; // 1B 闃闂ㄦ箍搴 %RH int8_t rssi; - // 瀹氭椂鍏抽榾鐘舵佸彉閲 - uint8_t timer_close_enabled; // 瀹氭椂鍏抽榾鏄惁鍚敤 - uint16_t timer_close_min; // 瀹氭椂鍏抽榾鏃堕棿锛堝垎閽燂級 - uint32_t timer_close_start_time; // 瀹氭椂鍏抽榾寮濮嬫椂闂 } TsValveData; extern TsValveData gValveData; +typedef struct __attribute__((packed)) +{ + uint32_t timer_minutes; // 璁剧疆鐨勫畾鏃跺垎閽熸暟锛0琛ㄧず鏈縺娲 + uint32_t start_time; // 瀹氭椂鍣ㄥ惎鍔ㄦ椂鐨勬椂闂存埑 + uint8_t is_active; // 瀹氭椂鍣ㄦ槸鍚︽縺娲 0=鏈縺娲 1=婵娲 +} TsTimerCloseState; + +extern TsTimerCloseState gTimerCloseState; + uint8_t CheckSum(const uint8_t *data, size_t len); void BSP_VAVLE_Init(void); @@ -134,9 +135,7 @@ void BSP_VALVE_Generate_ValveResponse(TsRawFrameData *pRawData, TeFrameCmd cmd, void BSP_VALVE_Generate_UploadData(TsRawFrameData *pRawData); -// 瀹氭椂鍏抽榾鐩稿叧鍑芥暟 -void BSP_VALVE_StartTimerClose(uint16_t close_min); -void BSP_VALVE_StopTimerClose(void); -uint16_t BSP_VALVE_GetTimerCloseRemainMin(void); - +static uint8_t BSP_VALVE_SetTimerClose(uint32_t minutes); +static uint8_t BSP_VALVE_CancelTimerClose(void); +static uint32_t BSP_VALVE_GetRemainingMinutes(void); #endif // ! __BSP_VALVE_H__ diff --git a/bsp/src/bsp_bmp390.c b/bsp/src/bsp_bmp390.c index bdc7174..356b604 100644 --- a/bsp/src/bsp_bmp390.c +++ b/bsp/src/bsp_bmp390.c @@ -65,6 +65,12 @@ typedef struct // 瓒呮俯鐩稿叧 uint8_t over_temp_flag; // 瓒呮俯鏍囧織 + + // 寤舵椂鍏抽榾鐩稿叧 + uint8_t auto_close_enabled; // 寤舵椂鍏抽榾鍔熻兘鏄惁鍚敤 + uint8_t auto_close_check_count; // 鏃犳祦閲忔娴嬫鏁拌鏁 + uint8_t auto_close_active; // 寤舵椂鍏抽榾妫娴嬫槸鍚︽縺娲 + uint32_t auto_close_start_time; // 寤舵椂鍏抽榾寮濮嬫椂闂 } TsValveSafetyStatus; // 瀹夊叏鐘舵佸叏灞鍙橀噺 @@ -868,6 +874,66 @@ uint8_t isWithinTolerance(int32_t ref_value, int32_t measured_value, uint8_t tol } } +/** + * @brief 妫娴嬬閬撴槸鍚︽棤娴侀噺鐘舵 + * + * @return uint8_t 杩斿洖1琛ㄧず鏃犳祦閲忥紝杩斿洖0琛ㄧず鏈夋祦閲 + */ +uint8_t isNoFlowDetected(void) +{ + // 妫娴嬭繘鍑哄彛鍘嬪樊鏄惁鍦ㄦ棤娴侀噺闃堝艰寖鍥村唴 (0卤2Pa) + if (ValveRawData.in_out_press_diff >= -AUTO_CLOSE_NO_FLOW_THRESHOLD && + ValveRawData.in_out_press_diff <= AUTO_CLOSE_NO_FLOW_THRESHOLD) + { + logDebug("No flow detected: pressure diff = %d Pa", ValveRawData.in_out_press_diff); + return 1; // 鏃犳祦閲 + } + + logDebug("Flow detected: pressure diff = %d Pa", ValveRawData.in_out_press_diff); + return 0; // 鏈夋祦閲 +} + +/** + * @brief 鍚姩寤舵椂鍏抽榾鍔熻兘 + */ +void startAutoCloseTimer(void) +{ + if (!valve_safety.auto_close_enabled) + { + valve_safety.auto_close_enabled = 1; + valve_safety.auto_close_active = 1; + valve_safety.auto_close_check_count = 0; + valve_safety.auto_close_start_time = BSP_Get_Tick(); + + logDebug("Auto close timer started"); + + // 寮濮嬬涓娆℃娴嬶紝寤舵椂5鍒嗛挓 + tmos_start_task(check_task_id, AUTO_CLOSE_CHECK_EVT, MS1_TO_SYSTEM_TIME(AUTO_CLOSE_CHECK_INTERVAL_MS)); + + // 璁剧疆35鍒嗛挓瓒呮椂淇濇姢锛30鍒嗛挓+5鍒嗛挓璇樊瀹归檺锛 + tmos_start_task(check_task_id, AUTO_CLOSE_TIMEOUT_EVT, MS1_TO_SYSTEM_TIME(35 * 60 * 1000)); + } +} + +/** + * @brief 鍋滄寤舵椂鍏抽榾鍔熻兘 + */ +void stopAutoCloseTimer(void) +{ + if (valve_safety.auto_close_enabled) + { + valve_safety.auto_close_enabled = 0; + valve_safety.auto_close_active = 0; + valve_safety.auto_close_check_count = 0; + + // 鍋滄瀹氭椂鍣 + tmos_stop_task(check_task_id, AUTO_CLOSE_CHECK_EVT); + tmos_stop_task(check_task_id, AUTO_CLOSE_TIMEOUT_EVT); + + logDebug("Auto close timer stopped"); + } +} + uint16_t Check_ProcessEvent(uint8_t task_id, uint16_t events) { if (events & CHECK_EVT_START) @@ -878,6 +944,17 @@ uint16_t Check_ProcessEvent(uint8_t task_id, uint16_t events) // TODO:鐘舵佸垏鎹笉瀵 if (gValveData.switch_status == kOpened) { + // 寤舵椂鍏抽榾鍔熻兘鍚姩鏉′欢妫娴 + // 鍙湪鏈惎鍔ㄥ欢鏃跺叧闃鏃舵娴嬫棤娴侀噺鐘舵侊紝涓鏃﹀惎鍔ㄥ氨浜ょ粰瀹氭椂妫娴嬪鐞 + if (!valve_safety.auto_close_enabled) + { + if (isNoFlowDetected()) + { + startAutoCloseTimer(); + logDebug("寤舵椂鍏抽榾鍚姩锛氭娴嬪埌鏃犳祦閲忕姸鎬"); + } + } + // 瓒呭帇妫娴 // 鍚庣鍏抽榾锛岃繘姘旂鍘嬪姏瓒呰繃闃堝6200鍏抽榾 // 娴侀噺0.45鏃跺欙紝杩涙皵绔帇鍔涜秴杩囬槇鍊6200鍏抽榾 @@ -889,19 +966,23 @@ uint16_t Check_ProcessEvent(uint8_t task_id, uint16_t events) VALVE_CLOSE(); fault_state = 1; + // 瓒呭帇鍏抽榾鏃跺仠姝㈠欢鏃跺叧闃鍔熻兘 + stopAutoCloseTimer(); tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(CHARGE_TIME_MS)); } // 娆犲帇妫娴 - else if (ValveRawData.in_press <= ValveInfo.low_press) - { - VALVE_CLOSE(); + // else if (ValveRawData.in_press <= ValveInfo.low_press) + // { + // VALVE_CLOSE(); - fault_state = 2; - tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(CHARGE_TIME_MS)); - logError("******************************"); - logError("娆犲帇鍏抽榾"); - } -#if 0 + // fault_state = 2; + // // 娆犲帇鍏抽榾鏃跺仠姝㈠欢鏃跺叧闃鍔熻兘 + // stopAutoCloseTimer(); + // tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(CHARGE_TIME_MS)); + // logError("******************************"); + // logError("娆犲帇鍏抽榾"); + // } +#if 1 // 1銆佽繃娴佽嚜鍔ㄥ叧闂細 // 杩涙皵绔帇鍔2kpa鏃讹紝棰濆畾娴侀噺璋冨埌0.9 // 杩涙皵绔帇鍔涘崌鍒 3kpa宸﹀彸鏃讹紝闃闂ㄤ笉鑳藉叧锛屾祦閲忎笉瓒呰繃1.4 @@ -940,6 +1021,12 @@ uint16_t Check_ProcessEvent(uint8_t task_id, uint16_t events) } else if (gValveData.switch_status == kClosed) { + // 闃闂ㄥ叧闂椂鍋滄寤舵椂鍏抽榾鍔熻兘 + if (valve_safety.auto_close_enabled) + { + stopAutoCloseTimer(); + } + // 鐐圭伀寮闃 // 鐩戞祴ValveRawData_buffer锛屽綋鍓嶆渶鏂扮殑鍘嬪樊鍊煎ぇ浜庝笂涓绉掔殑鍘嬪樊 if (isWithinTolerance(ValveRawData_buffer[2].in_press, ValveRawData_buffer[4].in_press, 50) @@ -954,15 +1041,15 @@ uint16_t Check_ProcessEvent(uint8_t task_id, uint16_t events) VALVE_OPEN(); tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(CHARGE_TIME_MS)); } - else - { - logDebug("鐐圭伀寮闃澶辫触"); - for (int i = 2; i < 5; i++) - { - logDebug("[%d]: in_press = %d; out_press = %d; in_out_press_diff = %d", i - , ValveRawData_buffer[i].in_press, ValveRawData_buffer[i].out_press, ValveRawData_buffer[i].in_out_press_diff); - } - } + // else + // { + // logDebug("鐐圭伀寮闃澶辫触"); + // for (int i = 2; i < 5; i++) + // { + // logDebug("[%d]: in_press = %d; out_press = %d; in_out_press_diff = %d", i + // , ValveRawData_buffer[i].in_press, ValveRawData_buffer[i].out_press, ValveRawData_buffer[i].in_out_press_diff); + // } + // } } // 瓒呮俯鍏抽榾鍔熻兘锛氭娴嬭嚦灏戜袱涓紶鎰熷櫒鐨勬俯搴﹁秴杩囬槇鍊 @@ -984,76 +1071,6 @@ uint16_t Check_ProcessEvent(uint8_t task_id, uint16_t events) motor_flag = 2; // 瑙﹀彂鍏抽榾 } } -#if 0 - // 鐐圭伀寮闃鍔熻兘锛氭娴嬬噧姘旂伓鎵撳紑浣嗛榾闂ㄥ叧闂殑鎯呭喌 - // 褰撻榾闂ㄥ叧闂椂锛屾娴嬬敤姘旈渶姹 - if (gValveData.switch_status == kClosed) - { - // 妫娴嬬敤姘旂壒寰侊細鍑哄彛鍘嬪姏姣斿ぇ姘斿帇浣庝竴瀹氬硷紝琛ㄧず涓嬫父鏈夌敤姘旈渶姹 - // P[1]涓哄嚭鍙e帇鍔涳紝P[2]涓哄ぇ姘斿帇 - if (P[2] > P[1] && (P[2] - P[1] >= SAFETY_GAS_REQUEST_PRESS_DIFF)) - { - valve_safety.auto_open_count++; - logDebug("Auto open detect: %d", valve_safety.auto_open_count); - - // 杩炵画澶氭妫娴嬪埌鐢ㄦ皵闇姹傦紝瑙﹀彂寮闃 - if (valve_safety.auto_open_count >= SAFETY_AUTO_OPEN_THRESHOLD && !valve_safety.auto_open_flag) - { - logDebug("Auto opening valve due to gas usage detected!"); - valve_safety.auto_open_flag = 1; - // 璁剧疆motor_flag涓1锛岃Е鍙戝紑闃 - motor_flag = 1; - } - } - else - { - // 閲嶇疆璁℃暟鍣 - valve_safety.auto_open_count = 0; - } - } - else - { - // 闃闂ㄥ紑鍚姸鎬侊紝閲嶇疆妫娴嬭鏁板拰鏍囧織 - valve_safety.auto_open_count = 0; - valve_safety.auto_open_flag = 0; - } - - // 寰硠婕忓叧闃鍔熻兘锛氭娴嬪井灏忔皵娴佸苟鑷姩鍏抽棴闃闂 - // 褰撻榾闂ㄦ墦寮鏃讹紝妫娴嬪井娉勬紡鎯呭喌 - if (gValveData.switch_status == kOpened) - { - // 妫娴嬪井娉勬紡鐗瑰緛锛氬叆鍙e拰鍑哄彛鍘嬪樊闈炲父灏忥紝浣嗗瓨鍦ㄦ寔缁殑灏忔皵娴 - // P[0]涓哄叆鍙e帇鍔涳紝P[1]涓哄嚭鍙e帇鍔 - // 鍘嬪樊鑼冨洿锛氬ぇ浜0纭繚鏈夋祦閲忥紝浣嗗皬浜庨槇鍊艰〃绀烘祦閲忎綆浜0.3L/min - if (P[0] > P[1] && (P[0] - P[1] > 0) && (P[0] - P[1] < SAFETY_MICRO_LEAK_PRESS_DIFF)) - { - valve_safety.micro_leak_count++; - logDebug("Micro leak detect: %d, pressure diff: %d", valve_safety.micro_leak_count, P[0] - P[1]); - - // 杩炵画澶氭妫娴嬪埌寰硠婕忥紝瑙﹀彂鍏抽榾 - if (valve_safety.micro_leak_count >= SAFETY_MICRO_LEAK_THRESHOLD && !valve_safety.micro_leak_flag) - { - logDebug("Auto closing valve due to micro leak detected!"); - valve_safety.micro_leak_flag = 1; - // 璁剧疆motor_flag涓2锛岃Е鍙戝叧闃 - motor_flag = 2; - } - } - else - { - // 涓嶆弧瓒冲井娉勬紡鏉′欢锛岄噸缃鏁板櫒 - valve_safety.micro_leak_count = 0; - } - } - else - { - // 闃闂ㄥ叧闂姸鎬侊紝閲嶇疆妫娴嬭鏁板拰鏍囧織 - valve_safety.micro_leak_count = 0; - valve_safety.micro_leak_flag = 0; - } -#endif - // 鍏崇伓鍏崇伀 ^P寰堝皬锛屽欢鏃跺悗鍏抽棴 - //^p涓庡ぇ姘斿帇 } // logDebug("motor_flag_end = %d",motor_flag); @@ -1119,6 +1136,74 @@ uint16_t Check_ProcessEvent(uint8_t task_id, uint16_t events) // } return (events ^ MOTOR_STOP_EVT); } + + // 寤舵椂鍏抽榾妫娴嬩簨浠跺鐞 + if (events & AUTO_CLOSE_CHECK_EVT) + { + if (valve_safety.auto_close_enabled && valve_safety.auto_close_active) + { + valve_safety.auto_close_check_count++; + + logDebug("寤舵椂鍏抽榾绗%d娆℃娴 (鍏遍渶6娆)", valve_safety.auto_close_check_count); + + // 妫娴嬪綋鍓嶆槸鍚︿粛涓烘棤娴侀噺鐘舵 + if (isNoFlowDetected()) + { + logDebug("绗%d娆℃娴嬬‘璁ゆ棤娴侀噺 (in_out_press_diff=%d Pa)", + valve_safety.auto_close_check_count, ValveRawData.in_out_press_diff); + + // 濡傛灉宸茬粡妫娴嬩簡6娆★紙30鍒嗛挓锛夛紝鎵ц鍏抽榾 + if (valve_safety.auto_close_check_count >= AUTO_CLOSE_CHECK_COUNT) + { + logError("******************************"); + logError("寤舵椂鍏抽榾:30鍒嗛挓鏃犳祦閲,鑷姩鍏抽棴闃闂"); + logError("6娆℃娴嬪潎纭鏃犳祦閲,鎬昏楁椂: %d ms", BSP_Get_Tick() - valve_safety.auto_close_start_time); + + // 鎵ц鍏抽榾鍔ㄤ綔 + motor_flag = 2; // 瑙﹀彂鍏抽榾 + + // 鍋滄寤舵椂鍏抽榾鍔熻兘 + stopAutoCloseTimer(); + } + else + { + // 缁х画涓嬩竴娆℃娴嬶紝鍐嶇瓑5鍒嗛挓 + logDebug("绗%d娆℃娴嬪畬鎴,5鍒嗛挓鍚庤繘琛岀%d娆℃娴", + valve_safety.auto_close_check_count, valve_safety.auto_close_check_count + 1); + tmos_start_task(check_task_id, AUTO_CLOSE_CHECK_EVT, + MS1_TO_SYSTEM_TIME(AUTO_CLOSE_CHECK_INTERVAL_MS)); + } + } + else + { + // 妫娴嬪埌鏈夋祦閲忥紝鍋滄寤舵椂鍏抽榾 + logDebug("绗%d娆℃娴嬪彂鐜版湁娴侀噺 (in_out_press_diff=%d Pa)锛屽仠姝㈠欢鏃跺叧闃", + valve_safety.auto_close_check_count, ValveRawData.in_out_press_diff); + stopAutoCloseTimer(); + } + } + + return (events ^ AUTO_CLOSE_CHECK_EVT); + } + + // 寤舵椂鍏抽榾瓒呮椂浜嬩欢澶勭悊锛堝鐢ㄥ畨鍏ㄦ満鍒讹級 + if (events & AUTO_CLOSE_TIMEOUT_EVT) + { + if (valve_safety.auto_close_enabled) + { + logError("******************************"); + logError("寤舵椂鍏抽榾锛氳秴鏃朵繚鎶わ紝寮哄埗鍏抽棴闃闂"); + + // 寮哄埗鎵ц鍏抽榾鍔ㄤ綔 + motor_flag = 2; // 瑙﹀彂鍏抽榾 + + // 鍋滄寤舵椂鍏抽榾鍔熻兘 + stopAutoCloseTimer(); + } + + return (events ^ AUTO_CLOSE_TIMEOUT_EVT); + } + return 0; } void Function_Check(void) diff --git a/bsp/src/bsp_valve.c b/bsp/src/bsp_valve.c index 006dc20..eefca7d 100644 --- a/bsp/src/bsp_valve.c +++ b/bsp/src/bsp_valve.c @@ -19,6 +19,7 @@ #include "bsp_adc.h" #include "bsp_led.h" #include "bsp_bmp390.h" +#include "bsp_tim.h" #undef LOG_ENABLE #define LOG_ENABLE 1 @@ -28,6 +29,7 @@ TsValveData gValveData = {0}; TsRawFrameData RelyData; +TsTimerCloseState gTimerCloseState = {0}; tmosTaskID vavle_task_id = INVALID_TASK_ID; @@ -196,17 +198,41 @@ static void VAVLE_Task_ProcessTmosMsg(uint8_t *p_rev_msg) // 澶勭悊TMOS娑堟伅鍑 logDebug("kCmdOpenVavle"); tmos_set_event(vavle_task_id, VAVLE_OPEN_START_EVT); break; - // case kCmdTimerCloseVavle: // 瀹氭椂鍏抽榾鍛戒护 - // logDebug("kCmdTimerCloseVavle"); - // if (HostFrameData->len >= 2) { - // // 瀹氭椂鍙傛暟鍦╠ata涓紝鍓2瀛楄妭琛ㄧず瀹氭椂鏃堕棿锛堝垎閽燂級 - // uint16_t close_min = (HostFrameData->data[0] << 8) | HostFrameData->data[1]; - // BSP_VALVE_StartTimerClose(close_min); - // } else { - // // 浣跨敤榛樿鏃堕棿 - // BSP_VALVE_StartTimerClose(VALVE_TIMER_CLOSE_DEFAULT_MIN); - // } - // break; + case kCmdTimerClose: // 璁剧疆瀹氭椂鍏抽榾鍛戒护 + { + uint8_t result = 0; + if (HostFrameData->len >= 4) { + uint32_t minutes = 0; + tmos_memcpy(&minutes, HostFrameData->data, 4); // 瀹夊叏鐨勫唴瀛樻嫹璐 + result = BSP_VALVE_SetTimerClose(minutes); + logDebug("kCmdTimerClose: %d minutes, result: %d", minutes, result); + } + // 鐢熸垚鍝嶅簲: 鐘舵(1瀛楄妭) + 璁剧疆鐨勫垎閽熸暟(4瀛楄妭) + uint8_t response[5] = {result}; + tmos_memcpy(&response[1], &gTimerCloseState.timer_minutes, 4); // 瀹夊叏鐨勫唴瀛樻嫹璐 + GenerateRawFrame(&RelyData, kCmdTimerClose, response, 5); + tmos_set_event(Peripheral_TaskID, SBP_REPLY_CMD_EVT); + break; + } + case kCmdCancelTimer: // 鍙栨秷瀹氭椂鍏抽榾鍛戒护 + { + uint8_t result = BSP_VALVE_CancelTimerClose(); + logDebug("kCmdCancelTimer: result: %d", result); + BSP_VALVE_Generate_ValveResponse(&RelyData, kCmdCancelTimer, result); + tmos_set_event(Peripheral_TaskID, SBP_REPLY_CMD_EVT); + break; + } + case kCmdQueryTimer: // 鏌ヨ瀹氭椂鍣ㄧ姸鎬佸懡浠 + { + uint32_t remaining = BSP_VALVE_GetRemainingMinutes(); + uint8_t response[5]; + response[0] = gTimerCloseState.is_active; + tmos_memcpy(&response[1], &remaining, 4); // 瀹夊叏鐨勫唴瀛樻嫹璐 + logDebug("kCmdQueryTimer: active: %d, remaining: %d", gTimerCloseState.is_active, remaining); + GenerateRawFrame(&RelyData, kCmdQueryTimer, response, 5); + tmos_set_event(Peripheral_TaskID, SBP_REPLY_CMD_EVT); + break; + } default: logError("Invalid command"); break; @@ -360,26 +386,6 @@ static uint16_t VAVLE_Task_ProcessEvent(uint8_t task_id, uint16_t events) // 闃 tmos_set_event(vavle_task_id, VAVLE_LOW_VBAT_ALARM_EVT); } - // // 妫鏌ュ畾鏃跺叧闃鏄惁鍒版椂闂 - // if (gValveData.timer_close_enabled && gValveData.switch_status == kOpened) - // { - // uint32_t current_time = BSP_Get_Tick(); - // uint32_t elapsed_ms = current_time - gValveData.timer_close_start_time; - // uint32_t timer_ms = (uint32_t)gValveData.timer_close_min * 60 * 1000; - - // if (elapsed_ms >= timer_ms) - // { - // // 鏃堕棿鍒帮紝瑙﹀彂鍏抽榾浜嬩欢 - // tmos_set_event(vavle_task_id, VAVLE_TIMER_CLOSE_EVT); - // } - // else - // { - // // 鍓╀綑鏃堕棿锛堝垎閽燂級 - // uint16_t remain_min = (timer_ms - elapsed_ms) / (60 * 1000); - // logDebug("Timer close remaining: %d minutes", remain_min); - // } - // } - tmos_start_task(vavle_task_id, VAVLE_LOOP_DECT_EVT, MS1_TO_SYSTEM_TIME(VALVE_DECT_PERIOD_MS)); return (events ^ VAVLE_LOOP_DECT_EVT); @@ -414,49 +420,24 @@ static uint16_t VAVLE_Task_ProcessEvent(uint8_t task_id, uint16_t events) // 闃 return (events ^ VAVLE_LOW_VBAT_LED_OFF_EVT); } - // // 瀹氭椂鍏抽榾浜嬩欢澶勭悊 - // if (events & VAVLE_TIMER_CLOSE_EVT) - // { - // logDebug("VAVLE_TIMER_CLOSE_EVT"); - - // // 鍏抽棴瀹氭椂鍣 - // BSP_VALVE_StopTimerClose(); - - // // 濡傛灉闃闂ㄥ綋鍓嶆槸鎵撳紑鐘舵侊紝鍒欒Е鍙戝叧闂 - // if (gValveData.switch_status == kOpened) - // { - // // 瑙﹀彂鍏抽榾浜嬩欢 - // tmos_set_event(vavle_task_id, VAVLE_CLOSE_START_EVT); - // } - - // return (events ^ VAVLE_TIMER_CLOSE_EVT); - // } - - // // 瀹氭椂鍏抽榾寮濮嬩簨浠跺鐞 - // if (events & VAVLE_TIMER_CLOSE_START_EVT) - // { - // logDebug("VAVLE_TIMER_CLOSE_START_EVT"); - - // // 璁板綍寮濮嬫椂闂 - // gValveData.timer_close_start_time = BSP_Get_Tick(); - // gValveData.timer_close_enabled = 1; - - // logDebug("Timer close started: %d minutes", gValveData.timer_close_min); - - // // 闂儊LED鎻愮ず鐢ㄦ埛瀹氭椂宸茶缃紙鍙夛級 - // LED_VALVE_CLOSE; - // DelayMs(200); - // if (gValveData.switch_status == kOpened) - // { - // LED_VALVE_OPEN; - // } - // else - // { - // LED_VALVE_CLOSE; - // } - - // return (events ^ VAVLE_TIMER_CLOSE_START_EVT); - // } + if (events & VAVLE_TIMER_CLOSE_EVT) // 瀹氭椂鍏抽榾浜嬩欢 + { + logInfo("Timer close triggered - auto closing valve"); + + // 娓呴櫎瀹氭椂鍣ㄧ姸鎬 + gTimerCloseState.is_active = 0; + gTimerCloseState.timer_minutes = 0; + + // 瑙﹀彂鍏抽榾鍔ㄤ綔 + tmos_set_event(vavle_task_id, VAVLE_CLOSE_START_EVT); + + // 鍙戦佸畾鏃跺叧闃瀹屾垚閫氱煡 + uint8_t notification = 1; // 瀹氭椂鍏抽榾瀹屾垚 + GenerateRawFrame(&RelyData, kCmdTimerClose, ¬ification, 1); + tmos_set_event(Peripheral_TaskID, SBP_REPLY_CMD_EVT); + + return (events ^ VAVLE_TIMER_CLOSE_EVT); + } return 0; } @@ -465,6 +446,9 @@ void BSP_VAVLE_Init(void) // 闃闂ㄥ垵濮嬪寲鍑芥暟 { vavle_task_id = TMOS_ProcessEventRegister(VAVLE_Task_ProcessEvent); tmos_memset(&gValveData, 0, sizeof(gValveData)); + + // 鍒濆鍖栧畾鏃跺櫒鐘舵 + tmos_memset(&gTimerCloseState, 0, sizeof(gTimerCloseState)); gValveData.temp = -100; gValveData.in_pressure = 0; @@ -474,11 +458,6 @@ void BSP_VAVLE_Init(void) // 闃闂ㄥ垵濮嬪寲鍑芥暟 gValveData.type = kTyq; // 璁剧疆闃闂ㄧ被鍨 gValveData.bat = BSP_ReadVbat(); // 璇诲彇鐢垫睜鐢靛帇 - // 鍒濆鍖栧畾鏃跺叧闃鐘舵佸彉閲 - gValveData.timer_close_enabled = 0; - gValveData.timer_close_min = 0; - gValveData.timer_close_start_time = 0; - BSP_MOTOR_Init(); // 鍒濆鍖栫數鏈 tmos_start_task(vavle_task_id, VAVLE_LOOP_DECT_EVT, MS1_TO_SYSTEM_TIME(1000)); //VALVE_DECT_PERIOD_MS @@ -488,53 +467,72 @@ void BSP_VAVLE_Init(void) // 闃闂ㄥ垵濮嬪寲鍑芥暟 gValveData.switch_status = kClosed; // 鍒濆鍖栭榾闂ㄧ姸鎬佷负鍏抽棴 } -// void BSP_VALVE_StartTimerClose(uint16_t close_min) -// { -// if (close_min == 0) -// { -// // 鍏抽棴瀹氭椂鍣 -// BSP_VALVE_StopTimerClose(); -// return; -// } +static uint8_t BSP_VALVE_SetTimerClose(uint32_t minutes) +{ + // 鍙傛暟楠岃瘉 + if (minutes == 0 || minutes > 1440) { // 1鍒嗛挓鍒24灏忔椂 + logError("Invalid timer minutes: %d", minutes); + return 0; // 璁剧疆澶辫触 + } + + // 妫鏌ュ綋鍓嶉榾闂ㄧ姸鎬侊紝濡傛灉宸茬粡鍏抽棴鍒欎笉闇瑕佸畾鏃跺叧闃 + if (gValveData.switch_status == kClosed) { + logDebug("Valve already closed, timer not needed"); + return 2; // 闃闂ㄥ凡鍏抽棴 + } + + // 鍋滄鐜版湁瀹氭椂鍣紙濡傛灉鏈夛級 + if (gTimerCloseState.is_active) { + tmos_stop_task(vavle_task_id, VAVLE_TIMER_CLOSE_EVT); + logDebug("Stopped existing timer"); + } + + // 璁剧疆鏂扮殑瀹氭椂鍣 + gTimerCloseState.timer_minutes = minutes; + gTimerCloseState.start_time = BSP_Get_Tick(); + gTimerCloseState.is_active = 1; + + // 鍚姩TMOS瀹氭椂鍣 + uint32_t delay_ms = minutes * 60 * 1000; + tmos_start_task(vavle_task_id, VAVLE_TIMER_CLOSE_EVT, MS1_TO_SYSTEM_TIME(delay_ms)); + + logInfo("Timer close set: %d minutes", minutes); + return 1; // 璁剧疆鎴愬姛 +} -// // 闄愬埗鏈澶у畾鏃舵椂闂 -// if (close_min > VALVE_TIMER_CLOSE_MAX_MIN) -// { -// close_min = VALVE_TIMER_CLOSE_MAX_MIN; -// } +static uint8_t BSP_VALVE_CancelTimerClose(void) +{ + if (!gTimerCloseState.is_active) { + logDebug("No active timer to cancel"); + return 0; // 娌℃湁婵娲荤殑瀹氭椂鍣 + } + + // 鍋滄瀹氭椂鍣 + tmos_stop_task(vavle_task_id, VAVLE_TIMER_CLOSE_EVT); + + // 娓呴櫎鐘舵 + gTimerCloseState.is_active = 0; + gTimerCloseState.timer_minutes = 0; + + logInfo("Timer close cancelled"); + return 1; // 鍙栨秷鎴愬姛 +} -// // 璁剧疆瀹氭椂鍙傛暟 -// gValveData.timer_close_min = close_min; +static uint32_t BSP_VALVE_GetRemainingMinutes(void) +{ + if (!gTimerCloseState.is_active) { + return 0; // 娌℃湁婵娲荤殑瀹氭椂鍣 + } + + uint32_t elapsed_ms = BSP_Get_Tick() - gTimerCloseState.start_time; + uint32_t total_ms = gTimerCloseState.timer_minutes * 60 * 1000; + + if (elapsed_ms >= total_ms) { + return 0; // 鏃堕棿宸插埌 + } + + uint32_t remaining_ms = total_ms - elapsed_ms; + return (remaining_ms / 60000) + 1; // 鍚戜笂鍙栨暣鍒板垎閽 +} -// // 瑙﹀彂瀹氭椂寮濮嬩簨浠 -// tmos_set_event(vavle_task_id, VAVLE_TIMER_CLOSE_START_EVT); -// logDebug("BSP_VALVE_StartTimerClose: %d minutes", close_min); -// } - -// void BSP_VALVE_StopTimerClose(void) -// { -// gValveData.timer_close_enabled = 0; -// gValveData.timer_close_min = 0; - -// logDebug("BSP_VALVE_StopTimerClose"); -// } - -// uint16_t BSP_VALVE_GetTimerCloseRemainMin(void) -// { -// if (!gValveData.timer_close_enabled) -// { -// return 0; -// } - -// uint32_t current_time = BSP_Get_Tick(); -// uint32_t elapsed_ms = current_time - gValveData.timer_close_start_time; -// uint32_t timer_ms = (uint32_t)gValveData.timer_close_min * 60 * 1000; - -// if (elapsed_ms >= timer_ms) -// { -// return 0; -// } - -// return (timer_ms - elapsed_ms) / (60 * 1000); -// }