#ifndef MODBUSRTU_H
#define MODBUSRTU_H

#include <QObject>
#include "modbus.h"
#include <QThread>
#include <QEventLoop>

class QTimer;

class ModbusRTU : public QThread
{
    Q_OBJECT
public:
    ModbusRTU(QObject *parent = nullptr);
    ~ModbusRTU();

public slots:
    void write_regs_slot(int addr, const uint16_t data);
    void read_regs_slot(int addr, int nb, uint16_t *data, int row);
    // void read_regs_input_slot_vol(int addr, int nb, uint16_t *data);
    // void read_regs_input_slot_temp(int addr, int nb, uint16_t *data);
    void change_BMUIndex_slot(int index);

public:
    modbus_t *m_ModbusRTUDevice;
    bool isConnect;
    const char *comPort;
    int baudRate;
    char parity;
    int dataBit;
    int stopBit;
    int BMUIndex = 0;
    bool closeThread = true;

public:
    void run() override;
    QEventLoop eventLoop;

private:

static constexpr int MODBUS_ERR = -1;

    enum DataType{
        TypeRecvData,
        TypeSendData
    };

public:
    void init();
    bool modbusRTUConnect(const char *comPort, int baudRate, char parity, int dataBit, int stopBit);
    void modbusRTUDisconnect();

    //0x01：读线圈状态: 00 01 00 00 00 06 01        01 67 89 00 05
    int read_coil_status(int addr, int nb, uint8_t *dest);
    //0x02：读离散量输入: 00 01 00 00 00 06 01      02 67 89 00 05
    int read_input_status(int addr, int nb, uint8_t *dest);
    //0x03：读保持寄存器: 00 01 00 00 00 06 01      03 67 89 00 05
    int read_holding_register(int addr, int nb, uint16_t *dest);
    //0x04：读输入寄存器: 00 01 00 00 00 06 01      04 67 89 00 05
    int read_input_register(int addr, int nb, uint16_t *dest);
    //0x05：写单个线圈: 00 01 00 00 00 06 01        05 67 89 FF 00
    int write_single_coil(int coil_addr, int status);
    //0x06：写单个保持寄存器: 00 01 00 00 00 06 01    06 67 89 12 34
    int write_single_register(int reg_addr, const uint16_t value);
    //0x0F（15）：写多个线圈: 00 01 00 00 00 08 01     0F 67 89 00 05 01 1F
    int write_multiple_coil(int addr, int nb, const uint8_t *data);
    //0x10（16）：写多个保持寄存器: 00 01 00 00 00 11 01   10 67 89 00 05 0A 00 00 00 00 00 00 00 00 00 05
    int write_multiple_registers(int addr, int nb, const uint16_t *data);

signals:
    void sig_ModbusRTUConnected();
    void sig_showModbusData(QByteArray byteArray, int dataType, uint16_t *data);
    void sig_showModbusData_sgl_tempt(QByteArray byteArray, int dataType, uint16_t *data);
    void sig_showModbusData_base_info1_45(QByteArray byteArray,int dataType, uint16_t *data);
    void sig_showModbusData_base_info57_78(QByteArray byteArray,int dataType, uint16_t *data);
    void sig_showModbusData_base_info83_106(QByteArray byteArray,int dataType, uint16_t *data);
    void sig_showModbusData_base_info47_49_51_53_55(QByteArray byteArray,int dataType);
    void sig_showModbusData_base_info_list_47_49_51_53_55(QList<int> byteArray,int dataType);
    void sig_showReadHoldingRegs(int row, int nb, uint16_t *data);
    void sig_showFault(QByteArray byteArray, int dataType, uint16_t *data);
    void paused();
    void resumed();


public slots:
    void slot_pauseThread();
    void slot_resumeThread();
};

#endif // MODBUSRTU_H
