/**
 * @file output_control.c
 * @brief BLDC风机+冷热比例阀温控器输出控制模块
 * @details 实现自动、制冷、制热、通风四种工作模式的温度控制逻辑
 */

#include "output_control.h"
#include "parameter.h"
#include "i2c_mcu.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <string.h>
#include <math.h>

static const char *TAG = "OUTPUT_CTRL";

// 温控状态全局变量
static temp_control_state_t g_temp_state = {0};

// 输出值缓存，用于避免重复的I2C写入
static struct {
    uint8_t last_ao1_output;     // 上次AO1输出值
    uint8_t last_ao2_output;     // 上次AO2输出值  
    uint8_t last_ao3_output;     // 上次AO3输出值
    uint8_t last_k4_state;       // 上次K4继电器状态
    uint8_t last_k5_state;       // 上次K5继电器状态
    bool initialized;            // 缓存是否已初始化
} output_cache = {0};

// 内部函数声明
static esp_err_t update_temperature_values(void);
static esp_err_t calculate_fan_output(uint8_t *ao1_output);
static esp_err_t calculate_heat_valve_output(uint8_t *ao2_output);
static esp_err_t calculate_cool_valve_output(uint8_t *ao3_output);
static esp_err_t apply_outputs(uint8_t ao1, uint8_t ao2, uint8_t ao3);
static esp_err_t apply_outputs_optimized(uint8_t ao1, uint8_t ao2, uint8_t ao3, bool force_update);
static uint8_t get_fan_speed_percentage(uint16_t speed);
static uint8_t get_auto_fan_speed_percentage(void);
static esp_err_t roomcard_energy_saving_control(void);

// 外部函数声明（来自i2c_mcu.c）
//extern float get_temp_disp(void);
extern float get_celsius_temp(void);
extern int get_fault_code(void);  // 获取故障码
extern int i2c_mcu_relay_K4(uint8_t on);
extern int i2c_mcu_relay_K5(uint8_t on);

// 内部辅助函数
static uint32_t get_system_time_seconds(void);
static bool check_valve_start_delay(uint32_t valve_close_time, uint16_t delay_minutes);
static bool check_valve_interval(uint32_t last_change_time, uint8_t last_output, uint8_t new_output);

static bool is_system_power_on_ready(void);

// 检查掉电记忆参数并联动控制开关机状态
static void check_power_state(void) {
    if (GetPower_off_memory() == 0) {
        // 掉电后上电保持OFF
        if (GetOnOffState() != 0) {
            SetOnOffState(0); // 强制写为OFF
            ESP_LOGI(TAG, "Power_off_memory=0，强制开关机状态为OFF");
        }
    }
    // Power_off_memory=1，无需处理
}

/**
 * @brief 初始化温控输出模块
 */
esp_err_t output_control_init(void)
{
    // 检查掉电记忆参数与开关机状态联动
    check_power_state();
    
    // 初始化状态结构体
    memset(&g_temp_state, 0, sizeof(temp_control_state_t));
    
    // 读取初始参数
    g_temp_state.work_mode = GetWork_mode();
    g_temp_state.fan_speed = GetFan_speed();
    
    // 参数兼容性检查：单管路模式不支持自动模式
    // uint16_t pipe_option = GetPipe_option();
    // if (pipe_option == 0 && g_temp_state.work_mode == WORK_MODE_AUTO) {
    //     ESP_LOGW(TAG, "单管路模式不支持自动模式，建议使用制冷(1)或制热(2)模式");
        // 可以选择强制修改为制冷模式，或者仅警告
        // g_temp_state.work_mode = WORK_MODE_COOL;  // 可选：强制改为制冷模式
    // }
    
    // 初始化阀门状态标志
    g_temp_state.heat_valve_opened = false;
    g_temp_state.cool_valve_opened = false;
    
    // 初始化阀门时间控制字段
    uint32_t current_time = get_system_time_seconds();
    g_temp_state.heat_valve_close_time = current_time;
    g_temp_state.cool_valve_close_time = current_time;
    g_temp_state.heat_valve_last_change_time = current_time;
    g_temp_state.cool_valve_last_change_time = current_time;
    g_temp_state.heat_valve_last_output = 0;
    g_temp_state.cool_valve_last_output = 0;
    
    // 初始化风机延迟关闭字段
    g_temp_state.fan_should_stop_time = current_time;
    g_temp_state.fan_delay_stopping = true;     // 此处必须为true，否则系统启动风机输出不一定为0
    
    // 初始化风机状态保持字段
    g_temp_state.fan_was_on = false;  // 初始状态为关闭
    
    // 初始化开关机控制字段
    g_temp_state.onoff_state = GetOnOffState();
    g_temp_state.power_on_time = current_time;
    g_temp_state.power_on_delay_active = false;
    
    // 初始化日志优化字段
    g_temp_state.last_printed_ao1 = 0;
    g_temp_state.last_printed_ao2 = 0;
    g_temp_state.last_printed_ao3 = 0;
    
    // 初始化输出缓存
    output_cache.last_ao1_output = 0;  // 初始化为0，符合系统上电默认状态
    output_cache.last_ao2_output = 0;
    output_cache.last_ao3_output = 0;
    output_cache.last_k4_state = 0;
    output_cache.last_k5_state = 0;
    output_cache.initialized = false;
    
    // 初始化硬件输出为0，避免启动时不必要的硬件操作，AO1替换AO3，AO3不使用
    ESP_LOGI(TAG, "初始化硬件输出 - AO1:0, AO2:0, AO3:0, K3:0, K4:0, K5:0");
    i2c_mcu_ao1(0);
    i2c_mcu_ao2(0);
    //i2c_mcu_ao3(0);
    i2c_mcu_relay_K3(0);
    i2c_mcu_relay_K4(0);
    i2c_mcu_relay_K5(0);
    
    // 标记缓存已初始化，避免后续的强制初始化
    output_cache.initialized = true;
    
    ESP_LOGI(TAG, "温控输出模块初始化完成");
    return ESP_OK;
}

/**
 * @brief 更新温度值和温差计算
 */
static esp_err_t update_temperature_values(void)
{
    // 获取当前温度和设定温度
    g_temp_state.troom = get_celsius_temp();
    
    // 获取设定温度，根据温度单位进行转换
    uint16_t temperature_unit = Gettemperature_unit();
    if (temperature_unit == 1) {
        // 华氏度模式：将华氏度设定温度转换为摄氏度
        float setpoint_fahrenheit = (float)GetSetPoint();
        g_temp_state.tset = (setpoint_fahrenheit - 32.0f) * 5.0f / 9.0f;
    } else {
        // 摄氏度模式：直接使用设定温度
        g_temp_state.tset = (float)GetSetPoint();
    }
    
    // 计算温差
    g_temp_state.delta_t1 = g_temp_state.troom - g_temp_state.tset;     //ΔT1 = Troom - Tset，用于计算制冷温差
    g_temp_state.delta_t2 = g_temp_state.tset - g_temp_state.troom;     //ΔT2 = Tset - Troom，用于计算制热温差
    
    // 更新工作模式和风速档位
    g_temp_state.work_mode = GetWork_mode();
    g_temp_state.fan_speed = GetFan_speed();
    
    return ESP_OK;
}

/**
 * @brief 计算风机输出百分比
 */
