#include "acrel_DJSF1352RN.h"


int ccu_DCMeter_init(DCMeter_t* dev, const char* devname)
{
    if (dev)
    {
        dev->salve = 0x1;
        com_ttySx_init(&dev->tty, devname, 9600, 8, 'N', 1);
        com_ttySx_rs485_enable(&dev->tty, 1);
        pthread_mutex_init(&dev->mutex, NULL);
        return 0;
    }
    return -1;
}

/*****************************************************************************************
 * 功能描述: 获取直流电表A端口电压
 *****************************************************************************************/
float ccu_DCMeterA_readV(DCMeter_t* dev)
{
    if (dev)
    {
        uint16_t value[4];
        //pthread_mutex_lock(&dev->mutex);
        if (modbus_RTU_read_holding_registers(&dev->tty, dev->salve+0, 0, 2, value) == 0)
        {
            float readV = (float)value[0];
            float power = (float)value[1] - 3;
            readV = readV * powf(10, power);
            dev->current_V[0] = readV;
            // mlog_v("meter[%d]->V:%f\n", dev->salve+0, dev->current_V[0]);
        }
        //pthread_mutex_unlock(&dev->mutex);
    }
    return dev->current_V[0];
}

/*****************************************************************************************
 * 功能描述: 获取直流电表B端口电压
 *****************************************************************************************/
float ccu_DCMeterB_readV(DCMeter_t* dev)
{
    if (dev)
    {
        uint16_t value[4];
        //pthread_mutex_lock(&dev->mutex);
        if (modbus_RTU_read_holding_registers(&dev->tty, dev->salve+1, 0, 2, value) == 0)
        {
            float readV = (float)value[0];
            float power = (float)value[1] - 3;
            readV = readV * powf(10, power);
            dev->current_V[1] = readV;  
            // mlog_v("meter[%d]->V:%f\n", dev->salve+1, dev->current_V[1]);
        }
        //pthread_mutex_unlock(&dev->mutex);
    }
    return dev->current_V[1];
}

/*****************************************************************************************
 * 功能描述: 获取直流电表A端口电流
 *****************************************************************************************/
float ccu_DCMeterA_readI(DCMeter_t* dev)
{
    if (dev)
    {
        uint16_t value[4];
        //pthread_mutex_lock(&dev->mutex);
        if (modbus_RTU_read_holding_registers(&dev->tty, dev->salve+0, 2, 2, value) == 0)
        {
            float readV = (float)value[0];
            float power = (float)value[1] - 3;
            readV = readV * powf(10, power);
            dev->current_I[0] = readV;
            // mlog_v("meter[%d]->I:%f\n", dev->salve+0, dev->current_I[0]);
        }
        //pthread_mutex_unlock(&dev->mutex);
    }
    return dev->current_I[0];
}

/*****************************************************************************************
 * 功能描述: 获取直流电表B端口电流
 *****************************************************************************************/
float ccu_DCMeterB_readI(DCMeter_t* dev)
{
    if (dev)
    {
        uint16_t value[4];
        //pthread_mutex_lock(&dev->mutex);
        if (modbus_RTU_read_holding_registers(&dev->tty, dev->salve+1, 2, 2, value) == 0)
        {
            float readV = (float)value[0];
            float power = (float)value[1] - 3;
            readV = readV * powf(10, power);
            dev->current_I[1] = readV;
            // mlog_v("meter[%d]->I:%f\n", dev->salve+1, dev->current_I[1]);
        }
        //pthread_mutex_unlock(&dev->mutex);
    }
    return dev->current_I[1];
}

/*****************************************************************************************
 * 功能描述: 获取直流电表A端口功率
 *****************************************************************************************/
float ccu_DCMeterA_readP(DCMeter_t* dev)
{
    if (dev)
    {
        uint16_t value[4];
        //pthread_mutex_lock(&dev->mutex);
        if (modbus_RTU_read_holding_registers(&dev->tty, dev->salve+0, 8, 2, value) == 0)
        {
            float readV = (float)value[0];
            float power = (float)value[1] - 3 - 3;
            readV = readV * powf(10, power);
            dev->current_P[0] = readV;
        }
        //pthread_mutex_unlock(&dev->mutex);
    }
    return dev->current_P[0];
}

