0

I'm using the following code to try and send data as a ModbusTCP slave:

import socket
import logging

from pymodbus.constants import Defaults
from pymodbus.factory import ClientDecoder
from pymodbus.exceptions import NotImplementedException, ParameterException
from pymodbus.exceptions import ConnectionException
from pymodbus.transaction import ModbusSocketFramer, ModbusBinaryFramer
from pymodbus.client.common import ModbusClientMixin



#------------------------------------------------------------------#
#Logging
#------------------------------------------------------------------#
_logger = logging.getLogger(__name__)

##------------------------------------------------------------------##
##The Synchronous Clients
##------------------------------------------------------------------##

class BaseModbusClient(ModbusClientMixin):

    def __init__(self, framer, **kwargs):

        self.framer = framer
        if isinstance(self.framer, ModbusSocketFramer):
            self.transaction = DictTrasactionManager(self, **kwargs)
        else: self.transcation = FitoTransactionManager(self, **kwargs)

    def connect(self):
        raise NotImplementedException("Method not implemented by derived class")

    def close(self):
        pass

    def _send(self, request):
        raise NotImplementedException("Method not implemented by derived class")

    def _recv(self, size):
        raise NotImplementedException("Method not implemented by derived class")

    def excecute(self, request=None):
        if not self.connect():
            raise ConnectionException("Failed to connect[%s]" % (self.__str__()))
        return self.transaction.execute(request)


    def __enter__(self):
         if not self.connect():
             raise ConnectionException("Failed to connect [%s]" % (self.__str__()))
         raise self

    def __exit__(self, klass, value, traceback):
         self.close()

    def __str__(self):
         return "Null Transport"

class ModbusTcpClient(BaseModbusClient):

    def __init__(self, host='192.168.3.2', port=Defaults.Port, framer=ModbusSocketFramer, **kwargs):
        self.host = host
        self.port = port
        self.source_address = kwargs.get('source_address', ('', 0))
        BaseModbusClient.__init__(self,framer(ClientDecoder()), **kwargs)

    def connect(self):
        if self.socket: return True
        try:
            address = (self.host, self.port)
            self.socket = socket.create_connection((self.host, self.port),          timeout=Defaults.Timeout, source_address=self.source_address)
    except socket.error, msg:
        _logger.error('Connection to (%s, %s) failed: %s' % (self.host, self.port, msg))
        self.close()

    def close(self):
        if self.socket:
            self.socket.close()
        self.socket = None

    def _send(self, request):
        if not self.socket:
            raise ConnectionException(self.__str__())
        if request:
            return self.socket.send(request)
        return 0

    def _recv(self, size):
        if not self.socket:
            raise ConnectionException(self.__str__())
        return self.socket.recv(size)

    def __str__(self):
        return "%s:%s" % (self.host, self.port)

Now im willing to start and use all these functions. How do I start? should I just call the functions I need? My will is to connect to the master as a slave and change register values.

Thanks for the answers.

6
  • You should read the manual for the device you're trying to connect with and find out what the numbers are of the registers that you want to change. In the apps I've built with pymodbus, the only functions I've used frequently are the write_register and read_register method of the minimalmodbus.Instrument class. Commented Jan 11, 2015 at 11:59
  • Hi oliver, thanks for answering. I know the device ID and the registers I wish to change. I just can't seem to figure what needs to come first and how. to first open a connection to the server and read? what functions should I use?? Commented Jan 11, 2015 at 12:03
  • 1
    When I write a small script trying to connect I keep getting "from pymodbus.constants import Defauls - ImportError: No module named constants." can't figure it out, I don't use this module and even if I import it I get the same error.. Commented Jan 11, 2015 at 12:05
  • I need to make a correction before I lead you on the wrong track: In the apps I've built that needed the modbus protocol, I thought pymodbus was overkill, I just needed minimalmodbus. Commented Jan 11, 2015 at 12:08
  • would try that but it is written that modbus tcp is not supported.. Commented Jan 11, 2015 at 13:02

1 Answer 1

4

This should get you started.

from pymodbus.client.sync import ModbusTcpClient

#modbus connection
client = ModbusTcpClient('192.168.1.100')
connection = client.connect()

#read register
request = client.read_holding_registers(xxxx,3) #covert to float
result = request.registers

#write to register
client.write_registers(xxxx, [xxxx,xxxx,xxxx])
Sign up to request clarification or add additional context in comments.

2 Comments

Hey David, thanks for the answer. My connection is working but I have a problem with the read_holding_registers function. My device modbus address is 201, should I insert this address in the read_holding_registers function or should I insert the register address I want to read? because in this small script I do not use this "201" address anywhere. any idea??
Insert the register address you want to read. Example, my AI1 is register 40000. So I would write request = client.read_holding_registers(40000,3) result = request.registers. To verify the PLC is working correctly, download the OmniMBT program. It's a free download. Let me know if this doesn't make sense & I can explain differently.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.