static esp_err_t calculate_fan_output_with_valve_states(uint8_t *ao1_output, uint8_t new_ao2, uint8_t new_ao3)
{
    if (!ao1_output) return ESP_ERR_INVALID_ARG;    //检查传入的ao1_output指针是否为空(NULL)，若为空，则返回错误码ESP_ERR_INVALID_ARG
    
    *ao1_output = 0;  // 只有当ao1_output指针不为空时，才将0赋值给*ao1_output，否则不进行任何操作
    
    // 获取风机与阀门联动参数
    uint16_t fan_with_heat_valve = GetFan_state_with_heat_valve();
    uint16_t fan_with_cool_valve = GetFan_state_with_cool_valve();
    
    // 获取风机延迟关闭参数
    uint16_t fan_delay_off = GetFan_delay_off();
    
    // 如果延迟关闭时间为0，默认设置为3秒，避免与阀门同时关闭造成硬件干扰
    if (fan_delay_off == 0) {
        fan_delay_off = 3;
        // ESP_LOGD(TAG, "风机延迟关闭时间为0，默认设置为3秒避免硬件干扰");
    }
    
    // ESP_LOGD(TAG, "风机联动参数 - 热阀联动:%d, 冷阀联动:%d, 延迟关闭:%d秒", fan_with_heat_valve, fan_with_cool_valve, fan_delay_off);
    
    // 根据当前激活状态和联动设置计算风机基础输出
    // 注意：这里不直接处理联锁关闭，联锁关闭通过后面的延迟关闭逻辑处理
    if (g_temp_state.work_mode == WORK_MODE_FAN) {
        // 通风模式：只运行风机，不受阀门联动影响
        *ao1_output = get_fan_speed_percentage(g_temp_state.fan_speed);
    } else if (g_temp_state.cooling_active) {
        // 制冷激活状态
        if (fan_with_cool_valve == 1) {
            // 联动模式：风机输出与冷阀状态关联
            if (new_ao3 > 0) {
                *ao1_output = get_fan_speed_percentage(g_temp_state.fan_speed);
            } else {
                // 冷阀关闭但不立即关闭风机，让延迟关闭逻辑处理
                *ao1_output = get_fan_speed_percentage(g_temp_state.fan_speed);
            }
        } else {
            // 解耦模式：风机独立输出
            *ao1_output = get_fan_speed_percentage(g_temp_state.fan_speed);
        }
    } else if (g_temp_state.heating_active) {
        // 制热激活状态
        if (fan_with_heat_valve == 1) {
            // 联动模式：风机输出与热阀状态关联
            if (new_ao2 > 0) {
                *ao1_output = get_fan_speed_percentage(g_temp_state.fan_speed);
            } else {
                // 热阀关闭但不立即关闭风机，让延迟关闭逻辑处理
                *ao1_output = get_fan_speed_percentage(g_temp_state.fan_speed);
            }
        } else {
            // 解耦模式：风机独立输出
            *ao1_output = get_fan_speed_percentage(g_temp_state.fan_speed);
        }
    } else {
        // 既不制冷也不制热，风机关闭
        *ao1_output = 0;
    }
    
    // 风机延迟关闭功能处理
    // 仅在开机状态且非通风模式下执行延迟关闭逻辑
    if (/*fan_delay_off > 0 &&*/ g_temp_state.onoff_state == 1 && g_temp_state.work_mode != WORK_MODE_FAN) {
        // 根据当前激活状态检查相关阀门的联锁和关闭状态
        bool should_trigger_delay = false;
        
        if (g_temp_state.cooling_active) {
            // 制冷激活：只检查冷阀联锁和状态
            if (fan_with_cool_valve == 1 && new_ao3 == 0) {
                should_trigger_delay = true;
                ESP_LOGD(TAG, "制冷模式：风机与冷阀联锁且冷阀关闭，触发延迟关闭");
            }
        } else if (g_temp_state.heating_active) {
            // 制热激活：只检查热阀联锁和状态
            if (fan_with_heat_valve == 1 && new_ao2 == 0) {
                should_trigger_delay = true;
                ESP_LOGD(TAG, "制热模式：风机与热阀联锁且热阀关闭，触发延迟关闭");
            }
        }
        
        if (should_trigger_delay) {
            // 相关阀门联锁且关闭，启动风机延迟关闭
            if (!g_temp_state.fan_delay_stopping) {
                // 开始延迟关闭
                g_temp_state.fan_delay_stopping = true;
                g_temp_state.fan_should_stop_time = get_system_time_seconds() + fan_delay_off;
                ESP_LOGI(TAG, "联锁模式下相关阀门关闭(AO2:%d%%, AO3:%d%%)，启动风机延迟关闭，延迟时间: %d秒", new_ao2, new_ao3, fan_delay_off);
            }
            
            // 检查延迟时间是否已到
            if (get_system_time_seconds() >= g_temp_state.fan_should_stop_time) {
                // 延迟时间到，关闭风机
                *ao1_output = 0;
                g_temp_state.fan_delay_stopping = true;     // 此处必须为true，否则系统启动风机会反复输出与关闭
            } else {
                // 延迟期间保持风机运行
                *ao1_output = get_fan_speed_percentage(g_temp_state.fan_speed);
                ESP_LOGD(TAG, "联锁模式风机延迟关闭中，剩余时间: %d秒", 
                         (int)(g_temp_state.fan_should_stop_time - get_system_time_seconds()));
            }
        } else {
            // 不需要延迟关闭，清除延迟状态
            if (g_temp_state.fan_delay_stopping) {
                g_temp_state.fan_delay_stopping = false;
                ESP_LOGI(TAG, "延迟关闭条件不满足，取消风机延迟关闭");
            }
        }
    } else {
        // 无延迟关闭功能、关机状态或通风模式，清除延迟状态
        if (g_temp_state.fan_delay_stopping) {
            g_temp_state.fan_delay_stopping = false;
            if (g_temp_state.onoff_state == 0) {
                ESP_LOGD(TAG, "系统关机，清除风机延迟关闭状态");
            } else if (g_temp_state.work_mode == WORK_MODE_FAN) {
                ESP_LOGD(TAG, "通风模式，清除风机延迟关闭状态");
            } else {
                ESP_LOGD(TAG, "无延迟关闭功能，清除风机延迟关闭状态");
            }
        }
    }
    
    return ESP_OK;
}

/*FC 5个继电器状态控制*/
bool k1_state = 0;
bool k1_state_record = 0;
bool K1_state_act = 0;
bool k2_state = 0;
bool k2_state_record = 0;
bool K2_state_act = 0;
bool k3_state = 0;
bool k3_state_record = 0;
bool K3_state_act = 0;
bool k4_state = 0;
bool k4_state_record = 0;
bool K4_state_act = 0;
bool k5_state = 0;
bool k5_state_record = 0;
bool K5_state_act = 0;

static uint8_t fan_state = 0;
static uint8_t fan_state_record = 0;

/*风机状态，仅供UI使用*/
uint8_t fan_state_dis = 0;

esp_timer_handle_t relay_delay_timer = NULL;   
esp_timer_handle_t relay_start_timer = NULL;  

/*继电器开关不能同时执行*/
/*关闭继电器回调*/
void relay_delay_timer_args_callback(void *arg)
{
    printf("relay_delay_timer_args_callback\r\n");
    fan_state_dis = 0;
    k3_state = 0;
    k4_state = 0;
    k5_state = 0;
    esp_timer_stop(relay_delay_timer);
    esp_timer_delete(relay_delay_timer);
    relay_delay_timer = NULL;
}

/*打开继电器回调*/
void relay_start_timer_args_callback(void *arg)
{
    printf("relay_start_timer_args_callback\r\n");
    uint8_t tmp = *(uint8_t *)arg;
    printf("tmp = %d\r\n", tmp); 
    switch(tmp)
    {
        case 1:
        fan_state_dis = 1;
        k3_state = 0;
        k4_state = 0;
        k5_state = 1;
        break;

        case 2:
        fan_state_dis = 2;
        k3_state = 0;
        k4_state = 1;
        k5_state = 0;
        break;

        case 3:
        fan_state_dis = 3;
        k3_state = 1;
        k4_state = 0;
        k5_state = 0;
        break;

        default:
        fan_state_dis = 0;
        break;
    }
    esp_timer_stop(relay_start_timer);
    esp_timer_delete(relay_start_timer);
    relay_start_timer = NULL;
}


/*PIT-7RS-485,风机输出逻辑，与PIT-EC不共用*/
void fan_output_logic(uint8_t new_ao2, uint8_t new_ao3)
{
    // 获取风机与阀门联动参数
    uint16_t fan_with_heat_valve = GetFan_state_with_heat_valve();
    uint16_t fan_with_cool_valve = GetFan_state_with_cool_valve();

    g_temp_state.work_mode = GetWork_mode();
    g_temp_state.fan_speed = GetFan_speed();
    
    // 获取风机延迟关闭参数
    uint16_t fan_delay_off = 3;//GetFan_delay_off();
    
    // 如果延迟关闭时间为0，默认设置为3秒，避免与阀门同时关闭造成硬件干扰
    if (fan_delay_off == 0) {
        fan_delay_off = 3;
        // ESP_LOGD(TAG, "风机延迟关闭时间为0，默认设置为3秒避免硬件干扰");
    }

    float delta_t;
    /*计算风速*/
    switch(g_temp_state.fan_speed)
    {
        case FAN_SPEED_AUTO: 
            if (g_temp_state.work_mode == WORK_MODE_HEAT) {
                // 制热模式：使用△T2 = Tset - Troom
                delta_t = g_temp_state.delta_t2;
            } else if (g_temp_state.work_mode == WORK_MODE_COOL) {
                // 制冷模式：使用△T1 = Troom - Tset
                delta_t = g_temp_state.delta_t1;
            } else {
                // 自动模式或通风模式：根据当前激活状态确定使用的温差
                if (g_temp_state.heating_active) {
                    // 当前处于制热状态，使用制热逻辑
                    delta_t = g_temp_state.delta_t2;
                } else {
                    // 当前处于制冷状态或未激活状态，使用制冷逻辑
                    delta_t = g_temp_state.delta_t1;
                }
            }

            /*大于2度，高风*/
            if(delta_t > 2)
            {
                fan_state = 3;
            }
            else if(delta_t > 1) 
            {
                fan_state = 2;
            }
            else
            {
                fan_state = 1;
            }
            break;

        case FAN_SPEED_LOW: 
            fan_state = 1;
            break;

        case FAN_SPEED_MID: 
            fan_state = 2;
            break;

        case FAN_SPEED_HIGH: 
            fan_state = 3;
            break;

        default:
            break;
    }

    if (g_temp_state.onoff_state == 1 && g_temp_state.work_mode != WORK_MODE_FAN)
    {
        if(fan_with_heat_valve && g_temp_state.heating_active)
        {
            if(new_ao2 == 0)
            {
                fan_state = 0; //停风
                fan_delay_off = fan_delay_off + GetFan_delay_off();
            }
        }

        if(fan_with_cool_valve && g_temp_state.cooling_active)
        {
            if(new_ao3 == 0)
            {
                fan_state = 0; //停风
                fan_delay_off = fan_delay_off + GetFan_delay_off();
            }
        }
    }
    else if (g_temp_state.onoff_state == 1 && g_temp_state.work_mode == WORK_MODE_FAN)
    { 
        //fan_state = 0;
    }
    else if (g_temp_state.onoff_state == 0/* && !anti_freeze_mode_get()*/)
    { 
        fan_state = 0;
    }
   


    if(fan_state != fan_state_record)
    {
        fan_state_record = fan_state;
        /*风机继电器关闭延时定时器*/
        if(relay_delay_timer == NULL)
        {
            printf("relay_delay_timer_create\r\n");
            const esp_timer_create_args_t relay_delay_timer_args = 
            {
                .callback = relay_delay_timer_args_callback,
                .name = "relay_delay_timer_args",
                //.arg = fan_state,
            };
            esp_timer_create(&relay_delay_timer_args, &relay_delay_timer);
            esp_timer_start_once(relay_delay_timer, fan_delay_off *1000000);      
        }
        /*在计时时，切换风速，重新启动定时器*/
        else
        {
            esp_timer_stop(relay_delay_timer);
            esp_timer_start_once(relay_delay_timer, fan_delay_off *1000000);
        }
        /*风机继电器开启延时定时器*/
        if(relay_start_timer == NULL)
        {
            printf("relay_start_timer_create\r\n");
            const esp_timer_create_args_t relay_start_timer_args = 
            {
                .callback = relay_start_timer_args_callback,
                .name = "relay_start_timer_args",
                .arg = &fan_state,
            };
            esp_timer_create(&relay_start_timer_args, &relay_start_timer);
            esp_timer_start_once(relay_start_timer, (fan_delay_off+1) *1000000);      
        }
        else
        {
            esp_timer_stop(relay_start_timer);
            esp_timer_start_once(relay_start_timer, (fan_delay_off+1) *1000000);
        }
    }
}



/**
 * @brief 计算风机输出百分比（兼容函数）
 */
static esp_err_t calculate_fan_output(uint8_t *ao1_output)
{
    return calculate_fan_output_with_valve_states(ao1_output, g_temp_state.ao2_output, g_temp_state.ao3_output);
}