/*****************************************************************************************
 * 功能描述: 获取直流电表A端口功率
 *****************************************************************************************/
float ccu_DCMeterB_readP(DCMeter_t* dev)
{
    if (dev)
    {
        uint16_t value[4];
        //pthread_mutex_lock(&dev->mutex);
        if (modbus_RTU_read_holding_registers(&dev->tty, dev->salve+1, 8, 2, value) == 0)
        {
            float readV = (float)value[0];
            float power = (float)value[1] - 3 - 3;
            readV = readV * powf(10, power);
            dev->current_P[1] = readV;  
        }
        //pthread_mutex_unlock(&dev->mutex);
    }
    return dev->current_P[1];
}

/*****************************************************************************************
 * 功能描述: 获取直流电表A端口总电量
 *****************************************************************************************/
float ccu_DCMeterA_readE(DCMeter_t* dev)
{
    if (dev)
    {
        uint16_t value[4];
        //pthread_mutex_lock(&dev->mutex);
        if (modbus_RTU_read_holding_registers(&dev->tty, dev->salve+0, 12, 2, value) == 0)
        {
            dev->current_E[0] = (float)((value[0]<<16)|value[1])/1000;
        }
        //pthread_mutex_unlock(&dev->mutex);
    }
    return dev->current_E[0];
}

/*****************************************************************************************
 * 功能描述: 获取直流电表B端口总电量
 *****************************************************************************************/
float ccu_DCMeterB_readE(DCMeter_t* dev)
{
    if (dev)
    {
        uint16_t value[4];
        if (modbus_RTU_read_holding_registers(&dev->tty, dev->salve+1, 12, 2, value) == 0)
        {
            dev->current_E[1] = (float)((value[0]<<16)|value[1])/1000;
        }
    }
    return dev->current_E[1];
}

static float uint16_to_float(uint16_t value, uint16_t power3)
{
    float readV = (float)value;
    float power = (float)power3 - 3;
    return readV * powf(10, power);
}

void ccu_DCMeterA_check(DCMeter_t* dev, float* VMeter, float* IMeter, float* PMeter, float* EMeter)
{
    if (dev)
    {
        uint16_t value[16];
        if (modbus_RTU_read_holding_registers(&dev->tty, dev->salve+0, 0, 14, value) == 0)
        {
            dev->current_V[0] = uint16_to_float(value[0], value[1]);
            dev->current_I[0] = uint16_to_float(value[2], value[3]);
            dev->current_P[0] = uint16_to_float(value[8], value[9]);
            dev->current_E[0] = (float)((value[12]<<16)|value[13])/1000;
        }
        if (VMeter) *VMeter = dev->current_V[0];
        if (IMeter) *IMeter = dev->current_I[0];
        if (PMeter) *PMeter = dev->current_P[0];
        if (EMeter) *EMeter = dev->current_E[0];
    }
}

void ccu_DCMeterB_check(DCMeter_t* dev, float* VMeter, float* IMeter, float* PMeter, float* EMeter)
{
    if (dev)
    {
        uint16_t value[16];
        if (modbus_RTU_read_holding_registers(&dev->tty, dev->salve+1, 0, 14, value) == 0)
        {
            dev->current_V[1] = uint16_to_float(value[0], value[1]);
            dev->current_I[1] = uint16_to_float(value[2], value[3]);
            dev->current_P[1] = uint16_to_float(value[8], value[9]);
            dev->current_E[1] = (float)((value[12]<<16)|value[13])/1000;
        }
        if (VMeter) *VMeter = dev->current_V[1];
        if (IMeter) *IMeter = dev->current_I[1];
        if (PMeter) *PMeter = dev->current_P[1];
        if (EMeter) *EMeter = dev->current_E[1];   
    }
}


void ccu_DCMeter_exit(DCMeter_t* dev)
{
    if(dev)
    {
        com_ttySx_rs485_enable(&dev->tty, 0);
        com_ttySx_exit(&dev->tty);
        pthread_mutex_destroy(&dev->mutex);
    }
}