/***************************************************************************** * Copyright (c) 2022 Priva b.v. *****************************************************************************/ #pragma once #include "ConnectionConfig.h" #include "IModbusAdapter.h" #include "modbus.h" // std #include #include #include /// @brief The ModbusAdapter class represents a single modbus context. Each context will /// result in an instance of this class. It is not intended to be /// created directly but through a factory. The factory will create /// the object and return the pointer to its interface. class ModbusAdapter : public IModbusAdapter { public: /*! * \brief Default constructor */ explicit ModbusAdapter(); /*! * \brief Default destructor */ virtual ~ModbusAdapter(); /*! * \brief /// Create a modbus connection, accepting a configuration object. */ bool ModbusConnect( const ConnectionConfig &conncfg ) override; /*! * \brief ModbusDisconnect * Disconnect from the serial bus or the TCP connection, freeing its resources */ bool ModbusDisconnect() override; /*! * \brief Read data from a modbus device given by its parameters. * \param slaveId - The Id of the ModbusDevice. * \param functionCode - The code describing the action we want to perform on the device. * Given by an enum, provided by the modbus-stack. * \param startAddress - Startaddres of the register we want to read. * \param noOfItems - The number of items we expect back. * \returns modbusData - A vector holding each register in an entry in the same order as they are received. * Empty if no data was received. */ modbusData ModbusReadData( int slaveId, int functionCode, int startAddress, int noOfItems ) override; /*! * \brief Read data from the holdregisters ( or keep-registers ) of a modbus device. * \param slaveId - The Id of the ModbusDevice. * \param startAddress - Startaddres of the register we want to read. * \param noOfItems - The number of items we expect back. * \returns modbusData - A vector holding each register in an entry in the same order as they are received. * Empty if no data was received. */ modbusData ModbusReadHoldReg( int slaveId, int startAddress, int noOfItems ) override; /*! * \brief Write data to the device. * \param slaveId - The Id of the Modbus device * \param funtionCode - The code describing the action we want to perform on the device * given by an enum, provided by the modbus-stack. * \param startAddress - Startaddres of the register we want to read. * \param noOfItems - The number of items we expect to be written * \param values - The values we want to write to the given device. Each vector-entry represents a single byte * and they will be sent in sequence. */ void ModBusWriteData( int slaveId, int functionCode, int startAddress, int noOfItems, std::vectorvalues ) override; /*! * \brief Indicates if this connection is alive. * \return True if alive, false if not. */ bool isConnected() const override; /*! * \brief returns the translated error code coming from the modbus stack. * \param errnum - error Number coming from the stack. * \return The translated error as a string. Empty if not resolvable. */ std::string ErrorString( int errnum ) const override; private: // Methods bool ModbusConnectRTU( const std::string &serialport, int baud, char parity, int dataBits, int stopBits, int RTS, int timeOut ); bool ModbusConnectTCP( const std::string &ip, int port, int timeOut = -1 ); void InitBuffers(); void ClearBuffers(); private: // Members ConnectionType m_connType { ConnectionType::CT_UNKNOWN }; ///> The type of connection this instance provides. Needed for administration bool m_connected { false }; ///> Shows if the connection is still active. modbus_t *m_modbus; ///> The actual low-level modbus instance as a raw-pointer. ( unique_pointer gives an error on this struct ) // Return value Buffers ( Room for improvement ) uint8_t *m_dest; uint16_t *m_dest16; };