/**
 * @brief 计算热阀输出百分比（带状态保持区间的滞回控制+延迟和间隔控制）
 */
static esp_err_t calculate_heat_valve_output(uint8_t *ao2_output)
{
    if (!ao2_output) return ESP_ERR_INVALID_ARG;        //检查传入的ao2_output指针是否为空(NULL)，若为空，则返回错误码ESP_ERR_INVALID_ARG
    
    *ao2_output = g_temp_state.heat_valve_last_output;  // 默认保持上次输出
    
    // 只有在制热激活时才计算输出
    if (!g_temp_state.heating_active) {
        // 制热未激活，记录关闭时间
        if (g_temp_state.heat_valve_last_output > 0) {
            g_temp_state.heat_valve_close_time = get_system_time_seconds();
        }
        g_temp_state.heat_valve_opened = false;  // 重置状态
        *ao2_output = 0;
        
        // 更新输出记录
        if (g_temp_state.heat_valve_last_output != 0) {
            g_temp_state.heat_valve_last_output = 0;
            g_temp_state.heat_valve_last_change_time = get_system_time_seconds();
        }
        return ESP_OK;
    }
    
    // 获取比例带，根据温度单位进行转换
    uint16_t temperature_unit = Gettemperature_unit();
    uint16_t proportional_band;
    if (temperature_unit == 1) {
        // 华氏度模式：将比例带除以2转换为摄氏度
        proportional_band = GetProportional_band() / 2;
    } else {
        // 摄氏度模式：直接使用比例带
        proportional_band = GetProportional_band();
    }
    uint16_t min_valve_open = GetMin_Valve_Open();
    uint16_t valve_start_delay = GetValve_start_delay();  // 获取启动延迟（分钟）
    float delta_t = g_temp_state.delta_t2;  // 使用ΔT2 = Tset - Troom
    static uint8_t desired_output = 0;
    
    if (delta_t < (-0.5f)) {
        // 区间1: ΔT < 0，强制关闭
        desired_output = 0;
        g_temp_state.heat_valve_opened = false;
    } 
    else if (delta_t >= T_HOLD) {
        // 区间3: ΔT > 死区温度，计算比例输出
        
        // 计算期望输出值 - 修复数据类型溢出问题
        float calculated_ao_float = (delta_t - T_HOLD) * 100.0f / (float)proportional_band;
        uint8_t min_ao = min_valve_open * 10;  // min_valve_open转换为百分比
        
        // 先限制在0-100范围内
        if (calculated_ao_float < min_ao) {
            calculated_ao_float = (float)min_ao;
        } else if (calculated_ao_float > 100.0f) {
            calculated_ao_float = 100.0f;  // 限制最大值
        }
        
        // 步进5处理：向下取整到最近的5的倍数
        desired_output = ((uint8_t)calculated_ao_float / 5) * 5;
        
        // 确保不低于最小开度（步进5处理）
        if (desired_output < min_ao) {
            desired_output = ((min_ao + 4) / 5) * 5;  // 向上取整到最近的5的倍数
        }
        
        // ESP_LOGI(TAG, "制热阀计算 - △T2:%.2f, 比例带:%d, 计算值:%.1f, 步进处理后:%d%%", 
        //          delta_t, proportional_band, calculated_ao_float, desired_output);
        // g_temp_state.heat_valve_opened = true;  // 标记为开启状态
    } 
    else {
        // // 区间2: 0 ≤ ΔT ≤ T_HOLD，状态保持区间（滞回控制）
        // if (g_temp_state.heat_valve_opened) {
        //     // 如果之前是开启的，保持最小开度（步进5处理）
        //     uint8_t min_ao = min_valve_open * 10;
        //     desired_output = ((min_ao + 4) / 5) * 5;  // 向上取整到最近的5的倍数
        // } else {
        //     // 如果之前是关闭的，保持关闭
        //     desired_output = 0;
        // }
        // // 保持区间内不改变heat_valve_opened状态
    }
    
    // 检查动作时间间隔
    uint32_t current_time = get_system_time_seconds();
    uint32_t elapsed_time = current_time - g_temp_state.heat_valve_last_change_time;
    // ESP_LOGI(TAG, "热阀间隔检查 - 当前输出:%d%%, 期望输出:%d%%, 上次变化时间戳:%lu, 当前时间戳:%lu, 间隔:%lu秒", 
    //          g_temp_state.heat_valve_last_output, desired_output, 
    //          (unsigned long)g_temp_state.heat_valve_last_change_time, 
    //          (unsigned long)current_time, (unsigned long)elapsed_time);
             
    if (!check_valve_interval(g_temp_state.heat_valve_last_change_time, 
                             g_temp_state.heat_valve_last_output, 
                             desired_output)) {
        // ESP_LOGD(TAG, "热阀动作间隔未到，保持当前输出: %d%%", g_temp_state.heat_valve_last_output);
        *ao2_output = g_temp_state.heat_valve_last_output;
        return ESP_OK;
    }
    
    // 输出值有变化，更新记录
    if (g_temp_state.heat_valve_last_output != desired_output) {
        uint8_t old_output = g_temp_state.heat_valve_last_output;
        g_temp_state.heat_valve_last_output = desired_output;
        g_temp_state.heat_valve_last_change_time = get_system_time_seconds();
        // ESP_LOGI(TAG, "热阀输出变化: %d%% -> %d%%", old_output, desired_output);
    }
    
    *ao2_output = desired_output;
    return ESP_OK;
}

/**
 * @brief 计算冷阀输出百分比（带状态保持区间的滞回控制+延迟和间隔控制）
 */
static esp_err_t calculate_cool_valve_output(uint8_t *ao3_output)
{
    if (!ao3_output) return ESP_ERR_INVALID_ARG;
    
    *ao3_output = g_temp_state.cool_valve_last_output;  // 默认保持上次输出
    
    // 只有在制冷激活时才计算输出
    if (!g_temp_state.cooling_active) {
        // 制冷未激活，记录关闭时间
        if (g_temp_state.cool_valve_last_output > 0) {
            g_temp_state.cool_valve_close_time = get_system_time_seconds();
        }
        g_temp_state.cool_valve_opened = false;  // 重置状态
        *ao3_output = 0;
        
        // 更新输出记录
        if (g_temp_state.cool_valve_last_output != 0) {
            g_temp_state.cool_valve_last_output = 0;
            g_temp_state.cool_valve_last_change_time = get_system_time_seconds();
        }
        return ESP_OK;
    }
    
    // 获取比例带，根据温度单位进行转换
    uint16_t temperature_unit = Gettemperature_unit();
    uint16_t proportional_band;
    if (temperature_unit == 1) {
        // 华氏度模式：将比例带除以2转换为摄氏度
        proportional_band = GetProportional_band() / 2;
    } else {
        // 摄氏度模式：直接使用比例带
        proportional_band = GetProportional_band();
    }
    uint16_t min_valve_open = GetMin_Valve_Open();
    uint16_t valve_start_delay = GetValve_start_delay();  // 获取启动延迟（分钟）
    float delta_t = g_temp_state.delta_t1;  // 使用ΔT1 = Troom - Tset
    static uint8_t desired_output = 0;
    
    if (delta_t < (-0.5f)) {
        // 区间1: ΔT < 0，强制关闭
        desired_output = 0;
        g_temp_state.cool_valve_opened = false;
    } 
    else if (delta_t >= T_HOLD) {
        // 区间3: ΔT > 死区温度，计算比例输出
        
        // 计算期望输出值 - 修复数据类型溢出问题
        float calculated_ao_float = (delta_t - T_HOLD) * 100.0f / (float)proportional_band;
        uint8_t min_ao = min_valve_open * 10;  // min_valve_open转换为百分比
        
        // 先限制在0-100范围内
        if (calculated_ao_float < min_ao) {
            calculated_ao_float = (float)min_ao;
        } else if (calculated_ao_float > 100.0f) {
            calculated_ao_float = 100.0f;  // 限制最大值
        }
        
        // 步进5处理：向下取整到最近的5的倍数
        desired_output = ((uint8_t)calculated_ao_float / 5) * 5;
        
        // 确保不低于最小开度（步进5处理）
        if (desired_output < min_ao) {
            desired_output = ((min_ao + 4) / 5) * 5;  // 向上取整到最近的5的倍数
        }
        
        // ESP_LOGI(TAG, "制冷阀计算 - △T1:%.2f, 比例带:%d, 计算值:%.1f, 步进处理后:%d%%", 
        //          delta_t, proportional_band, calculated_ao_float, desired_output);
        // g_temp_state.cool_valve_opened = true;  // 标记为开启状态
    } 
    else {
        // // 区间2: 0 ≤ ΔT ≤ T_HOLD，状态保持区间（滞回控制）
        // if (g_temp_state.cool_valve_opened) {
        //     // 如果之前是开启的，保持最小开度（步进5处理）
        //     uint8_t min_ao = min_valve_open * 10;
        //     desired_output = ((min_ao + 4) / 5) * 5;  // 向上取整到最近的5的倍数
        // } else {
        //     // 如果之前是关闭的，保持关闭
        //     desired_output = 0;
        // }
        // // 保持区间内不改变cool_valve_opened状态
    }
    
    // 检查动作时间间隔
    uint32_t current_time = get_system_time_seconds();
    uint32_t elapsed_time = current_time - g_temp_state.cool_valve_last_change_time;
    // ESP_LOGI(TAG, "冷阀间隔检查 - 当前输出:%d%%, 期望输出:%d%%, 上次变化时间戳:%lu, 当前时间戳:%lu, 间隔:%lu秒", 
    //          g_temp_state.cool_valve_last_output, desired_output, 
    //          (unsigned long)g_temp_state.cool_valve_last_change_time, 
    //          (unsigned long)current_time, (unsigned long)elapsed_time);
             
    if (!check_valve_interval(g_temp_state.cool_valve_last_change_time, 
                             g_temp_state.cool_valve_last_output, 
                             desired_output)) {
        // ESP_LOGD(TAG, "冷阀动作间隔未到，保持当前输出: %d%%", g_temp_state.cool_valve_last_output);
        *ao3_output = g_temp_state.cool_valve_last_output;
        return ESP_OK;
    }
    
    // 输出值有变化，更新记录
    if (g_temp_state.cool_valve_last_output != desired_output) {
        uint8_t old_output = g_temp_state.cool_valve_last_output;
        g_temp_state.cool_valve_last_output = desired_output;
        g_temp_state.cool_valve_last_change_time = get_system_time_seconds();
        // ESP_LOGI(TAG, "冷阀输出变化: %d%% -> %d%%", old_output, desired_output);
    }
    
    *ao3_output = desired_output;
    return ESP_OK;
}

