pymodbus-dev / pymodbus

A full modbus protocol written in python
Other
2.29k stars 938 forks source link

Failure of cpp client connect to pymodbus #1877

Closed HackersSpirit closed 12 months ago

HackersSpirit commented 1 year ago

Versions

Python: 3.11.4 OS: Ubuntu 23.04 Pymodbus: 3.0.0rc1

Pymodbus Specific

Description

Task: I am attempting to run an asynchronous server by invoking a provided program using a C++ program with execlp.

Issue: Sometimes, my C++ client fails to establish a connection with the server. I have attempted to clear the client context in my application, but I am unable to discern the issue from the server logs. When the client fails, the only logs I receive are as follows:

[MainThread ] [INFO ] Entering the modpi script [MainThread ] [INFO ] Going to start the server [MainThread ] [DEBUG] Using selector: EpollSelector Due to the absence of logs on the server, I am uncertain whether the server has received the request or not whether client fails due to port blocked by server

Code and Logs

import random
import logging
import time
import sys,os,signal
from pymodbus.datastore import ModbusSequentialDataBlock, ModbusSlaveContext, ModbusServerContext
from pymodbus.server.async_io import StartTcpServer
from pymodbus.exceptions import ModbusException
from pymodbus.pdu import ExceptionResponse

class ModbusSimulator:
    ## Initialize and start the Modbus TCP server.
    #
    # @param address: The address on which the server should listen (e.g., ("localhost", 5020)).
    def __init__(self, address):
        self.address = address
        self.log = self.setup_logging()
        self.setup_registers()

        # Register signal handlers to capture exit signals
        signal.signal(signal.SIGINT, self.cleanup_and_exit)
        signal.signal(signal.SIGTERM, self.cleanup_and_exit)

        self.log.info("Entering the modpi script")

        self.log.info("Going to start the server")

        if self.start_server():
            self.logger.info("Server started successfully.")
        else:
            self.logger.error("Server failed to start.")

    ## Set up logging for the Modbus server.
    def setup_logging(self):
        current_time = time.strftime("%Y-%m-%d_%H-%M-%S") 
        log_file_name = f"modsim_{current_time}.log"
        logFormatter = logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]  %(message)s")

        log = logging.getLogger()
        log.setLevel(logging.DEBUG)

        fileHandler = logging.FileHandler(log_file_name)
        fileHandler.setFormatter(logFormatter)
        log.addHandler(fileHandler)

        consoleHandler = logging.StreamHandler()
        consoleHandler.setFormatter(logFormatter)
        log.addHandler(consoleHandler)

        return log

    ## Define the Modbus registers and set initial values.
    def setup_registers(self):
        coils = ModbusSequentialDataBlock(1, [False] * 100)
        discrete_inputs = ModbusSequentialDataBlock(1, [False] * 100)
        holding_registers = ModbusSequentialDataBlock(1, [0] * 100)
        input_registers = ModbusSequentialDataBlock(1, [0] * 100)

        temperature_values = [random.randint(4, 15) for _ in range(7)]
        holding_registers.setValues(1, temperature_values)

        print("temperature_values:", temperature_values)
        print("Printing value inside holding register", holding_registers.getValues(4))

        # Define the Modbus slave context
        slave_context = ModbusSlaveContext(
            di=discrete_inputs,
            co=coils,
            hr=holding_registers,
            ir=input_registers
        )

        # Define the Modbus server context
        self.server_context = ModbusServerContext(slaves=slave_context, single=True)

    ## Start the Modbus TCP server.
    def start_server(self):
        try:
            StartTcpServer(context=self.server_context, identity=None, address=self.address)
            self.log.info("Server started sccessfully")
            return True 
        except ModbusException as e:
            self.logger.error("An error occurred during server startup:", exc_info=True)  # Log the exception
            self.log.error("Failed to start the server")
            return False  # Server failed to start

    def cleanup_and_exit(self, signum, frame):
        self.log.info("Received exit signal. Cleaning up and exiting...")
        self.server_context = None  # Release the server context
        sys.exit(0)

if __name__ == "__main__":
    server = ModbusSimulator(("localhost", 1502))

# please use the following to format logs when posting them here
import pymodbus

pymodbus.pymodbus_apply_logging_config()
janiversen commented 1 year ago

Please use our debug call in your client py script, that will provide you with more detailed information (see our examples).

janiversen commented 1 year ago

I am confused, you write you use the async server but your code is sync.

HackersSpirit commented 1 year ago

@janiversen : My both issue are interlinked please refer Issue in installing pymodbus #1876

HackersSpirit commented 1 year ago

Please use our debug call in your client py script, that will provide you with more detailed information (see our examples).

Are you refering to the following in examples

_logger = logging.getLogger(file) _logger.setLevel("DEBUG")

janiversen commented 1 year ago

No look at the last line of the code you supplied.

I am still confused your example is NOT async, and the issues might be interlinked, but seems quite different to me. Maybe first get version 3.54 installed.

janiversen commented 1 year ago

Still open ?

janiversen commented 12 months ago

Closed due to lack of activity.