// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*! \example modbus/server
    \title Modbus Server
    \ingroup qtserialbus-examples
    \meta category Connectivity

    \brief The example implements a Modbus server application.

    The example acts as Modbus server. It receives standard Modbus requests,
    adjusts its internal states based on the request and responds with the
    appropriate reply.

    This example must be used in conjunction with the
    \l {modbus/client}{Modbus Client example}.
    This example should be started and put into the listen state before the
    Modbus client example is started. Subsequent interactions between the two
    examples use the Modbus protocol.

    Key classes used in this example:

    \list
        \li \l QModbusServer
        \li \l QModbusDataUnit
    \endlist

    \image ../images/modbusserver.png

    \section1 Creating a QModbusServer

    An instance of \l QModbusServer is required to perform any communication.
    Depending on the specified connection type, the example can instantiate a
    \l QModbusRtuSerialServer (for serial communication) or a
    \l QModbusTcpServer (for TCP-based communication).

    \snippet modbus/server/mainwindow.cpp create_server_0

    Once the server is created, the register map is set using
    \l QModbusServer::setMap() method. This register map is used by client
    applications to read and write server data.

    \snippet modbus/server/mainwindow.cpp create_server_1

    After that the communication parameters and the server address are
    specified. The communication parameters depend on the communication type:

    \snippet modbus/server/mainwindow.cpp create_server_2

    After the server is created and all the parameters are specified, use
    \l QModbusServer::connectDevice() to connect to Modbus network.

    \section1 Changing Local Values

    The example allows to change values of all supported
    \l {QModbusDataUnit::RegisterType}{register types} by using the provided
    combo boxes or line edits. Once the value is updated in the UI, the
    \l QModbusServer::setData() method is used to update the actual value on
    the server:

    \snippet modbus/server/mainwindow.cpp update_data_locally

    \section1 Handling Remote Writes

    The Modbus clients are capable of updating \l {QModbusDataUnit::}{Coils}
    and \l {QModbusDataUnit::}{HoldingRegisters} by sending write requests.
    Once the value is updated on the server side using such request, a
    \l QModbusServer::dataWritten() signal is emitted.

    \snippet modbus/server/mainwindow.cpp connect_data_written

    The Modbus server example connects to this signal, extracts the updated
    values and updates the UI accordingly:

    \snippet modbus/server/mainwindow.cpp update_data_from_remote

    \include examples-run.qdocinc
*/