/**
 * @brief 应用输出值到硬件(该模块预留，不使用)
 */
static esp_err_t apply_outputs(uint8_t ao1, uint8_t ao2, uint8_t ao3)
{
    esp_err_t ret = ESP_OK;
    uint16_t pipe_option = GetPipe_option();  // 获取管路选项（0=单管路，1=双管路）
    uint16_t work_mode = GetWork_mode();      // 获取工作模式
    
    // // 应用风机输出
    // if (i2c_mcu_ao1(ao1) != ESP_OK) {
    //     ESP_LOGE(TAG, "风机输出失败: %d%%", ao1);
    //     ret = ESP_FAIL;
    // }
    
    if (pipe_option == 1) {
        // 双管路模式：AO2为热阀，AO3为冷阀，都有继电器联动
        
        // 应用热阀输出（AO2 + K4继电器联动）
        if (ao2 > 0) {
            // 开启热阀继电器
            // if (i2c_mcu_relay_K4(1) != ESP_OK) {
            //     ESP_LOGE(TAG, "热阀继电器K4开启失败");
            //     ret = ESP_FAIL;
            // }
            if (i2c_mcu_ao2(ao2) != ESP_OK) {
                ESP_LOGE(TAG, "热阀输出失败: %d%%", ao2);
                ret = ESP_FAIL;
            }
        } else {
            // 关闭热阀和继电器
            if (i2c_mcu_ao2(0) != ESP_OK) {
                ESP_LOGE(TAG, "热阀关闭失败");
                ret = ESP_FAIL;
            }
            // if (i2c_mcu_relay_K4(0) != ESP_OK) {
            //     ESP_LOGE(TAG, "热阀继电器K4关闭失败");
            //     ret = ESP_FAIL;
            // }
        }
        
        // 应用冷阀输出（AO3 + K5继电器联动）
        if (ao3 > 0) {
            // 开启冷阀继电器
            // if (i2c_mcu_relay_K5(1) != ESP_OK) {
            //     ESP_LOGE(TAG, "冷阀继电器K5开启失败");
            //     ret = ESP_FAIL;
            // }
            if (i2c_mcu_ao1(ao3) != ESP_OK) {
                ESP_LOGE(TAG, "冷阀输出失败: %d%%", ao3);
                ret = ESP_FAIL;
            }
            else
            {
                // printf("1 ao3 = %d\r\n", ao3);
            }
        } else {
            // 关闭冷阀和继电器
            if (i2c_mcu_ao1(0) != ESP_OK) {
                ESP_LOGE(TAG, "冷阀关闭失败");
                ret = ESP_FAIL;
            }
            else
            {
                // printf("2 ao3 = %d\r\n", ao3);
            }
            // if (i2c_mcu_relay_K5(0) != ESP_OK) {
            //     ESP_LOGE(TAG, "冷阀继电器K5关闭失败");
            //     ret = ESP_FAIL;
            // }
        }
        
    } else {
        // 单管路模式：只使用AO2，根据工作模式决定制冷还是制热
        // 不使用继电器K4和K5，AO3也不使用
        
        uint8_t ao2_final_output = 0;
        const char* mode_name = "";
        
        if (work_mode == WORK_MODE_COOL) {
            // 制冷模式：使用ao3的值作为制冷输出，通过AO2输出
            ao2_final_output = ao3;
            mode_name = "制冷";
        } else if (work_mode == WORK_MODE_HEAT) {
            // 制热模式：使用ao2的值作为制热输出
            ao2_final_output = ao2;
            mode_name = "制热";
        } else {
            // 通风模式或其他情况：无阀门输出
            ao2_final_output = 0;
            mode_name = "通风";
        }
        
        // 应用单管路输出
        if (i2c_mcu_ao2(ao2_final_output) != ESP_OK) {
            ESP_LOGE(TAG, "单管路%s输出失败: %d%%", mode_name, ao2_final_output);
            ret = ESP_FAIL;
        } else if (ao2_final_output > 0) {
            ESP_LOGD(TAG, "单管路%s输出: %d%%", mode_name, ao2_final_output);
        }

        // 确保AO3关闭
        if (i2c_mcu_ao1(0) != ESP_OK) {
            ESP_LOGE(TAG, "AO3关闭失败");
            ret = ESP_FAIL;
        }
        else
        {
            // printf("3 ao3 = %d\r\n", ao3);
        }
    }
    return ret;
}



esp_timer_handle_t relay_k1_delay_timer = NULL;   
esp_timer_handle_t relay_k2_delay_timer = NULL; 
esp_timer_handle_t relay_fan_speed_off_delay_timer = NULL; 
esp_timer_handle_t relay_k3_delay_timer = NULL;  
esp_timer_handle_t relay_k4_delay_timer = NULL;  
esp_timer_handle_t relay_k5_delay_timer = NULL;  

void relay_k1_delay_timer_args_callback(void *arg)
{
    printf("relay_k1_delay_timer_args_callback *(uint8_t *)arg = %d\r\n", *(uint8_t *)arg);
    uint8_t tmp = *(uint8_t *)arg;
    i2c_mcu_ao1(tmp);
}

void relay_k2_delay_timer_args_callback(void *arg)
{
    printf("relay_k2_delay_timer_args_callback *(uint8_t *)arg = %d\r\n", *(uint8_t *)arg);
    uint8_t tmp = *(uint8_t *)arg;
    i2c_mcu_ao2(tmp);
}

void relay_fan_speed_off_delay_timer_args_callback(void *arg)
{
    printf("~~~~~~~~~~~~~~relay_fan_speed_off_delay_timer_args_callback\r\n");
    K3_state_act = 0;
    K4_state_act = 0;
    K5_state_act = 0;
    i2c_mcu_relay_K3(0);
    i2c_mcu_relay_K4(0);
    i2c_mcu_relay_K5(0);
}

void relay_k3_delay_timer_args_callback(void *arg)
{
    printf("~~~~~~~~~~~~~~relay_k3_delay_timer_args_callback\r\n");
    K3_state_act = 1;
    i2c_mcu_relay_K3(1);
}

void relay_k4_delay_timer_args_callback(void *arg)
{
    printf("~~~~~~~~~~~~~~relay_k4_delay_timer_args_callback\r\n");
    K4_state_act = 1;
    i2c_mcu_relay_K4(1);
}

void relay_k5_delay_timer_args_callback(void *arg)
{
    printf("~~~~~~~~~~~~~~relay_k5_delay_timer_args_callback\r\n");
    K5_state_act = 1;
    i2c_mcu_relay_K5(1);
}



/**
 * @brief 优化的输出应用函数：只有数值变化时才进行I2C写入
 * @param ao1 风机输出百分比 (0-100)
 * @param ao2 热阀输出百分比 (0-100) 
 * @param ao3 冷阀输出百分比 (0-100)
 * @param force_update 是否强制更新所有输出
 * @return ESP_OK 成功，其他值失败
 */
