#include "board.h" #include "stat.h" #include "rtc_run.h" #include "param.h" #include "alarm.h" #include "tdc_tof.h" #include "eeprom.h" #include "app_nb.h" #include "bill.h" static rtc_run_t yesterday_max_flow_rate_time; // 昨天最高流量时间 static double yesterday_max_flow_rate = 0.0f; // 昨天最高流量 static rtc_run_t today_max_flow_rate_time; // 今天最高流量时间 static double today_max_flow_rate = 0.0f; // 今天最高流量 static double large_flow_cum = 0.0f; static double leak_flow_cum = 0.0f; static double cnti_flow_cum = 0.0f; static uint32_t BwFlowCnt = 0; extern float BwFlowThres; // void SetStatFlow(double flow_rate) //{ // rtc_run_t *rr; // // if (flow_rate > today_max_flow_rate) // { // today_max_flow_rate = flow_rate; // get_rtc_run(&rr); // memcpy(&today_max_flow_rate_time, rr, sizeof(rtc_run_t)); // } // large_flow_cum += flow_rate; // leak_flow_cum += flow_rate; // cnti_flow_cum += flow_rate; // if (flow_rate < BwFlowThres) // { // BwFlowCnt++; // } // else // { // if (BwFlowCnt > 0) // { // BwFlowCnt--; // } // } //} /** * @brief 流量统计与累积处理函数,在tdc_flow_itf中调用 * @param flow_rate 当前瞬时流量 (ml/s) * @note 该函数负责:更新当日最大流量、流量累积、小流量计数 */ void SetStatFlow(double flow_rate) { rtc_run_t *rr; // RTC 时间结构体指针 // ====================== 1. 更新当日最大瞬时流量 ====================== // 如果当前流量 > 已记录的当日最大流量,则更新最大值和发生时间 if (flow_rate > today_max_flow_rate) { today_max_flow_rate = flow_rate; // 更新最大流量值 get_rtc_run(&rr); // 获取当前系统RTC时间 // 保存最大流量发生的时间点 memcpy(&today_max_flow_rate_time, rr, sizeof(rtc_run_t)); } // ====================== 2. 各类流量累积计算 ====================== large_flow_cum = flow_rate; // 大流量监测累积量 leak_flow_cum = flow_rate; // 漏水监测累积量 cnti_flow_cum = flow_rate; // 持续流量异常监测累积量 // ====================== 3. 小流量(小流量/始动流量)计数 ====================== // 当前流量 < 小流量阈值 → 小流量持续计数+1 if (flow_rate < BwFlowThres) { BwFlowCnt++; } // 流量恢复正常 → 小流量计数递减(防抖/平滑处理) else { if (BwFlowCnt > 0) { BwFlowCnt--; } } } // void ClrStatFlow(void) { // yesterday_max_flow_rate = 0.0f; // memset(&yesterday_max_flow_rate_time, 0, sizeof(rtc_run_t)); // today_max_flow_rate = 0.0f; // memset(&today_max_flow_rate_time, 0, sizeof(rtc_run_t)); // large_flow_cum = 0.0f; // leak_flow_cum = 0.0f; // cnti_flow_cum = 0.0f; // } // double get_max_flow_rate(void) { // return yesterday_max_flow_rate * 0.000001f * 3600; // } // void clr_max_flow_rate(void) { // yesterday_max_flow_rate = today_max_flow_rate; // memcpy(&yesterday_max_flow_rate_time, &today_max_flow_rate_time, sizeof(rtc_run_t)); // today_max_flow_rate = 0.0f; // } // void get_max_flow_rate_time(rtc_run_t **rr) { // *rr = &yesterday_max_flow_rate_time; // } // void bw_flow_monitor(void) { // if (alarm_status(ERR_BW_FLOW)) { // if (BwFlowCnt == 0) { // Alarm(ERR_BW_FLOW, 0, 0); // } // } else { // if (BwFlowCnt >= 60) { // Alarm(ERR_BW_FLOW, 1, BwFlowCnt); // } // } // } /** * @brief 清空所有流量统计数据(初始化/重置) */ void ClrStatFlow(void) { // 昨日/今日峰值流量清零 yesterday_max_flow_rate = 0.0f; memset(&yesterday_max_flow_rate_time, 0, sizeof(rtc_run_t)); today_max_flow_rate = 0.0f; memset(&today_max_flow_rate_time, 0, sizeof(rtc_run_t)); // 各类流量累积量清零 large_flow_cum = 0.0f; leak_flow_cum = 0.0f; cnti_flow_cum = 0.0f; } /** * @brief 获取昨日最大流量(单位转换后) * @return 转换后流量值 */ double get_max_flow_rate(void) { // 单位转换:原始值 → 标准流量单位 return yesterday_max_flow_rate * 0.000001f * 3600.0f; } /** * @brief 每日零点切换峰值流量(今日→昨日,今日清零) */ void clr_max_flow_rate(void) { // 今日峰值移动到昨日 yesterday_max_flow_rate = today_max_flow_rate; memcpy(&yesterday_max_flow_rate_time, &today_max_flow_rate_time, sizeof(rtc_run_t)); memset(&today_max_flow_rate_time, 0, sizeof(rtc_run_t)); // wxl2026-7-22 // 今日峰值清零 today_max_flow_rate = 0.0f; } void clr_max_flow_rate_all(void) { memset(&yesterday_max_flow_rate_time, 0, sizeof(rtc_run_t)); memset(&today_max_flow_rate_time, 0, sizeof(rtc_run_t)); yesterday_max_flow_rate = 0; today_max_flow_rate = 0; } /** * @brief 获取昨日最大流量发生的时间 * @param rr 二级指针,用于返回时间结构体地址 */ void get_max_flow_rate_time(rtc_run_t **rr) { if (rr != NULL) // 防二级指针空指针 { *rr = &yesterday_max_flow_rate_time; } } /** * @brief 反向计量监测,每1秒调用1次 * @note 连续小流量达到60次(1分钟)触发报警,计数归0时恢复 */ void bw_flow_monitor(void) { // 已报警:计数为0则恢复报警 if (alarm_status(ERR_BW_FLOW)) { if (BwFlowCnt == 0) { Alarm(ERR_BW_FLOW, 0, 0); } } // 未报警:计数≥60触发报警 else { if (BwFlowCnt >= 60) { Alarm(ERR_BW_FLOW, 1, BwFlowCnt); } } } // void high_water_temp_monitor(void) { // static uint16_t high_temp_up_cnt = 0; // static uint16_t high_temp_down_cnt = 0; // Param_t *param; // uint16_t temp = (uint16_t)(WaterTemp * 10); //unit: 0.1 celsius degree // GetParam(¶m); // if (alarm_status(ERR_HIGH_TEMP)) { // if (temp <= (param->high_temp_alarm_thres)) { // high_temp_down_cnt++; // if (high_temp_down_cnt >= 3) { // Alarm(ERR_HIGH_TEMP, 0, temp); // high_temp_down_cnt = 0; // } // } else { // high_temp_down_cnt = 0; // } // } else { // if (temp > (param->high_temp_alarm_thres)) { // high_temp_up_cnt++; // if (high_temp_up_cnt >= 3) { // Alarm(ERR_HIGH_TEMP, 1, temp); // high_temp_up_cnt = 0; // } // } else { // high_temp_up_cnt = 0; // } // } //} // void low_water_temp_monitor(void) { // static uint16_t low_temp_up_cnt = 0; // static uint16_t low_temp_down_cnt = 0; // Param_t *param; // uint16_t temp = (uint16_t)(WaterTemp * 10); //unit: 0.1 celsius degree // GetParam(¶m); // if (alarm_status(ERR_LOW_TEMP)) { // if (temp >= (param->low_temp_alarm_thres)) { // low_temp_up_cnt++; // if (low_temp_up_cnt >= 3) { // Alarm(ERR_LOW_TEMP, 0, temp); // low_temp_up_cnt = 0; // } // } else { // low_temp_up_cnt = 0; // } // } else { // if (temp < (param->low_temp_alarm_thres)) { // low_temp_down_cnt++; // if (low_temp_down_cnt >= 3) { // Alarm(ERR_LOW_TEMP, 1, temp); // low_temp_down_cnt = 0; // } // } else { // low_temp_down_cnt = 0; // } // } //} /** * @brief 高温报警监测(每秒调用1次) * 规则:连续3秒超过阈值 → 报警;连续3秒低于阈值 → 恢复 */ void high_water_temp_monitor(void) { if (StartUp < 10) return; // wxl2026-5-18 static uint16_t alarm_confirm_cnt = 0; // 报警确认计数 static uint16_t recover_confirm_cnt = 0; // 恢复确认计数 Param_t *param = NULL; uint16_t current_temp; // 单位:0.1℃ if (StartUp < 10) return; // wxl2026-5-18 GetParam(¶m); if (param->high_temp_alarm_thres == 0 || WaterTemp > 100.0f || WaterTemp < 0.0f) // wxl2026-5-18 温度不在范围不判别 { alarm_confirm_cnt = 0; if (alarm_status(ERR_HIGH_TEMP)) // temp err or temp high warning disabled, clear flag { Alarm(ERR_HIGH_TEMP, 0, 0); } return; } // 获取参数 & 温度采样 current_temp = (uint16_t)(WaterTemp * 10); // 已报警状态:判断恢复条件(连续3次 ≤ 阈值) if (alarm_status(ERR_HIGH_TEMP)) { if (current_temp <= param->high_temp_alarm_thres) { if (++recover_confirm_cnt >= 3) { Alarm(ERR_HIGH_TEMP, 0, (uint32_t)current_temp); recover_confirm_cnt = 0; } } else { recover_confirm_cnt = 0; // 不满足,清零 } } // 未报警:判断触发条件(连续3次 > 阈值) else { if (current_temp > param->high_temp_alarm_thres) { if (++alarm_confirm_cnt >= 3) { Alarm(ERR_HIGH_TEMP, 1, (uint32_t)current_temp); alarm_confirm_cnt = 0; } } else { alarm_confirm_cnt = 0; // 不满足,清零 } } } /** * @brief 低温报警监测(每秒调用1次) * 规则:连续3秒低于阈值 → 报警;连续3秒高于阈值 → 恢复 */ void low_water_temp_monitor(void) { static uint16_t alarm_confirm_cnt = 0; // 报警确认计数 static uint16_t recover_confirm_cnt = 0; // 恢复确认计数 Param_t *param = NULL; uint16_t current_temp; // 单位:0.1℃ if (StartUp < 10) return; // wxl2026-5-18 GetParam(¶m); if (param->low_temp_alarm_thres == 0 || WaterTemp > 100.0f || WaterTemp < 0.0f) // wxl2026-5-18 温度不在范围不判别 { alarm_confirm_cnt = 0; if (alarm_status(ERR_LOW_TEMP)) // temp err or temp low warning disabled,clear warn flag { Alarm(ERR_LOW_TEMP, 0, 0); } return; } // 获取参数 & 温度采样 current_temp = (uint16_t)(WaterTemp * 10); // 已报警状态:判断恢复条件(连续3次 ≥ 阈值) if (alarm_status(ERR_LOW_TEMP)) { if (current_temp >= param->low_temp_alarm_thres) { if (++recover_confirm_cnt >= 3) { Alarm(ERR_LOW_TEMP, 0, (uint32_t)current_temp); recover_confirm_cnt = 0; } } else { recover_confirm_cnt = 0; } } // 未报警:判断触发条件(连续3次 < 阈值) else { if (current_temp < param->low_temp_alarm_thres) { if (++alarm_confirm_cnt >= 3) { Alarm(ERR_LOW_TEMP, 1, (uint32_t)current_temp); alarm_confirm_cnt = 0; } } else { alarm_confirm_cnt = 0; } } } // void large_flow_monitor(void) { // static uint32_t large_flow_cnt = 0; // Param_t *param; // uint32_t cnti_moni_time; // uint32_t large_flow; // GetParam(¶m); // if (param->large_flow_alarm_thres == 0 || // param->large_flow_cnti_moni_time == 0) { // return; // } // large_flow_cnt++; // cnti_moni_time = param->large_flow_cnti_moni_time * 60; // if (large_flow_cnt < cnti_moni_time) { // return; // } // large_flow = (uint32_t)(large_flow_cum * 0.0001); //unit: 0.01m^3 // if (alarm_status(ERR_LARGE_FLOW)) { // if (large_flow < param->large_flow_alarm_thres) { // Alarm(ERR_LARGE_FLOW, 0, large_flow); // } // } else { // if (large_flow >= param->large_flow_alarm_thres) { // Alarm(ERR_LARGE_FLOW, 1, large_flow_cnt); // } // } // large_flow_cnt = 0; // large_flow_cum = 0.0f; //} /** * @brief 大流量连续监测(每秒调用1次) * @功能 流量连续超过阈值 ≥ 设定分钟数,才报警;低于阈值立即清零计时 * @参数 large_flow_cnti_moni_time 单位:分钟 */ void large_flow_monitor(void) { static uint32_t large_flow_continuous_sec = 0; // 连续超阈值计时(秒) Param_t *param = NULL; double flow_current; // 当前流量ml/s uint32_t alarm_threshold_sec; // 报警阈值(转换成秒) if (StartUp < 10) return; // wxl2026-5-18 GetParam(¶m); double large_flow_alarm_thres = param->large_flow_alarm_thres; // m^3/hX100 large_flow_alarm_thres = large_flow_alarm_thres * (10000.0f / 3600.0f); // m^3/hX100 -> ml/s // 阈值/时间未配置,不监测 if (param->large_flow_alarm_thres == 0 || param->large_flow_cnti_moni_time == 0) { large_flow_continuous_sec = 0; if (alarm_status(ERR_LARGE_FLOW)) // if large flow warning disabled ,clear flag { Alarm(ERR_LARGE_FLOW, 0, 0); } return; } // 核心:分钟 → 秒 alarm_threshold_sec = param->large_flow_cnti_moni_time * 60; // 计算当前流量 flow_current = large_flow_cum; // ============== 核心逻辑 ============== // 1. 当前流量 ≥ 阈值:计时+1 if (flow_current >= large_flow_alarm_thres) { // 防止计数溢出 if (large_flow_continuous_sec < alarm_threshold_sec) { large_flow_continuous_sec++; } // 连续超时达到设定分钟 → 触发报警 if (large_flow_continuous_sec >= alarm_threshold_sec) { // 已报警则不重复上报 if (!alarm_status(ERR_LARGE_FLOW)) { Alarm(ERR_LARGE_FLOW, 1, (uint32_t)flow_current); } } } // 2. 流量 < 阈值:立即清零计时(中断连续状态) else { large_flow_continuous_sec = 0; // 已报警则恢复 if (alarm_status(ERR_LARGE_FLOW)) { Alarm(ERR_LARGE_FLOW, 0, (uint32_t)flow_current); } } } // void cnti_flow_monitor(void) { // static uint32_t cnti_flow_cnt = 0; // static uint32_t cnti_prev_flow_cum = 0; // Param_t *param; // uint32_t cnti_moni_time; // uint32_t cnti_flow; // GetParam(¶m); // if (param->cnti_flow_cnti_moni_time == 0) { // return; // } // cnti_flow_cnt++; // cnti_moni_time = param->cnti_flow_cnti_moni_time * 60; // if (cnti_flow_cnt < cnti_moni_time) { // return; // } // cnti_flow = (uint32_t)(cnti_flow_cum * 0.0001); //unit: 0.01m^3 // if (alarm_status(ERR_CNTI_FLOW)) { // if (cnti_flow < param->large_flow_alarm_thres // || (cnti_prev_flow_cum > 0 // && cnti_flow < (cnti_prev_flow_cum * 12 / 10) // && cnti_flow > (cnti_prev_flow_cum * 8 / 10))) { // Alarm(ERR_CNTI_FLOW, 0, cnti_flow); // } // } else { // if (cnti_flow >= param->large_flow_alarm_thres // && cnti_prev_flow_cum > 0 // && (cnti_flow >= (cnti_prev_flow_cum * 12 / 10) // || cnti_flow <= (cnti_prev_flow_cum * 8 / 10))) { // Alarm(ERR_CNTI_FLOW, 1, cnti_flow); // } // } // cnti_prev_flow_cum = cnti_flow; // cnti_flow_cum = 0.0f; // cnti_flow_cnt = 0; //} /** * @brief 持续流量异常监测 * @call 每秒调用1次 * @rule 流量异常持续 >= 设定分钟数 → 报警 * @异常条件: * 1. 流量 >= 阈值 * 2. 相比上周期波动 > ±20% */ void cnti_flow_monitor(void) { static uint32_t abnormal_second_cnt = 0; // 异常持续秒数 static uint32_t last_period_flow = 0; // 上一周期基准流量 Param_t *param = NULL; double current_flow; // 当前流量 0.01m? uint8_t is_abnormal = 0; if (StartUp < 10) return; // wxl2026-5-18 GetParam(¶m); // 未开启监测 if (param->cnti_flow_cnti_moni_time == 0) { abnormal_second_cnt = 0; if (alarm_status(ERR_CNTI_FLOW)) { Alarm(ERR_CNTI_FLOW, 0, 0); } return; } // 当前周期流量 // current_flow = (uint32_t)(cnti_flow_cum * 0.0001f); current_flow = cnti_flow_cum; // ==================== 异常判断 ==================== // 条件1:超过流量阈值 // 条件2:与上周期相比波动 > ±20% (突增 ≥120% 或 突降 ≤80%) if (current_flow > 0 && last_period_flow > 0) { if (current_flow <= last_period_flow * 12 / 10 && current_flow >= last_period_flow * 8 / 10) { is_abnormal = 1; } } // ==================== 持续异常计时 ==================== if (is_abnormal) { abnormal_second_cnt++; // 每秒 +1 // 持续时间 >= 设定分钟 → 报警 if (abnormal_second_cnt >= param->cnti_flow_cnti_moni_time * 60) { if (!alarm_status(ERR_CNTI_FLOW)) { Alarm(ERR_CNTI_FLOW, 1, (uint32_t)current_flow); } abnormal_second_cnt = param->cnti_flow_cnti_moni_time * 60 + 2; } } else { // 恢复正常:清零计时 + 解除报警 if (abnormal_second_cnt > 0) { abnormal_second_cnt = 0; if (alarm_status(ERR_CNTI_FLOW)) { Alarm(ERR_CNTI_FLOW, 0, (uint32_t)current_flow); } } // 正常时更新基准流量 last_period_flow = current_flow; } // 每秒累积量清零 // cnti_flow_cum = 0.0f; } // void leak_flow_monitor(void) { // static uint32_t leak_flow_cnt = 0; // static uint32_t leak_prev_flow_cum = 0; // Param_t *param; // uint32_t cnti_moni_time; // uint32_t leak_flow; // GetParam(¶m); // if (param->leak_flow_alarm_thres == 0 // || param->leak_flow_cnti_moni_time == 0) { // return; // } // leak_flow_cnt++; // cnti_moni_time = param->leak_flow_cnti_moni_time * 60; // if (leak_flow_cnt < cnti_moni_time) { // return; // } // leak_flow = (uint32_t)(leak_flow_cum * 0.0001); //unit: 0.01m^3 // if (alarm_status(ERR_LEAK)) { // if (leak_flow > param->leak_flow_alarm_thres // || (leak_prev_flow_cum > 0 // && leak_flow < (leak_prev_flow_cum * 12 / 10) // && leak_flow > (leak_prev_flow_cum * 8 / 10))) { // Alarm(ERR_LEAK, 0, leak_flow); // } // } else { // if (leak_flow <= param->leak_flow_alarm_thres // && leak_prev_flow_cum > 0 // && (leak_flow >= (leak_prev_flow_cum * 12 / 10) // || leak_flow <= (leak_prev_flow_cum * 8 / 10))) { // Alarm(ERR_LEAK, 1, leak_flow); // } // } // leak_prev_flow_cum = leak_flow; // leak_flow_cum = 0.0f; // leak_flow_cnt = 0; //} /** * @brief 渗漏流量异常监测 * @call 每秒调用1次 * @param leak_flow_cnti_moni_time 单位:分钟 * @rule 满足以下条件并持续 N 分钟 → 报警 * 1. 当前周期渗漏流量 ≤ 报警阈值 * 2. 与上周期流量波动 > ±20%(突增/突降) */ void leak_flow_monitor(void) { static uint32_t abnormal_cont_sec = 0; // 异常持续计时(秒) static uint32_t last_period_leak_flow = 0; // 上周期基准流量(0.01m?) Param_t *param = NULL; double curr_leak_flow; // 当前周期渗漏流量(0.01m?) uint32_t alarm_threshold_sec; // 报警阈值时间(秒) uint8_t is_flow_abnormal = 0; // 异常标志 if (StartUp < 10) return; // wxl2026-5-18 // 获取参数指针 GetParam(¶m); if (param == NULL) return; // 未使能监测(阈值或时间为0) if (param->leak_flow_alarm_thres == 0 || param->leak_flow_cnti_moni_time == 0) { abnormal_cont_sec = 0; if (alarm_status(ERR_LEAK)) { Alarm(ERR_LEAK, 0, 0); } return; } double leak_flow_alarm_thres = param->leak_flow_alarm_thres; // m^3/hX100 leak_flow_alarm_thres = leak_flow_alarm_thres * (10000.0f / 3600.0f); // m^3/hX100 -> ml/s // 转换监测时间:分钟 → 秒 alarm_threshold_sec = param->leak_flow_cnti_moni_time * 60; // 计算当前周期渗漏流量(单位:0.01m?) curr_leak_flow = leak_flow_cum; // ====================== 渗漏异常判断逻辑 ====================== // 异常条件: // 1. 当前流量 ≤ 渗漏阈值 // 2. 存在上周期基准值 // 3. 波动 > ±20% (≥120% 或 ≤80%) if (curr_leak_flow <= leak_flow_alarm_thres && last_period_leak_flow > 0) { if (curr_leak_flow <= last_period_leak_flow * 12 / 10 && curr_leak_flow >= last_period_leak_flow * 8 / 10) { is_flow_abnormal = 1; } } // ====================== 持续异常计时 & 报警 ====================== if (is_flow_abnormal) { // 异常状态:累计秒数 if (abnormal_cont_sec < alarm_threshold_sec) { abnormal_cont_sec++; } // 达到持续时间 → 触发报警 if (abnormal_cont_sec >= alarm_threshold_sec) { if (!alarm_status(ERR_LEAK)) { Alarm(ERR_LEAK, 1, (uint32_t)curr_leak_flow); } } } else { // 恢复正常:清零计时 if (abnormal_cont_sec > 0) { abnormal_cont_sec = 0; // 已报警则恢复 if (alarm_status(ERR_LEAK)) { Alarm(ERR_LEAK, 0, (uint32_t)curr_leak_flow); } } // 正常状态:更新基准流量 last_period_leak_flow = curr_leak_flow; } // 周期累积量清零 // leak_flow_cum = 0.0f; } /** * @brief 电池电压监控,1分钟调用1次 * @param 无 * @retval 无 */ void low_power_monitor(void) { static uint16_t low_pwr_up_cnt = 0; static uint16_t low_pwr_down_cnt = 0; uint16_t VbatMin; // mv VbatMin = McuVbat; // > McuVTxbat ? McuVTxbat : McuVbat;// wxl2026-6-2 if (alarm_status(ERR_LOW_POWER)) { // modified by yuewei 20260407 // if (McuVbat >= 3025) if ((McuVbat >= 3025) /* && (McuVTxbat >= 3025)*/) //// wxl2026-6-2 { low_pwr_up_cnt++; if (low_pwr_up_cnt >= 1) // 3->1,modified by yuewei 20260407 { Alarm(ERR_LOW_POWER, 0, (uint32_t)VbatMin); low_pwr_up_cnt = 0; } } else { low_pwr_up_cnt = 0; } } else { // modified by yuewei 20260407 // if (McuVbat <= 2975) if (McuVbat <= 2975 /*|| McuVTxbat <= 2975*/) // only one vol port in small meter wxl2026-6-2 { low_pwr_down_cnt++; // ADC every 10 minutes monitor 5 day = 6 * 24 * 5 = 720 if (low_pwr_down_cnt >= 5) // 720->5, modified by yuewei 20260407 { Alarm(ERR_LOW_POWER, 1, (uint32_t)VbatMin); low_pwr_down_cnt = 0; } } else { if (low_pwr_down_cnt > 0) { low_pwr_down_cnt--; } } } } // void tdc_rw_err_monitor(void) { // uint32_t err_cnt = get_tdc_rw_err_cnt(); // // if (alarm_status(ERR_TOF_SPI_RW)) { // if (err_cnt == 0) { // Alarm(ERR_TOF_SPI_RW, 0, 0); // } // } else { // if (err_cnt >= 30) { // Alarm(ERR_TOF_SPI_RW, 1, err_cnt); // } // } // } // void eeprom_rw_err_monitor(void) { // uint32_t err_cnt = get_eeprom_rw_err_cnt(); // // if (alarm_status(ERR_MEMORY)) { // if (err_cnt == 0) { // Alarm(ERR_MEMORY, 0, 0); // } // } else { // if (err_cnt >= 30) { // Alarm(ERR_MEMORY, 1, err_cnt); // } // } // } /** * @brief TDC SPI 读写错误监测 * @rule 错误计数 ≥30 报警,错误计数=0 恢复 */ void tdc_rw_err_monitor(void) { if (StartUp < 10) return; // wxl2026-5-18 uint32_t err_cnt = get_tdc_rw_err_cnt(); if (alarm_status(ERR_TOF_SPI_RW)) { // 已报警:错误清零则恢复 if (err_cnt == 0) { Alarm(ERR_TOF_SPI_RW, 0, 0); } } else { // 未报警:错误数≥30 触发报警 if (err_cnt >= 30) { Alarm(ERR_TOF_SPI_RW, 1, err_cnt); } } } /** * @brief EEPROM 读写错误监测 * @rule 错误计数 ≥30 报警,错误计数=0 恢复 */ void eeprom_rw_err_monitor(void) { if (StartUp < 10) return; // wxl2026-5-18 uint32_t err_cnt = get_eeprom_rw_err_cnt(); if (alarm_status(ERR_MEMORY)) { // 已报警:错误清零则恢复 if (err_cnt == 0) { Alarm(ERR_MEMORY, 0, 0); } } else { // 未报警:错误数≥30 触发报警 if (err_cnt >= 30) { Alarm(ERR_MEMORY, 1, err_cnt); } } } // void water_flow_monitor(void) { // bw_flow_monitor(); // large_flow_monitor(); // cnti_flow_monitor(); // leak_flow_monitor(); // // high_water_temp_monitor(); // low_water_temp_monitor(); // tdc_rw_err_monitor(); // eeprom_rw_err_monitor(); //} /** * @brief 监测入口(未使用) * @detail 统一调度所有流量、温度、通信故障监测 */ void water_flow_monitor(void) { // 1. 流量类监测 bw_flow_monitor(); // 小流量/始动流量监测 large_flow_monitor(); // 大流量持续监测 cnti_flow_monitor(); // 持续流量异常监测 leak_flow_monitor(); // 渗漏流量监测 // 2. 温度类监测 high_water_temp_monitor(); // 高温报警监测 low_water_temp_monitor(); // 低温报警监测 // 3. 硬件通信故障监测 tdc_rw_err_monitor(); // TDC SPI 读写错误监测 eeprom_rw_err_monitor(); // EEPROM 读写错误监测 } // void high_pressure_monitor(void) { // static uint16_t high_press_up_cnt = 0; // static uint16_t high_press_down_cnt = 0; // Param_t *param; // GetParam(¶m); // //add by yuewei 20260407 // if (param->pressure_sensor != 1) //no pressure sensor or not set // { // return; // } // if (param->high_press_alarm_thres == 0) { // return; // } // uint16_t pressure = (uint16_t)(WaterPressure * 100); //unit: 0.01MPa // if (alarm_status(ERR_HIGH_PRESSURE)) { // if (pressure <= (param->high_press_alarm_thres - 2)) { // high_press_down_cnt++; // if (high_press_down_cnt >= 3) { // Alarm(ERR_HIGH_PRESSURE, 0, pressure); // high_press_down_cnt = 0; // } // } else { // high_press_down_cnt = 0; // } // } else { // if (pressure >= (param->high_press_alarm_thres + 2)) { // high_press_up_cnt++; // if (high_press_up_cnt >= 3) { // Alarm(ERR_HIGH_PRESSURE, 1, pressure); // high_press_up_cnt = 0; // } // } else { // high_press_up_cnt = 0; // } // } //} // void low_pressure_monitor(void) { // static uint16_t low_press_up_cnt = 0; // static uint16_t low_press_down_cnt = 0; // Param_t *param; // GetParam(¶m); // //add by yuewei 20260407 // if (param->pressure_sensor != 1) //no pressure sensor or not set // { // return; // } // if (param->low_press_alarm_thres == 0) { // return; // } // uint16_t pressure = (uint16_t)(WaterPressure * 100); //unit: 0.01MPa // // if (alarm_status(ERR_LOW_PRESSURE)) { // if (pressure >= (param->low_press_alarm_thres + 2)) { // low_press_up_cnt++; // if (low_press_up_cnt >= 3) { // Alarm(ERR_LOW_PRESSURE, 0, pressure); // low_press_up_cnt = 0; // } // } else { // low_press_up_cnt = 0; // } // // } else { // if (pressure <= (param->low_press_alarm_thres - 2)) { // low_press_down_cnt++; // if (low_press_down_cnt >= 3) { // Alarm(ERR_LOW_PRESSURE, 1, pressure); // low_press_down_cnt = 0; // } // } else { // low_press_down_cnt = 0; // } // } //} /** * @brief 高压报警监测(每1分钟调用1次) * 规则:压力连续3次 ≥ 阈值+2 → 报警 * 报警后连续3次 ≤ 阈值-2 → 恢复 * 仅当压力传感器使能时(param->pressure_sensor == 1)生效 * 单位:0.01MPa */ void high_pressure_monitor(void) { static uint16_t alarm_confirm_cnt = 0; // 报警连续确认计数 static uint16_t recover_confirm_cnt = 0; // 恢复连续确认计数 Param_t *param = NULL; uint16_t curr_pressure; // 当前压力 GetParam(¶m); if (param == NULL) return; // 未安装压力传感器 / 未使能 if (param->pressure_sensor != 1) { alarm_confirm_cnt = 0; recover_confirm_cnt = 0; return; } // 阈值未配置 if (param->high_press_alarm_thres == 0) { return; } // 计算当前压力 0.01MPa curr_pressure = (uint16_t)(WaterPressure * 100); // 已报警 → 判断恢复条件(连续3次 ≤ 阈值-2) if (alarm_status(ERR_HIGH_PRESSURE)) { if (curr_pressure <= (param->high_press_alarm_thres - 2)) { if (++recover_confirm_cnt >= 3) { Alarm(ERR_HIGH_PRESSURE, 0, curr_pressure); recover_confirm_cnt = 0; } } else { recover_confirm_cnt = 0; } } // 未报警 → 判断触发条件(连续3次 ≥ 阈值+2) else { if (curr_pressure >= (param->high_press_alarm_thres + 2)) { if (++alarm_confirm_cnt >= 3) { Alarm(ERR_HIGH_PRESSURE, 1, curr_pressure); alarm_confirm_cnt = 0; } } else { alarm_confirm_cnt = 0; } } } /** * @brief 低压报警监测(每1分钟调用1次) * 规则:压力连续3次 ≤ 阈值-2 → 报警 * 报警后连续3次 ≥ 阈值+2 → 恢复 * 仅当压力传感器使能时(param->pressure_sensor == 1)生效 * 单位:0.01MPa */ void low_pressure_monitor(void) { static uint16_t alarm_confirm_cnt = 0; // 报警连续确认计数 static uint16_t recover_confirm_cnt = 0; // 恢复连续确认计数 Param_t *param = NULL; uint16_t curr_pressure; // 当前压力 GetParam(¶m); if (param == NULL) return; // 未安装压力传感器 / 未使能 if (param->pressure_sensor != 1) { alarm_confirm_cnt = 0; recover_confirm_cnt = 0; return; } // 阈值未配置 if (param->low_press_alarm_thres == 0) { return; } // 计算当前压力 0.01MPa curr_pressure = (uint16_t)(WaterPressure * 100); // 已报警 → 判断恢复条件(连续3次 ≥ 阈值+2) if (alarm_status(ERR_LOW_PRESSURE)) { if (curr_pressure >= (param->low_press_alarm_thres + 2)) { if (++recover_confirm_cnt >= 3) { Alarm(ERR_LOW_PRESSURE, 0, curr_pressure); recover_confirm_cnt = 0; } } else { recover_confirm_cnt = 0; } } // 未报警 → 判断触发条件(连续3次 ≤ 阈值-2) else { if (curr_pressure <= (param->low_press_alarm_thres - 2)) { if (++alarm_confirm_cnt >= 3) { Alarm(ERR_LOW_PRESSURE, 1, curr_pressure); alarm_confirm_cnt = 0; } } else { alarm_confirm_cnt = 0; } } } // void pressure_monitor(void) { // high_pressure_monitor(); // low_pressure_monitor(); // } /** * @brief 水压监测总入口(未使用) * @detail 统一调度高压、低压报警监测 */ void pressure_monitor(void) { // 水压上下限监测 high_pressure_monitor(); // 高压报警监测 low_pressure_monitor(); // 低压报警监测 }