//
// Created by DELL on 2024/10/16.
//

#include "ffx_master.h"
#include "modbus.h"
#include "usart.h"
#include "cmsis_os2.h"
#include "mini_gateway_master.h"
#include "modbus_slave.h"

static nmbs_t nmbs;
static uint8_t slaves[5] = {0}; // 保存已经存在的从站号
static uint8_t index = 0;
void search_ffx_slave();


static int32_t uart_read(uint8_t *buf, uint16_t count, int32_t byte_timeout_ms,
                         void *arg)
{
    HAL_StatusTypeDef status = HAL_UART_Receive(&huart2, buf, count, byte_timeout_ms);
    if (status == HAL_OK)
    {
        return count;
    } else
    {
        return 0;
    }
}

static int32_t uart_write(const uint8_t *buf, uint16_t count, int32_t byte_timeout_ms,
                          void *arg)
{
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
    HAL_UART_Transmit(&huart2, buf, count, byte_timeout_ms);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
    return count;
}

_Noreturn void ffx_poll_task(void *pv){
    for (;;)
    {
        search_ffx_slave();
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
        osDelay(1000 * 60);
    }
}
_Noreturn void ffx_mater_task(void *pv)
{
    for (;;)
    {
        ffx_status_t ffxStatus;
        bool is_power_on = false;
        for (int i = 0; i < sizeof(slaves); i++)
        {
            if (slaves[i] != 0)
            {
                nmbs_set_destination_rtu_address(&nmbs, slaves[i]);
                uint16_t data[10];
                uint16_t inner_data[1];
                nmbs_error err = nmbs_read_holding_registers(&nmbs, POWER_FFX_ADDRESS, 2, data);
                osDelay(200);
                nmbs_read_holding_registers(&nmbs, INNER_NUM_FFX_ADDRESS, 1, &inner_data[0]);
                osDelay(200);
                nmbs_read_holding_registers(&nmbs, SET_TEMP_FFX_ADDRESS, 1, &data[2]);
                osDelay(200);
                nmbs_read_holding_registers(&nmbs, FAN_SPEED_FFX_ADDRESS, 1, &data[3]);
                osDelay(200);
                nmbs_read_holding_registers(&nmbs, TEMP_ON_FFX_ADDRESS, 1, &data[4]);
                osDelay(200);
                nmbs_read_holding_registers(&nmbs, TEMP_OFF_FFX_ADDRESS, 1, &data[5]);
                if (err == NMBS_ERROR_NONE)
                {
                    ffxStatus.power = data[0];
                    ffxStatus.mode = data[1];
                    ffxStatus.set_temp = data[2];
                    ffxStatus.fan_speed = data[3];
                    ffxStatus.inner_num = inner_data[0];
                    if (ffxStatus.power && !(is_power_on))
                    {
                        is_power_on = true;
                        set_reg_value(POWER_REG_ADDRESS, ffxStatus.power);
                        set_reg_value(WORK_MODE_REG_ADDRESS, ffxStatus.mode);
                        set_reg_value(INNER_REG_ADDRESS, ffxStatus.inner_num);
                        set_reg_value(FAN_SPEED_REG_ADDRESS, ffxStatus.fan_speed);
                        set_reg_value(SET_TEMP_REG_ADDRESS, ffxStatus.set_temp);
                        set_reg_value(TEMP_ON_FFX_ADDRESS, data[4]);
                        set_reg_value(TEMP_OFF_FFX_ADDRESS, data[5]);
                    }
                    sync_ac_status(&ffxStatus);
                }
                osDelay(500);
            }
        }
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_12);// LED闪烁
        if ((ffxStatus.power == 0) && (is_power_on == false))
        {
            set_reg_value(POWER_REG_ADDRESS, ffxStatus.power);
        }
    }
}

// 检测从机是否存在
bool check_slave_exist(uint8_t slave_addr)
{
    nmbs_set_destination_rtu_address(&nmbs, slave_addr);
    uint16_t result;
    HAL_Delay(300);
    nmbs_error err = nmbs_read_holding_registers(&nmbs, 0x01, 1, &result);
    return err == NMBS_ERROR_NONE;
}

// 轮询从站
void search_ffx_slave()
{
    for (int i = SLAVE_ADDRESS_START; i <= SLAVE_ADDRESS_END; i++)
    {
        bool exist = check_slave_exist(i);
        if (exist)
        {
            slaves[index] = i;
            index++;
        }
//        HAL_Delay(500);
    }
    index = 0;
}

void ffx_master_init()
{
    nmbs_platform_conf platformConf;// 配置uart
    platformConf.transport = NMBS_TRANSPORT_RTU;// RTU
    platformConf.read = &uart_read;     // 读写函数
    platformConf.write = &uart_write;   // 读写函数
    nmbs_client_create(&nmbs, &platformConf);// 创建客户端
    nmbs_set_read_timeout(&nmbs, 100);
    nmbs_set_byte_timeout(&nmbs, 100);
//    search_ffx_slave();
    // 开启轮询任务
    osThreadNew(ffx_poll_task, NULL, NULL);
    osThreadNew(ffx_mater_task, NULL, NULL);
}