static esp_err_t apply_outputs_optimized(uint8_t ao1, uint8_t ao2, uint8_t ao3, bool force_update)
{
    esp_err_t ret = ESP_OK;
    uint16_t pipe_option = GetPipe_option();  // 获取管路选项（0=单管路，1=双管路）
    uint16_t work_mode = GetWork_mode();      // 获取工作模式
    bool ao1_changed = false, ao2_changed = false, ao3_changed = false;
    bool k4_changed = false, k5_changed = false;
    
    // 检查是否需要强制更新
    if (force_update) {
        /*ao1_changed = */ao2_changed = ao3_changed = true;
        //k4_changed = k5_changed = true;
        ESP_LOGI(TAG, "输出缓存强制更新 - 强制写入所有输出");
    } else {
        // 检查各输出值是否变化
        //ao1_changed = (ao1 != output_cache.last_ao1_output);
        ao2_changed = (ao2 != output_cache.last_ao2_output);
        ao3_changed = (ao3 != output_cache.last_ao3_output);
    }
    
    fan_output_logic(ao2, ao3);
    // 应用风机输出（AO1）
    // if (ao1_changed) {
    //     if (i2c_mcu_ao1(ao1) != ESP_OK) {
    //         ESP_LOGE(TAG, "风机输出失败: %d%%", ao1);
    //         ret = ESP_FAIL;
    //     } else {
    //         output_cache.last_ao1_output = ao1;
    //         // ESP_LOGD(TAG, "风机输出更新: %d%%", ao1);
    //     }
    // }
    
    if (pipe_option == 1) {
        // 双管路模式：AO2为热阀，AO3为冷阀，都有继电器联动
        
        // 处理热阀输出（AO2 + K4继电器联动）
        uint8_t k4_new_state = (ao2 > 0) ? 1 : 0;
        k4_changed = (k4_new_state != output_cache.last_k4_state) || force_update;
        
        if (ao2_changed || k4_changed) {
            if (ao2 > 0) {
                // 开启热阀：先开继电器，再设置输出
                if (k4_changed) {
                    if (/*i2c_mcu_relay_K4(1) != ESP_OK*/0) {
                        ESP_LOGE(TAG, "热阀继电器K4开启失败");
                        ret = ESP_FAIL;
                    } else {
                        output_cache.last_k4_state = 1;
                        // ESP_LOGD(TAG, "热阀继电器K4开启");
                    }
                }
                if (ao2_changed) {
                    k1_state = 1;
                    output_cache.last_ao2_output = ao2;
                }
            } else {
                // 关闭热阀：先关输出，再关继电器
                if (ao2_changed) {
                    k1_state = 0;
                    output_cache.last_ao2_output = 0;
                }
                if (k4_changed) {
                    if (/*i2c_mcu_relay_K4(0) != ESP_OK*/0) {
                        ESP_LOGE(TAG, "热阀继电器K4关闭失败");
                        ret = ESP_FAIL;
                    } else {
                        output_cache.last_k4_state = 0;
                        // ESP_LOGD(TAG, "热阀继电器K4关闭");
                    }
                }
            }
        }
        
        // 处理冷阀输出（AO3 + K5继电器联动）
        uint8_t k5_new_state = (ao3 > 0) ? 1 : 0;
        k5_changed = (k5_new_state != output_cache.last_k5_state) || force_update;
        
        if (ao3_changed || k5_changed) {
            if (ao3 > 0) {
                // 开启冷阀：先开继电器，再设置输出
                if (k5_changed) {
                    if (/*i2c_mcu_relay_K5(1) != ESP_OK*/0) {
                        ESP_LOGE(TAG, "冷阀继电器K5开启失败");
                        ret = ESP_FAIL;
                    } else {
                        output_cache.last_k5_state = 1;
                        // ESP_LOGD(TAG, "冷阀继电器K5开启");
                    }
                }
                if (ao3_changed) {
                    k2_state = 1;
                    output_cache.last_ao3_output = ao3;
                }
            } else {
                // 关闭冷阀：先关输出，再关继电器
                if (ao3_changed) {
                    k2_state = 0;
                    output_cache.last_ao3_output = 0;
                }
                if (k5_changed) {
                    if (/*i2c_mcu_relay_K5(0) != ESP_OK*/0) {
                        ESP_LOGE(TAG, "冷阀继电器K5关闭失败");
                        ret = ESP_FAIL;
                    } else {
                        output_cache.last_k5_state = 0;
                        // ESP_LOGD(TAG, "冷阀继电器K5关闭");
                    }
                }
            }
        }
        
    } else {
        // 单管路模式：只使用AO2，根据工作模式决定制冷还是制热
        uint8_t ao2_final_output = 0;
        const char* mode_name = "";
        
        if (work_mode == WORK_MODE_COOL) {
            // 制冷模式：使用ao3的值作为制冷输出，通过AO2输出
            ao2_final_output = ao3;
            mode_name = "制冷";
        } else if (work_mode == WORK_MODE_HEAT) {
            // 制热模式：使用ao2的值作为制热输出
            ao2_final_output = ao2;
            mode_name = "制热";
        } else {
            // 通风模式或其他情况：无阀门输出
            ao2_final_output = 0;
            mode_name = "通风";
        }

        /*puxin 20250718*/
        // 确保AO3关闭（仅在需要时）
        if (output_cache.last_ao3_output != 0 || force_update) {
            output_cache.last_ao3_output = 0;
        }
        
        // 检查单管路AO2输出是否需要更新
            if (ao2_final_output > 0)
            {
                k1_state = 1;
                k2_state = 0;
            }
            else
            {
                k1_state = 0;
                k2_state = 1;
            }
    }

    /*实际继电器输出*/
    printf("k1_state:%d, k2_state:%d\r\n", k1_state, k2_state);
    if(k1_state_record != k1_state || k2_state_record != k2_state)
    {
        printf("k1_state_record:%d, k2_state_record:%d\r\n", k1_state_record, k2_state_record);
        k1_state_record = k1_state;
        k2_state_record = k2_state;
        if(k1_state == 0)
        {
            const esp_timer_create_args_t relay_k1_delay_timer_args = 
            {
                .callback = relay_k1_delay_timer_args_callback,
                .name = "relay_k1_delay_timer_args",
                .arg = &k1_state,
            };
            esp_timer_create(&relay_k1_delay_timer_args, &relay_k1_delay_timer);
            esp_timer_start_once(relay_k1_delay_timer, 1000000);
            
            const esp_timer_create_args_t relay_k2_delay_timer_args = 
            {
                .callback = relay_k2_delay_timer_args_callback,
                .name = "relay_k2_delay_timer_args",
                .arg = &k2_state,
            };
            esp_timer_create(&relay_k2_delay_timer_args, &relay_k2_delay_timer);
            esp_timer_start_once(relay_k2_delay_timer, 2000000);
        }
        else
        {
            const esp_timer_create_args_t relay_k1_delay_timer_args = 
            {
                .callback = relay_k1_delay_timer_args_callback,
                .name = "relay_k1_delay_timer_args",
                .arg = &k1_state,
            };
            esp_timer_create(&relay_k1_delay_timer_args, &relay_k1_delay_timer);
            esp_timer_start_once(relay_k1_delay_timer, 2000000);
            
            const esp_timer_create_args_t relay_k2_delay_timer_args = 
            {
                .callback = relay_k2_delay_timer_args_callback,
                .name = "relay_k2_delay_timer_args",
                .arg = &k2_state,
            };
            esp_timer_create(&relay_k2_delay_timer_args, &relay_k2_delay_timer);
            esp_timer_start_once(relay_k2_delay_timer, 1000000);
        }
    }

    printf("k3_state:%d, k4_state:%d, k5_state:%d\r\n", k3_state, k4_state, k5_state);
    if(k3_state_record != k3_state || k4_state_record != k4_state || k5_state_record != k5_state)
    {
        printf("k3_state_record:%d, k4_state_record:%d, k5_state_record:%d\r\n", k3_state_record, k4_state_record, k5_state_record);
        k3_state_record = k3_state;
        k4_state_record = k4_state;
        k5_state_record = k5_state;

        if(K3_state_act != k3_state || K4_state_act != k4_state || K5_state_act != k5_state)
        {
            const esp_timer_create_args_t relay_fan_speed_off_delay_timer_args = 
            {
                .callback = relay_fan_speed_off_delay_timer_args_callback,
                .name = "relay_fan_speed_off_delay_timer_args",
            };
            esp_timer_create(&relay_fan_speed_off_delay_timer_args, &relay_fan_speed_off_delay_timer);
            esp_timer_start_once(relay_fan_speed_off_delay_timer, 3000000);
        }
        else if (relay_fan_speed_off_delay_timer != NULL)
        {
            esp_timer_stop(relay_fan_speed_off_delay_timer);
        }
        
        if(k3_state == 1)
        {
            const esp_timer_create_args_t relay_k3_delay_timer_args = 
            {
                .callback = relay_k3_delay_timer_args_callback,
                .name = "relay_k3_delay_timer_args",
                .arg = &k3_state,
            };
            esp_timer_create(&relay_k3_delay_timer_args, &relay_k3_delay_timer);
            esp_timer_start_once(relay_k3_delay_timer, 4000000);
        }
        else if(k4_state == 1)
        {
            const esp_timer_create_args_t relay_k4_delay_timer_args = 
            {
                .callback = relay_k4_delay_timer_args_callback,
                .name = "relay_k4_delay_timer_args",
                .arg = &k4_state,
            };
            esp_timer_create(&relay_k4_delay_timer_args, &relay_k4_delay_timer);
            esp_timer_start_once(relay_k4_delay_timer, 4000000);
        }
        else if(k5_state == 1)
        {
            const esp_timer_create_args_t relay_k5_delay_timer_args = 
            {
                .callback = relay_k5_delay_timer_args_callback,
                .name = "relay_k5_delay_timer_args",
                .arg = &k5_state,
            };
            esp_timer_create(&relay_k5_delay_timer_args, &relay_k5_delay_timer);
            esp_timer_start_once(relay_k5_delay_timer, 4000000);
        }
    }
    
    // 统计实际的I2C操作次数
    int i2c_operations = 0;
    if (ao1_changed) i2c_operations++;
    if (pipe_option == 1) {
        if (ao2_changed) i2c_operations++;
        if (ao3_changed) i2c_operations++;
        if (k4_changed) i2c_operations++;
        if (k5_changed) i2c_operations++;
    } else {
        if (ao2_changed || force_update) i2c_operations++;
        if (output_cache.last_ao3_output != 0 || force_update) i2c_operations++;
    }
    
    if (i2c_operations > 0) {
        // ESP_LOGD(TAG, "I2C优化：本次执行%d个写入操作", i2c_operations);
    } else {
        ESP_LOGV(TAG, "I2C优化：无变化，跳过所有写入操作");
    }
    
    return ret;
}

/**
 * @brief 根据风速档位获取输出百分比
 */
static uint8_t get_fan_speed_percentage(uint16_t speed)
{
    switch (speed) {
        case FAN_SPEED_AUTO:
            // 自动风：根据温差自动调节风速
            return get_auto_fan_speed_percentage();
        case FAN_SPEED_LOW:
            // 低风：使用GetLow_Fan_Voltage()的值乘以10
            return (uint8_t)(GetLow_Fan_Voltage() * 10);
        case FAN_SPEED_MID:
            // 中风：使用GetMed_Fan_Voltage()的值乘以10
            return (uint8_t)(GetMed_Fan_Voltage() * 10);
        case FAN_SPEED_HIGH:
            // 高风：使用GetHigh_Fan_Voltage()的值乘以10
            return (uint8_t)(GetHigh_Fan_Voltage() * 10);
        default:
            return 0;    // 错误档位关闭
    }
}

/**
 * @brief 自动风模式：根据温差和阀门状态计算合适的风速百分比
 * @details 优化后的自动风逻辑：
 * - 若△T1<0（制冷）或△T2<0（制热），根据风机与阀门联动设置决定风机输出
 * - 若△T1＞0.2（制冷）或△T2＞0.2（制热），AO1=25*(△T-0.2)，受Min/Max_Fan_Voltage*10限制，步进5
 * - 若0≤△T≤0.2，根据上一状态决定：开启则计算输出，关闭则保持关闭
 */
