// Guard for the header
#ifndef POWERMETER_H_
#define POWERMETER_H_

#include <Arduino.h>
#include <Wire.h>

// Typedef for the channel selection
typedef enum {
        CHA     = 0,
        CHB     = 1,
        CHC     = 2,
        CHD     = 3,
        CHE     = 4,
        CHF     = 5,
        NEUTRAL = 6,
        TOTAL   = 7
} PowerMeterChannel;


// Typedef for the kind of information selection
typedef enum {
        VRMS                    = 0,
        IRMS                    = 12,
        VPEAK                   = 24,
        IPEAK                   = 36,
        POWER_FACTOR            = 48,
        FREQUENCY               = 60,
        ACTIVE_POWER            = 66,
        REACTIVE_POWER          = 90,
        APPARENT_POWER          = 114,
        /* ACTIVE_ENERGY           = 138, */
        /* REACTIVE_ENERGY         = 162, */
        /* APPARENT_ENERGY         = 186 */
} _infoCommand;

// Typedef for the kind of information selection
typedef enum {
        RS232                   = 244,
        PLC                     = 243
} PowerMeterCommunication;

/**
* selectCom function
*
* This function select if the RS232 from the internal power meter will be listened by the PLC or will be send to the RS232 via external connector
* If this function is not call, the definited communication will be with the RS232
*
* This function requires a variable of the type PowerMeterCommunication with the channel will be converted
*
* This function does not return anything
*/
uint8_t selectCom(PowerMeterCommunication com);


/**
* get_VRMS function
*
* This function returns the value of the VRMS of the selected channel
*
* This function requires a variable of the type PowerMeterChannel with the channel will be converted
*
* This function returns one parameter:
*
* - uint32_t: Value that contains the value in mV of the selected channel
*/
uint32_t get_VRMS(PowerMeterChannel channel);

/**
* get_IRMS function
*
* This function returns the value of the IRMS of the selected channel
*
* This function requieres a variable of the type PowerMeterChannel with the channel will be converted
*
* This function returns one parameter:
*
* - uint32_t: Value that contains the value in uA of the selected channel
*/
uint32_t get_IRMS(PowerMeterChannel channel);

/**
* get_VPEAK function
*
* This function returns the value of the VPEAK of the selected channel
*
* This function requieres a variable of the type PowerMeterChannel with the channel will be converted
*
* This function returns one parameter:
*
* - uint32_t: Value that contains the value in mV of the selected channel
*/
uint32_t get_VPEAK(PowerMeterChannel channel);

/**
* get_IPEAK function
*
* This function returns the value of the IPEAK of the selected channel
*
* This function requieres a variable of the type PowerMeterChannel with the channel will be converted
*
* This function returns one parameter:
*
* - uint32_t: Value that contains the value in uA of the selected channel
*/
uint32_t get_IPEAK(PowerMeterChannel channel);

/**
* get_PowerFactor function
*
* This function returns the power factor of the selected channel
*
* This function requieres a variable of the type PowerMeterChannel with the channel will be converted
*
* This function returns one parameter:
*
* - uint32_t: Value that contains the power factor of the selected channel (e.g. 0.4251 = 4251)
*/
uint32_t get_PowerFactor(PowerMeterChannel channel);

/**
* get_Frequency function
*
* This function returns the value of the frequency of the selected channel
*
* This function requieres a variable of the type PowerMeterChannel with the channel will be converted
*
* This function returns one parameter:
*
* - uint16_t: Value that contains the value in Hz*100 of the selected channel
*/
uint16_t get_Frequency(PowerMeterChannel channel);

/**
* get_ActivePower function
*
* This function returns the value of the active power of the selected channel
*
* This function requieres a variable of the type PowerMeterChannel with the channel will be converted
*
* This function returns one parameter:
*
* - int64_t: Value that contains the value in uW of the selected channel
*/
int64_t get_ActivePower(PowerMeterChannel channel);

/**
* get_ReactivePower function
*
* This function returns the value of the reactive power of the selected channel
*
* This function requieres a variable of the type PowerMeterChannel with the channel will be converted
*
* This function returns one parameter:
*
* - int64_t: Value that contains the value in uVAr of the selected channel
*/
int64_t get_ReactivePower(PowerMeterChannel channel);

/**
* get_ApparentPower function
*
* This function returns the value of the apparent power of the selected channel
*
* This function requieres a variable of the type PowerMeterChannel with the channel will be converted
*
* This function returns one parameter:
*
* - int64_t: Value that contains the value in uVA of the selected channel
*/
int64_t get_ApparentPower(PowerMeterChannel channel);

/**
* get_AllInfo function
*
* This function returns all the information contained in the power meter
* Is useful for optimize I2C communication time
*
* This function requires a pointer with 211 available bytes
*
* This function returns 0 if the function detected some error. 1 in other cases.
*
* - From 0 to 0:        Contains the FW version of the power meter
* - From 1 to 4:        VRMS channel A
* - From 5 to 8:        VRMS channel B
* - From 9 to 12:       VRMS channel C
* - From 13 to 16:      IRMS channel A
* - From 17 to 20:      IRMS channel B
* - From 21 to 24:      IRMS channel C
* - From 25 to 28:      VPEAK channel A
* - From 29 to 32:      VPEAK channel B
* - From 33 to 36:      VPEAK channel C
* - From 37 to 40:      IPEAK channel A
* - From 41 to 44:      IPEAK channel B
* - From 45 to 48:      IPEAK channel C
* - From 49 to 52:      Power factor channel A
* - From 53 to 56:      Power factor channel B
* - From 57 to 60:      Power factor channel C
* - From 61 to 62:      Frequency channel A
* - From 63 to 64:      Frequency channel B
* - From 65 to 66:      Frequency channel C
* - From 67 to 74:      Active power channel A
* - From 75 to 82:      Active power channel B
* - From 83 to 90:      Active power channel C
* - From 91 to 98:      Reactive power channel A
* - From 99 to 106:     Reactive power channel B
* - From 107 to 114:    Reactive power channel C
* - From 115 to 122:    Apparent power channel A
* - From 123 to 130:    Apparent power channel B
* - From 131 to 138:    Apparent power channel C
*/
uint8_t get_AllInfo(uint8_t *info);



/**
* _returnPowerInfoUint32
*
* This private function returns the uint32_t information about some information of the power meter
*/
uint32_t _returnPowerInfoUint32(_infoCommand infoPosition);

/**
* _returnPowerInfoUint16
*
* This private function returns the uint16_t information about some information of the power meter
*/
uint16_t _returnPowerInfoUint16(_infoCommand infoPosition);

/**
* _returnPowerInfoUint64
*
* This private function returns the uint64_t information about some information of the power meter
*/
uint64_t _returnPowerInfoUint64(_infoCommand infoPosition);

/**
* _returnPowerInfoInt64
*
* This private function returns the int64_t information about some information of the power meter
*/
int64_t _returnPowerInfoInt64(_infoCommand infoPosition);

#endif
