#include "HLW8032.h"
#include "math.h"
/* Private defines -----------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
uint8_t first_run = 1;                    // 添加这行代码
float E_total = 0;                        // 累计电量
uint8_t UART4_RX_BUF[UART4_MAX_RECV_LEN]; // 改为UART4
uint8_t UART4_TX_BUF[UART4_MAX_SEND_LEN]; // 改为UART4
__IO uint16_t UART4_RX_STA;               // 改为UART4
float g_energy = 0;                       // 初始化为0
uint8_t link = 0;
volatile float analog_status[3] = {0};  // 定义并初始化数组
uint8_t k = 0;
uint16_t old_reg = 0, len = 0;
double V = 0, C = 0, P = 0, E_con = 0;
double base_energy = 0;           // EEPROM中的基准值
float last_minute_energy = 0;    // 上一分钟的电量值
float current_minute_energy = 0; // 当前分钟的电量值
void Apphl8032_Init(void)
{
    /* 初始化串口4 */
    MX_UART4_Init();
    
    // 使用HAL库的单字节接收中断
    HAL_UART_Receive_IT(&huart4, &aRxBuffer, 1);
    //从EEPROM读取累计电量
    base_energy = Load_Energy_From_EEPROM();
    analog_status[1] = base_energy; // 初始化为0
    last_minute_energy=0.0f;
    current_minute_energy=0.0f;
}

void Data_Processing(void)
{
    static uint32_t lastProcessTime = 0;
    static uint32_t lastSaveTime = 0;
    static uint32_t last_saved_energy =0.0f;
    uint32_t currentTime = HAL_GetTick();
    
    // 至少1秒处理一次
    if(currentTime - lastProcessTime < 1000)
    {
       // printf("Data processing skipped: less than 1 second since last processing.\r\n");
        UART4_RX_STA = 0;
        return;
    }

    if (UART4_RX_STA & 0x8000) // 接收完成
    {
      //  printf("Data reception complete. Processing data...\r\n");
        
        uint32_t VP_REG = 0, V_REG = 0; // 电压相关寄存器
        uint32_t CP_REG = 0, C_REG = 0; // 电流相关寄存器
        uint32_t PP_REG = 0, P_REG = 0; // 功率相关寄存器
        uint32_t PF = 0, PF_COUNT = 0;  // 电量相关寄存器
        uint32_t dat_sum = 0;           // 校验和

        // 计算校验和
        for (uint8_t i = 2; i < 23; i++)
        {
            dat_sum += UART4_RX_BUF[i];
        }

      //  printf("Calculated checksum: %lu, Received checksum: %02X\r\n", dat_sum % 256, UART4_RX_BUF[23]);

        if (dat_sum % 256 == UART4_RX_BUF[23]) // 校验和正确
        {
          //  printf("Checksum is valid.\r\n");

            // 1. 计算电压
            VP_REG = UART4_RX_BUF[2] * 65536 + UART4_RX_BUF[3] * 256 + UART4_RX_BUF[4];
            V_REG = UART4_RX_BUF[5] * 65536 + UART4_RX_BUF[6] * 256 + UART4_RX_BUF[7];
            if (V_REG != 0)
            {
                V = (VP_REG / V_REG) * 1.88;
              //  printf("Voltage calculated: V=%.2fV\r\n", V);
            }
            else
            {
              //  printf("V_REG is zero, voltage calculation skipped.\r\n");
            }

            // 2. 计算电流
            CP_REG = UART4_RX_BUF[8] * 65536 + UART4_RX_BUF[9] * 256 + UART4_RX_BUF[10];
            C_REG = UART4_RX_BUF[11] * 65536 + UART4_RX_BUF[12] * 256 + UART4_RX_BUF[13];
            if (C_REG != 0)
            {
                C = ((CP_REG * 100.0) / C_REG) / 100.0;
              //  printf("Current calculated: I=%.3fA\r\n", C);
            }
            else
            {
              //  printf("C_REG is zero, current calculation skipped.\r\n");
            }

            // 3. 计算功率
            PP_REG = UART4_RX_BUF[14] * 65536 + UART4_RX_BUF[15] * 256 + UART4_RX_BUF[16];
            P_REG = UART4_RX_BUF[17] * 65536 + UART4_RX_BUF[18] * 256 + UART4_RX_BUF[19];
            if (P_REG != 0)
            {
                P = (PP_REG / P_REG) * 1.88;
              //  printf("Power calculated: P=%.3fW\r\n", P);
            }
            else
            {
              //  printf("P_REG is zero, power calculation skipped.\r\n");
            }

            // 4. 计算电量
            if ((UART4_RX_BUF[20] & 0x80) != old_reg)
            {
                k++;
                old_reg = UART4_RX_BUF[20] & 0x80;
            }

            PF = (k * 65536) + (UART4_RX_BUF[21] * 256) + UART4_RX_BUF[22];
           // printf("Power factor calculated: PF=%lu\r\n", PF);

            if (P >= 0.0 && PP_REG != 0)
            {
                PF_COUNT = ((100000 * 3600) / (PP_REG * 1.88)) * 10000;
                current_minute_energy = ((PF * 10000.0) / PF_COUNT) / 10000.0;

                static uint32_t last_save_time = 0;
                uint32_t current_time = HAL_GetTick();

                // 每10秒打印一次当前状态
                if(current_time - last_save_time >= 10000) // 每10秒
                {
                 //  printf("Current Status:\r\n");
                 //  printf("V=%.2fV, I=%.3fA, P=%.3fW\r\n", V, C, P);
                  // printf("Current Energy=%.6f, Last Energy=%.6f\r\n", 
                   //       current_minute_energy, last_minute_energy);
                }

                // 每分钟计算一次增量
                if (current_time - last_save_time >= 60000) // 60秒
                {
                    float minute_increase = current_minute_energy - last_minute_energy;
                  //  printf("Minute increase: %.6f KWH\r\n", minute_increase);

                    // 添加保护，防止异常值
                    if (minute_increase > 0.0f && minute_increase < 1.0f)
                    {
                        base_energy += minute_increase;
                        analog_status[1] = base_energy;
                       if((base_energy - last_saved_energy >= 0.1f)|| (currentTime-lastSaveTime>300000))
                       {
                             Save_Energy_To_EEPROM(base_energy);
                             last_saved_energy=base_energy;
                       }
                    }
                    else
                    {
                      //  printf("Invalid energy increase: %.6f KWH\r\n", minute_increase);
                    }

                    last_minute_energy = current_minute_energy;
                    last_save_time = current_time;
                }
            }
            else
            {
              //  printf("Power or PP_REG is zero. P=%.3f, PP_REG=%lu\r\n", P, PP_REG);
            }
        }
        else
        {
          //  printf("Checksum is invalid.\r\n");
        }
    }
    
    lastProcessTime = currentTime;
    UART4_RX_STA = 0; // 这里可能需要调整
}