static uint8_t get_auto_fan_speed_percentage(void)
{
    // 根据工作模式和激活状态确定使用的温差
    float delta_t;
    bool is_cooling_mode;
    
    if (g_temp_state.work_mode == WORK_MODE_HEAT) {
        // 制热模式：使用△T2 = Tset - Troom
        delta_t = g_temp_state.delta_t2;
        is_cooling_mode = false;
    } else if (g_temp_state.work_mode == WORK_MODE_COOL) {
        // 制冷模式：使用△T1 = Troom - Tset
        delta_t = g_temp_state.delta_t1;
        is_cooling_mode = true;
    } else {
        // 自动模式或通风模式：根据当前激活状态确定使用的温差
        if (g_temp_state.heating_active) {
            // 当前处于制热状态，使用制热逻辑
            delta_t = g_temp_state.delta_t2;
            is_cooling_mode = false;
        } else {
            // 当前处于制冷状态或未激活状态，使用制冷逻辑
            delta_t = g_temp_state.delta_t1;
            is_cooling_mode = true;
        }
    }
    
    // 获取风机电压限制参数
    uint16_t min_fan_voltage = GetMin_Fan_Voltage();
    uint16_t max_fan_voltage = GetMax_Fan_Voltage();
    
    // 转换为百分比限制（电压值*10）
    uint8_t min_output = (uint8_t)(min_fan_voltage * 10);
    uint8_t max_output = (uint8_t)(max_fan_voltage * 10);
    
    // 根据温差计算输出
    if (delta_t < 0) {
        // △T < 0：温度已达标，根据风机与阀门联动设置决定风机输出
        uint16_t fan_with_heat_valve = GetFan_state_with_heat_valve();
        uint16_t fan_with_cool_valve = GetFan_state_with_cool_valve();
        
        if (is_cooling_mode) {
            // 制冷模式：根据风机与冷阀联动设置
            if (fan_with_cool_valve == 0) {
                // 风机与冷阀不同步：风机按最低风速运行
                g_temp_state.fan_was_on = true;  // 记录开启状态
                ESP_LOGD(TAG, "制冷模式△T<0 - 风机与冷阀不同步，风机按最低风速运行: %d%%", min_output);
                return min_output;
            } else {
                // 风机与冷阀同步：风机关闭
                g_temp_state.fan_was_on = false;  // 记录关闭状态
                ESP_LOGD(TAG, "制冷模式△T<0 - 风机与冷阀同步，风机关闭");
                return 0;
            }
        } else {
            // 制热模式：根据风机与热阀联动设置
            if (fan_with_heat_valve == 0) {
                // 风机与热阀不同步：风机按最低风速运行
                g_temp_state.fan_was_on = true;  // 记录开启状态
                ESP_LOGD(TAG, "制热模式△T<0 - 风机与热阀不同步，风机按最低风速运行: %d%%", min_output);
                return min_output;
            } else {
                // 风机与热阀同步：风机关闭
                g_temp_state.fan_was_on = false;  // 记录关闭状态
                ESP_LOGD(TAG, "制热模式△T<0 - 风机与热阀同步，风机关闭");
                return 0;
            }
        }
    } else if (delta_t >= T_HOLD) {
        // △T > 死区温度：需要调节，计算输出
        g_temp_state.fan_was_on = true;   // 记录开启状态
        
        // 计算输出：AO1 = 30 * (△T - 死区温度)
        float calculated_output = 30.0f * (delta_t - T_HOLD);
        
        // 限制在最小最大值范围内
        if (calculated_output < min_output) {
            calculated_output = (float)min_output;
        } else if (calculated_output > max_output) {
            calculated_output = (float)max_output;
        }
        
        // 步进5处理：向下取整到最近的5的倍数
        uint8_t output = (uint8_t)(calculated_output / 5) * 5;
        
        // ESP_LOGI(TAG, "自动风计算 - 模式:%s, △T:%.2f, 计算值:%.1f, 限制后:%.1f, 最终输出:%d%%", 
        //          is_cooling_mode ? "制冷" : "制热", delta_t, 25.0f * (delta_t - T_HOLD), 
        //          calculated_output, output);
        
        return output;
    } else {
        // 0 ≤ △T ≤ 死区温度：状态保持区间
        if (g_temp_state.fan_was_on) {
            // 上一状态是开启，计算输出
            float calculated_output = 25.0f * (delta_t - T_HOLD);
            
            // 限制在最小最大值范围内
            if (calculated_output < min_output) {
                calculated_output = (float)min_output;
            } else if (calculated_output > max_output) {
                calculated_output = (float)max_output;
            }
            
            // 步进5处理
            uint8_t output = (uint8_t)(calculated_output / 5) * 5;
            
            ESP_LOGD(TAG, "自动风状态保持(开启) - 模式:%s, △T:%.2f, 输出:%d%%", 
                     is_cooling_mode ? "制冷" : "制热", delta_t, output);
            
            return output;
        } else {
            // 上一状态是关闭，保持关闭
            ESP_LOGD(TAG, "自动风状态保持(关闭) - 模式:%s, △T:%.2f, 输出:0%%", 
                     is_cooling_mode ? "制冷" : "制热", delta_t);
            
            return 0;
        }
    }
}



/**
 * @brief 温控系统主循环处理函数
 */
esp_err_t output_control_process(void)
{
    esp_err_t ret = ESP_OK;
    
    // 检查NTC故障状态，故障时关闭所有输出
    int fault_code = get_fault_code();
    if (fault_code > 0) {
        // NTC故障，关闭所有输出
            ESP_LOGW(TAG, "NTC故障检测到(错误码:%d)，关闭所有输出", fault_code);
            //g_temp_state.ao1_output = 0;
            g_temp_state.ao2_output = 0;
            g_temp_state.ao3_output = 0;
            ret = apply_outputs_optimized(0, 0, 0, true);
            if (ret != ESP_OK) {
                ESP_LOGE(TAG, "NTC故障时关闭输出失败");
                return ret;
            }
        return ESP_OK;  // 故障时直接返回，不进行正常温控计算
    }
    
    // 房卡节能控制处理
    ret = roomcard_energy_saving_control();
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "房卡节能控制处理失败");
        return ret;
    }
    
    // 首先处理开关机控制
    ret = output_control_onoff();
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "开关机控制处理失败");
        return ret;
    }
    
    // 更新温度值
    ret = update_temperature_values();
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "更新温度值失败");
        return ret;
    }
    
    // 检查系统是否已准备就绪（开机延迟检查）
    if (!is_system_power_on_ready()) {
        if (g_temp_state.onoff_state == 0) {
            // 系统关机状态，处理风机延迟关闭
            if (g_temp_state.fan_delay_stopping) {
                // 检查风机延迟关闭时间是否已到
                if (get_system_time_seconds() >= g_temp_state.fan_should_stop_time) {
                    // 延迟时间到，关闭风机
                    //g_temp_state.ao1_output = 0;
                    g_temp_state.fan_delay_stopping = false;
                    ESP_LOGI(TAG, "关机：风机延迟关闭时间到，风机关闭");
                    
                    ret = apply_outputs_optimized(0, 0, 0, false);
                    if (ret != ESP_OK) {
                        ESP_LOGE(TAG, "关机：应用最终关闭输出失败");
                        return ret;
                    }
                } else {
                    // 延迟期间保持风机运行，阀门保持关闭
                    ESP_LOGD(TAG, "关机：风机延迟关闭中，剩余时间: %d秒", 
                             (int)(g_temp_state.fan_should_stop_time - get_system_time_seconds()));
                    
                    ret = apply_outputs_optimized(/*g_temp_state.ao1_output*/0, 0, 0, false);
                    if (ret != ESP_OK) {
                        ESP_LOGE(TAG, "关机：应用延迟关闭输出失败");
                        return ret;
                    }
                }
            } else {
                // 无延迟关闭或已完成，关闭所有输出
                //g_temp_state.ao1_output = 0;
                g_temp_state.ao2_output = 0;
                g_temp_state.ao3_output = 0;
                
                ret = apply_outputs_optimized(0, 0, 0, false);
                if (ret != ESP_OK) {
                    ESP_LOGE(TAG, "关机：应用关闭输出失败");
                    return ret;
                }
                ESP_LOGD(TAG, "系统关机状态，所有输出关闭");
            }
        } else {
            // 开机延迟期内，强制关闭所有输出
            //g_temp_state.ao1_output = 0;
            g_temp_state.ao2_output = 0;
            g_temp_state.ao3_output = 0;
            
            static uint8_t record = 0;
            if(get_production_test_running_flag())
            {
                record = 1;
            }

            if(record == 1 && !get_production_test_running_flag())
            {
                record = 0;
                apply_outputs_optimized(0, 0, 0, true);
                ESP_LOGI(TAG, "生产测试结束，强制正常输出");
            }

            ret = apply_outputs_optimized(0, 0, 0, false);
            if (ret != ESP_OK) {
                ESP_LOGE(TAG, "应用关闭输出失败");
                return ret;
            }
            ESP_LOGD(TAG, "开机延迟期内，等待延迟结束...");
        }
        
        return ESP_OK;
    }
    
    // 系统开机且延迟已过，正常计算各路输出
    uint8_t /*ao1_output = 0, */ao2_output, ao3_output = 0;
    
    // 首先根据工作模式设置激活状态，这是阀门计算的前提条件
    switch (g_temp_state.work_mode) {
        case WORK_MODE_AUTO:
            // 自动模式：根据温差自动切换制冷/制热
            if (g_temp_state.delta_t1 > T_HOLD) {
                // 明确需要制冷
                if (g_temp_state.heating_active) {
                    // 从制热切换到制冷，立即关闭制热
                    g_temp_state.heating_active = false;
                    g_temp_state.heat_valve_opened = false;
                    // 重置热阀时间戳，确保自动模式切换后的延迟控制生效
                    g_temp_state.heat_valve_last_change_time = get_system_time_seconds();
                    // ESP_LOGI(TAG, "自动模式切换：制热→制冷，重置热阀时间戳，启动延迟控制");
                }
                g_temp_state.cooling_active = true;
            } else if (g_temp_state.delta_t1 < -T_HOLD) {
                // 明确需要制热
                if (g_temp_state.cooling_active) {
                    // 从制冷切换到制热，立即关闭制冷
                    g_temp_state.cooling_active = false;
                    g_temp_state.cool_valve_opened = false;
                    // 重置冷阀时间戳，确保自动模式切换后的延迟控制生效
                    g_temp_state.cool_valve_last_change_time = get_system_time_seconds();
                    // ESP_LOGI(TAG, "自动模式切换：制冷→制热，重置冷阀时间戳，启动延迟控制");
                }
                g_temp_state.heating_active = true;
            }
            // 死区内保持当前状态不变
            break;
            
        case WORK_MODE_COOL:
            // 制冷模式
            g_temp_state.cooling_active = true;
            g_temp_state.heating_active = false;
            g_temp_state.heat_valve_opened = false;
            g_temp_state.heat_valve_last_output = 0;
            // 重置热阀时间戳，确保模式切换后的延迟控制生效
            g_temp_state.heat_valve_last_change_time = get_system_time_seconds();
            // ESP_LOGI(TAG, "模式切换：制热→制冷，重置热阀时间戳，启动延迟控制");
            break;
            
        case WORK_MODE_HEAT:
            // 制热模式
            g_temp_state.heating_active = true;
            g_temp_state.cooling_active = false;
            g_temp_state.cool_valve_opened = false;
            g_temp_state.cool_valve_last_output = 0;
            // 重置冷阀时间戳，确保模式切换后的延迟控制生效
            g_temp_state.cool_valve_last_change_time = get_system_time_seconds();
            // ESP_LOGI(TAG, "模式切换：制冷→制热，重置冷阀时间戳，启动延迟控制");
            break;
            
        case WORK_MODE_FAN:
            // 通风模式
            g_temp_state.cooling_active = false;
            g_temp_state.heating_active = false;
            break;
    }
    
    // 保存当前阀门状态，供风机延迟关闭逻辑使用
    uint8_t previous_ao2_output = g_temp_state.ao2_output;
    uint8_t previous_ao3_output = g_temp_state.ao3_output;
    
    // 然后计算阀门输出，此时激活状态已经正确设置
    ret = calculate_heat_valve_output(&ao2_output);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "计算热阀输出失败");
        return ret;
    }
    
    ret = calculate_cool_valve_output(&ao3_output);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "计算冷阀输出失败");
        return ret;
    }
    
    // 先计算风机输出，传入新的阀门值供延迟关闭逻辑使用
    //ret = calculate_fan_output_with_valve_states(&ao1_output, ao2_output, ao3_output);

    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "计算风机输出失败");
        return ret;
    }
    
    // 最后更新阀门状态
    g_temp_state.ao2_output = ao2_output;
    g_temp_state.ao3_output = ao3_output;
    
    // 更新风机状态
    //g_temp_state.ao1_output = ao1_output;
    
    // 应用输出（使用优化版本，避免重复I2C写入）
    static uint8_t Pipe_option = 0;
    if(Pipe_option != GetPipe_option())
    {
        Pipe_option = GetPipe_option();
        ret = apply_outputs_optimized(/*ao1_output*/0, ao2_output, ao3_output, true);
    }
    else
    {
        ret = apply_outputs_optimized(/*ao1_output*/0, ao2_output, ao3_output, false);
    }
    
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "应用输出失败");
        return ret;
    }
    
    // 只在输出有变化时打印详细信息，减少日志冗余
    if (/*ao1_output != g_temp_state.last_printed_ao1 || */ao2_output != g_temp_state.last_printed_ao2 || ao3_output != g_temp_state.last_printed_ao3) {
        g_temp_state.last_printed_ao2 = ao2_output;
        g_temp_state.last_printed_ao3 = ao3_output;
    } 
    
    return ESP_OK;
}

