#pragma once

#define DEBUGLOG_DEFAULT_LOG_LEVEL_INFO

#include <DebugLog.h>
#include <RS485_Driver.h>

namespace drivers
{

    class S50140
    {
    private:
        const uint8_t maxRetries = 5;
        const uint8_t dataWords = 2;
        const uint16_t minDelay = 500;

        const uint16_t REG_V = 0x100C;
        const uint16_t REG_A = 0x1016;
        const uint16_t REG_Pact = 0x1026;
        const uint16_t REG_Papp = 0x102E;
        const uint16_t REG_Prea = 0x1036;
        const uint16_t REG_Freq = 0x1038;
        const uint16_t REG_Pf = 0x101E;
        const uint16_t REG_WhTot = 0x1106;
        const uint16_t REG_WhPart = 0x1400;
        const uint16_t REG_Serial = 0x0500;
        const uint16_t REG_Regset = 0x0538;
        const uint16_t REG_PartCount = 0x0526;

        typedef union
        {
            float_t f;
            struct
            {
                uint16_t hi;
                uint16_t lo;
            } words;
        } floatval_t;

    public:
        typedef struct
        {
            float_t v;
            float_t a;
            float_t pAct;
            float_t pApp;
            float_t pRea;
            float_t pf;
            float_t f;
            float_t whTot;
            float_t whPar;
        } powerinfo_t;

    public:
        S50140(drivers::MODBUS &bus, const uint8_t address);
        ~S50140();

        const powerinfo_t getAll();

        const float_t getV();
        const float_t getA();
        const float_t getPact();
        const float_t getPapp();
        const float_t getPrea();
        const float_t getPf();
        const float_t getF();
        const float_t getWhTot();
        const float_t getWhPar();

        const uint8_t getRegset();
        const uint16_t getCounterStatus();

        void resetPartialCounters();

    private:
        void delayRequest();
        float_t readFloatReg(const uint16_t reg);

    private:
        const uint8_t m_address;
        drivers::MODBUS &m_bus;
        uint64_t m_lastRequest;
    };
}