/**
 * @brief 获取当前温控状态
 */
esp_err_t output_control_get_state(temp_control_state_t *state)
{
    if (!state) return ESP_ERR_INVALID_ARG;
    
    memcpy(state, &g_temp_state, sizeof(temp_control_state_t));
    return ESP_OK;
}

/**
 * @brief 强制设置输出值（调试用）
 */
esp_err_t output_control_force_output(uint8_t ao1, uint8_t ao2, uint8_t ao3)
{
    ESP_LOGW(TAG, "强制输出设置 - AO1:%d%%, AO2:%d%%, AO3:%d%%", ao1, ao2, ao3);
    
    // 更新状态
    //g_temp_state.ao1_output = ao1;
    g_temp_state.ao2_output = ao2;
    g_temp_state.ao3_output = ao3;
    
    return apply_outputs_optimized(ao1, ao2, ao3, true);  // 强制输出强制更新
}

/**
 * @brief 停止所有输出
 */
esp_err_t output_control_stop_all(void)
{
    ESP_LOGI(TAG, "停止所有输出");
    
    // 清除状态
    //g_temp_state.ao1_output = 0;
    g_temp_state.ao2_output = 0;
    g_temp_state.ao3_output = 0;
    g_temp_state.cooling_active = false;
    g_temp_state.heating_active = false;
    
    return apply_outputs_optimized(0, 0, 0, true);  // 停止所有输出强制更新
}

/**
 * @brief 获取系统运行时间（秒）
 * @note 使用相对时间戳，避免长时间运行后的溢出风险
 */
static uint32_t get_system_time_seconds(void)
{
    static uint32_t base_time = 0;
    static bool initialized = false;
    
    uint32_t current_time = (uint32_t)(esp_timer_get_time() / 1000000);  // 微秒转秒
    
    if (!initialized) {
        base_time = current_time;
        initialized = true;
    }
    
    // 使用相对时间戳，避免溢出
    return current_time - base_time;
}

/**
 * @brief 检查阀门启动延迟时间
 * @param valve_close_time 阀门关闭时间戳
 * @param delay_minutes 延迟时间（分钟）
 * @return true=延迟时间已到，可以开启；false=仍在延迟期内
 */
static bool check_valve_start_delay(uint32_t valve_close_time, uint16_t delay_minutes)
{
    if (delay_minutes == 0) {
        return true;  // 无延迟要求
    }
    
    uint32_t current_time = get_system_time_seconds();
    uint32_t delay_seconds = delay_minutes * 60;  // 分钟转秒
    
    return (current_time - valve_close_time) >= delay_seconds;
}

/**
 * @brief 检查阀门动作时间间隔
 * @param last_change_time 上次变化时间戳
 * @param last_output 上次输出值
 * @param new_output 新的输出值
 * @return true=可以变化；false=间隔时间未到
 */
static bool check_valve_interval(uint32_t last_change_time, uint8_t last_output, uint8_t new_output)
{
    // 如果输出值没有变化，不需要检查间隔
    if (last_output == new_output) {
        return true;
    }
    
    uint32_t current_time = get_system_time_seconds();
    uint16_t valve_interval = GetValve_Interval();  // 获取基础间隔时间（秒）
    uint16_t valve_start_delay = GetValve_start_delay();  // 获取启动延迟（分钟）
    uint16_t effective_interval = valve_interval;  // 实际使用的间隔时间
    
    // 检查是否为阀门从0到非0的开启动作
    bool is_valve_opening = (last_output == 0 && new_output > 0);
    
    if (is_valve_opening && valve_start_delay > 0) {
        // 阀门从0到非0开启，需要考虑启动延迟
        uint16_t start_delay_seconds = valve_start_delay * 60;  // 分钟转秒
        
        if (start_delay_seconds > valve_interval) {
            // 启动延迟更长，使用启动延迟作为间隔时间
            effective_interval = start_delay_seconds;
            ESP_LOGD(TAG, "阀门开启：启动延迟(%d分钟=%d秒) > 间隔时间(%d秒)，使用启动延迟", 
                     valve_start_delay, start_delay_seconds, valve_interval);
        } else {
            // 间隔时间更长或相等，使用原间隔时间
            effective_interval = valve_interval;
            ESP_LOGD(TAG, "阀门开启：启动延迟(%d分钟=%d秒) <= 间隔时间(%d秒)，使用间隔时间", 
                     valve_start_delay, start_delay_seconds, valve_interval);
        }
    } else {
        // 阀门关闭（非0到0）或阀门调节（非0到非0），使用原间隔时间
        effective_interval = valve_interval;
        if (last_output > 0 && new_output == 0) {
            ESP_LOGD(TAG, "阀门关闭：使用标准间隔时间%d秒", effective_interval);
        } else if (last_output > 0 && new_output > 0) {
            ESP_LOGD(TAG, "阀门调节：使用标准间隔时间%d秒", effective_interval);
        }
    }
    
    // 如果实际间隔设置为0，不进行间隔控制
    if (effective_interval == 0) {
        return true;
    }
    
    // 防止时间戳下溢
    uint32_t elapsed_time;
    if (current_time >= last_change_time) {
        elapsed_time = current_time - last_change_time;
    } else {
        // 时间戳下溢，重置为0
        ESP_LOGW(TAG, "时间戳下溢检测：当前时间%lu < 上次时间%lu，重置间隔计算", 
                 (unsigned long)current_time, (unsigned long)last_change_time);
        elapsed_time = 0;
    }
    
    // 间隔检查
    if (elapsed_time >= effective_interval) {
        if (is_valve_opening && valve_start_delay > 0 && effective_interval > valve_interval) {
            ESP_LOGI(TAG, "阀门启动延迟时间已到(%lu秒)，允许开启 %d%% -> %d%%", 
                     (unsigned long)elapsed_time, last_output, new_output);
        } else {
            ESP_LOGD(TAG, "阀门间隔时间已到(%lu秒)，允许变化 %d%% -> %d%%", 
                     (unsigned long)elapsed_time, last_output, new_output);
        }
        return true;
    }
    
    // 计算最大等待时间：3倍间隔时间，但不超过300秒
    uint16_t max_wait_time = effective_interval * 3;
    if (max_wait_time > 300) {
        max_wait_time = 300;
    }
    
    // 防止时间戳异常：如果间隔时间超过24小时，重置时间戳
    if (elapsed_time > 86400) {  // 24小时 = 86400秒
        ESP_LOGW(TAG, "时间戳异常：间隔时间%lu秒超过24小时，重置时间戳", 
                 (unsigned long)elapsed_time);
        return true;  // 允许变化，重置时间戳
    }
    
    // 只有当等待时间真的超过最大限制时，才是强制更新
    if (elapsed_time >= max_wait_time) {
        ESP_LOGW(TAG, "阀门等待时间过长(%lu秒)，强制更新输出 %d%% -> %d%%", 
                 (unsigned long)elapsed_time, last_output, new_output);
        return true;
    }
    
    // 间隔时间未到，拒绝变化
    uint32_t remaining_time = effective_interval - elapsed_time;
    return false;
}

/**
 * @brief 检查系统开机是否已准备就绪（延迟3秒完成）
 * @return true=开机就绪，可以正常输出；false=仍在开机延迟期内
 */
static bool is_system_power_on_ready(void)
{
    // 如果系统是关机状态，不需要检查延迟
    if (g_temp_state.onoff_state == 0) {
        return false;  // 关机状态，不允许输出
    }
    
    // 如果没有激活开机延迟，说明已经就绪
    if (!g_temp_state.power_on_delay_active) {
        return true;
    }
    
    // 检查开机延迟时间是否已到（2秒）
    uint32_t current_time = get_system_time_seconds();
    if (current_time >= g_temp_state.power_on_time + 2) { 
        // 延迟时间已到，清除延迟状态
        g_temp_state.power_on_delay_active = false;
        ESP_LOGI(TAG, "开机延迟结束，系统正常运行");
        return true;
    }
    
    // 仍在延迟期内
    uint32_t remaining_time = (g_temp_state.power_on_time + 2) - current_time;
    ESP_LOGD(TAG, "开机延迟中，剩余时间: %lu秒", (unsigned long)remaining_time);
    return false;
}

/**
 * @brief 开关机控制函数
 * @details 获取OnOffState参数控制系统开关机
 *          OFF(0)：关风机，关闭所有阀门输出
 *          ON(1)：2s后恢复风机、阀门AO输出的开启条件
 */
esp_err_t output_control_onoff(void)
{
    // 获取当前开关机状态
    uint16_t current_onoff_state = GetOnOffState();
    uint32_t current_time = get_system_time_seconds();
    
    // 检查状态是否发生变化
    if (g_temp_state.onoff_state != current_onoff_state) {
        g_temp_state.onoff_state = current_onoff_state;
        
        if (current_onoff_state == 0) {
            // 切换到关机状态
            ESP_LOGI(TAG, "系统关机 - 启动关机流程");
            g_temp_state.power_on_delay_active = false;
            
            // 立即关闭阀门，但风机需要延迟关闭
            g_temp_state.ao2_output = 0;
            g_temp_state.ao3_output = 0;
            g_temp_state.cooling_active = false;
            g_temp_state.heating_active = false;
            
            // 重置阀门状态标志，避免状态保持
            g_temp_state.heat_valve_opened = false;
            g_temp_state.cool_valve_opened = false;
            
            // 重置阀门时间戳和输出值，确保开机后延迟控制生效
            g_temp_state.heat_valve_last_change_time = current_time;
            g_temp_state.cool_valve_last_change_time = current_time;
            g_temp_state.heat_valve_last_output = 0;  // 重置热阀输出记录
            g_temp_state.cool_valve_last_output = 0;  // 重置冷阀输出记录
            ESP_LOGI(TAG, "关机：重置阀门时间戳和输出值，确保开机后延迟控制生效");
            
            // 获取风机延迟关闭参数
            uint16_t fan_delay_off = GetFan_delay_off();
            if (fan_delay_off == 0) {
                fan_delay_off = 3;  // 默认3秒延迟
            }
        } else {
            // 切换到开机状态
            ESP_LOGI(TAG, "系统开机 - 启动2秒延迟，避免频繁开关机");
            g_temp_state.power_on_time = current_time;
            g_temp_state.power_on_delay_active = true;
        }
    }
    
    return ESP_OK;
}

/**
 * @brief 获取风机状态和阀门开度
 * @param fan_state 输出风机状态指针，1=运行，0=停止
 * @param valve_opening 输出阀门开度指针，制热时返回热阀开度，制冷时返回冷阀开度
 * @return ESP_OK成功，其他失败
 */
esp_err_t get_oc_fan_valve_state(uint8_t *fan_state, uint8_t *valve_opening)
{
    // 参数有效性检查
    if (!fan_state || !valve_opening) {
        ESP_LOGE(TAG, "get_oc_fan_valve_state: 无效参数");
        return ESP_ERR_INVALID_ARG;
    }
    
    // 1. 获取风机状态：风机输出不为0时为运行状态
    *fan_state = fan_state_dis;//(g_temp_state.ao1_output > 0) ? 1 : 0;
    
    // 2. 根据当前运行状态确定阀门开度
    if (g_temp_state.heating_active) {
        // 当前为制热状态，返回热阀(AO2)开度
        *valve_opening = g_temp_state.ao2_output;
        ESP_LOGD(TAG, "制热状态 - 风机:%s, 热阀开度:%d%%", 
                 *fan_state ? "运行" : "停止", *valve_opening);
    } else if (g_temp_state.cooling_active) {
        // 当前为制冷状态，返回冷阀(AO3)开度
        *valve_opening = g_temp_state.ao3_output;
        ESP_LOGD(TAG, "制冷状态 - 风机:%s, 冷阀开度:%d%%", 
                 *fan_state ? "运行" : "停止", *valve_opening);
    } else {
        // 既不制热也不制冷（通风模式或待机状态），阀门开度为0
        *valve_opening = 0;
        ESP_LOGD(TAG, "通风/待机状态 - 风机:%s, 阀门开度:0%%", 
                 *fan_state ? "运行" : "停止");
    }
    
    return ESP_OK;
}

/**
 * @brief 房卡节能控制函数
 * @details 根据思维导图实现房卡节能功能：
 *          - 无房卡功能：get_roomcard_detect()返回0xFF时，跳过处理
 *          - 有房卡功能：
 *            - 在位(==1)：按正常温度设定运行（无需调整）
 *            - 不在位(==0)：按节能温度运行
 *              - 制冷模式：使用ECO_Cool温度
 *              - 制热模式：使用ECO_Heat温度  
 *              - 自动模式：按制冷激活状态调用SetSetPoint()
 * @return ESP_OK成功，其他失败
 */
static esp_err_t roomcard_energy_saving_control(void)
{
    /*进入节能当前温度/温标拷贝*/
    static float temp_set_record = 0xffff;
    static uint16_t temperature_unit_record = 0xffff;//Gettemperature_unit();
    static int roomcard_status_record = 0xffff;

    // 获取房卡检测状态
    int roomcard_status = get_roomcard_detect();
    
    if(roomcard_status_record != roomcard_status)
    {
        roomcard_status_record = roomcard_status;
        /*防卡不在位*/
        if(roomcard_status == 0)
        {
            temp_set_record = GetSetPoint();
            temperature_unit_record = Gettemperature_unit();
        }

        /*防卡在位*/
        if(roomcard_status == 1)
        {
            if(temp_set_record !=0xffff)
            {
                if(temperature_unit_record == Gettemperature_unit())
                {
                    SetSetPoint(temp_set_record);
                }
                else
                {
                    if(Gettemperature_unit() == 0)
                    {
                        /*转为摄氏度*/
                        temp_set_record = (temp_set_record - 32)*5 /9 + 0.5f;
                        SetSetPoint(temp_set_record);
                    }
                    else
                    {
                        /*转为华氏度*/
                        temp_set_record = (temp_set_record*9 /5 + 32 + 0.5f);
                        SetSetPoint(temp_set_record);
                    }
                }
            }
        }
    }

    // 无房卡功能（External_Input != 2），跳过节能控制
    if (roomcard_status == 0xFF) {
        ESP_LOGV(TAG, "无房卡功能，跳过节能控制");
        return ESP_OK;
    }
    
    // 有房卡功能
    if (roomcard_status == -1) {
        // 房卡检测未初始化：跳过节能控制，等待检测完成
        ESP_LOGV(TAG, "房卡检测未初始化，跳过节能控制");
        return ESP_OK;
    } else if (roomcard_status == 1) {
        // 房卡在位：按正常温度设定运行，无需调整
        ESP_LOGV(TAG, "房卡在位，按正常温度运行");
        return ESP_OK;
    } else if (roomcard_status == 0) {
        // 房卡不在位：按节能温度运行
        uint16_t work_mode = GetWork_mode();
        uint16_t eco_heat = GetECO_Heat();
        uint16_t eco_cool = GetECO_Cool();
        float current_setpoint = GetSetPoint();
        float target_setpoint = current_setpoint;  // 默认保持当前设定
        bool need_update = false;
        
        ESP_LOGD(TAG, "房卡不在位，执行节能控制 - 工作模式:%d, 当前设定:%.1f°C, ECO制热:%d°C, ECO制冷:%d°C", 
                 work_mode, current_setpoint, eco_heat, eco_cool);

        /*防卡不在位需要记录设定温度/温标*/
        
        
        switch (work_mode) {
            case WORK_MODE_COOL:
                // 制冷模式：使用ECO_Cool温度
                target_setpoint = (float)eco_cool;
                if (fabs(current_setpoint - target_setpoint) > 0.1f) {
                    need_update = true;
                    ESP_LOGI(TAG, "制冷模式节能：设定温度 %.1f°C → %.1f°C", current_setpoint, target_setpoint);
                }
                break;
                
            case WORK_MODE_HEAT:
                // 制热模式：使用ECO_Heat温度
                target_setpoint = (float)eco_heat;
                if (fabs(current_setpoint - target_setpoint) > 0.1f) {
                    need_update = true;
                    ESP_LOGI(TAG, "制热模式节能：设定温度 %.1f°C → %.1f°C", current_setpoint, target_setpoint);
                }
                break;
                
            case WORK_MODE_AUTO:
                // 自动模式：根据当前激活状态决定使用哪个节能温度
                if (g_temp_state.cooling_active) {
                    // 当前制冷激活，使用ECO_Cool
                    target_setpoint = (float)eco_cool;
                    if (fabs(current_setpoint - target_setpoint) > 0.1f) {
                        need_update = true;
                        ESP_LOGI(TAG, "自动模式(制冷激活)节能：设定温度 %.1f°C → %.1f°C", current_setpoint, target_setpoint);
                    }
                } else if (g_temp_state.heating_active) {
                    // 当前制热激活，使用ECO_Heat
                    target_setpoint = (float)eco_heat;
                    if (fabs(current_setpoint - target_setpoint) > 0.1f) {
                        need_update = true;
                        ESP_LOGI(TAG, "自动模式(制热激活)节能：设定温度 %.1f°C → %.1f°C", current_setpoint, target_setpoint);
                    }
                } else {
                    // 自动模式但无激活状态：保持当前设定，等待激活后再调整
                    ESP_LOGV(TAG, "自动模式无激活状态，保持当前设定温度");
                }
                break;
                
            case WORK_MODE_FAN:
                // 通风模式：无阀门输出，不需要节能控制
                ESP_LOGV(TAG, "通风模式，跳过节能控制");
                break;
                
            default:
                ESP_LOGW(TAG, "未知工作模式：%d，跳过节能控制", work_mode);
                break;
        }
        
        // 更新设定温度
        if (need_update) {
            SetSetPoint(target_setpoint);
            ESP_LOGI(TAG, "房卡节能：设定温度已更新为 %.1f°C", target_setpoint);
        }
        
    } else {
        // 房卡检测失败或其他状态
        ESP_LOGW(TAG, "房卡检测状态异常：%d", roomcard_status);
    }
    
    return ESP_OK;
}