Giter Club home page Giter Club logo

pymodbus's People

Contributors

alexandrecuer avatar alexrudd2 avatar altendky avatar bashwork avatar bje- avatar canpolat avatar cavaler avatar ccatterina avatar chkr-private avatar couling avatar dependabot[bot] avatar dhoomakethu avatar dices avatar fredo70 avatar ilkka-ollakka avatar imba-tjd avatar jamesbraza avatar janiversen avatar jonmills avatar karlp avatar lsgunth avatar pjkundert avatar rahulraghu94 avatar semyont avatar sjlongland avatar starnight avatar thormick avatar tracernz avatar wlcrs avatar yegorich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pymodbus's Issues

ReadFileRecordResponse <calculateRtuFrameSize> calculates invalid size

Working on current SVN trunk, Revision r176
Code to reproduce:

records = []
records.append(FileRecord(file_number=26, record_number=0, record_length=1))
request = ReadFileRecordRequest(records)
request.unit_id = 4

    rq = c.client.execute(request)

Problem:

  • When calculating the response frame, the function ReadFileRecordResponse.calculateRtuFrameSize will have the whole frame as argument in including address and function code.

If changed from
byte_count = struct.unpack('B', buffer[0])[0]
to
byte_count = struct.unpack('B', buffer[2])[0] + 5
the function starts to work correctly.

Finish Adding Functional Tests

Finish adding the functional tests for all the server code and finish the unit test for the remainder of the server/client code.

Make sure that we are also using correct reference implementations (jamod, modpoll, etc) for each test:

  • sync/async server
  • sync/async client
  • special contexts

Change protocol to only read what it needs

Right now we are just reading until we get a full packet (which made for easy async stream handling), however, it messes with the serial implementations. What needs to happen is the header size needs to be read and then based on that, the exact amount specified there needs to be read. This would make the RTU implementation more reliable and fix the timeout issue with the serial libraries.

Incomplete data received from pl1000e module

Using ModbusTcpClient to connect to pl1000e module I received only the first part of the response and not the registers for some of them (firmware MAY05).
After investigation it semms that the tcp response is send as two sequences
.
If I add this line to transaction.py (line 68) everything is ok
result = self.client._recv(1024)
++ if len([hex(ord(x)) for x in result]) <= 7:
++ result += self.client._recv(1024)
Do you have any idea to solve this problem with a better solution ?
Thank you and sorry for my english

Timeout for ModbusUdpClient

If the slave stops, the UDP client realized with pymodbus hangs (on OS X). There seems to be no way to specify a timeout on the underlying socket as for the ModbusSerialClient. The following would allow to use a timeout argument using the newly passed down kwargs.

class ModbusUdpClient(BaseModbusClient):
    def __init__(self, host='127.0.0.1', port=Defaults.Port,
        framer=ModbusSocketFramer, **kwargs):
        ''' Initialize a client instance

        :param host: The host to connect to (default 127.0.0.1)
        :param port: The modbus port to connect to (default 502)
        :param framer: The modbus framer to use (default ModbusSocketFramer)
        '''
        self.host = host
        self.port = port
        self.socket = None
        self.timeout  = kwargs.get('timeout',  Defaults.Timeout)
        BaseModbusClient.__init__(self, framer(ClientDecoder()),**kwargs)

    def connect(self):
        ''' Connect to the modbus tcp server

        :returns: True if connection succeeded, False otherwise
        '''
        if self.socket: return True
        try:
            family = ModbusUdpClient._get_address_family(self.host)
            self.socket = socket.socket(family, socket.SOCK_DGRAM)
            self.socket.settimeout(self.timeout)
        except socket.error, ex:
            _logger.error('Unable to create udp socket %s' % ex)
            self.close()
        return self.socket != None

An update on the python3 build would be nice too.

Thanks,
Marko

ModbusClientFactory question/issue

I have multiple tcp modbus devices - http://www.advantech.com/products/ADAM-6017/mod_426AC8AA-4C77-4E4E-AED7-B41B9B387CF9.aspx that I'm polling on a recurring basis.

Below is a test script I wrote with pymodbus - in my output you'll notice that my deferredlist isn't firing until after Ctrl-C is hit...it's almost like there's a bit of synchronous code holding it up - Any feedback would be appreciated:

from twisted.internet import reactor, protocol, defer
from pymodbus.payload import PayloadDecoder
from pymodbus.client.async import ModbusClientProtocol, ModbusClientFactory
from pymodbus.exceptions import ConnectionException

class Advantech6017ClientProtocol(ModbusClientProtocol):

def connectionMade(self):
    print "connection made"
    ModbusClientProtocol.connectionMade(self);
    self.factory.setClient(self)

def read_ai(self):
    print self
    return self.read_input_registers(address = 0, count = 8, unit = 1)

class Advantech6017Factory(protocol.ReconnectingClientFactory):

protocol = Advantech6017ClientProtocol

def setClient(self, client):
    self.client = client

def read_device(self):
    return self.client.read_ai()

def buildProtocol(self, addr):
    self.resetDelay()
    p = Advantech6017ClientProtocol()
    p.factory = self
    return p    

def print_dl(data):
print("print_dl: %s" % data)

def error_dl(data):
print("error_dl: %s" % data)

def loop(factories):
try:
dl = defer.DeferredList(deferredList = [factory.read_device() for factory in factories], consumeErrors = True) #
dl.addCallback(print_dl)
dl.addErrback(error_dl)
except Exception as e:
print "major exception %s" % e
finally:
reactor.callLater(1, loop, factories)

ip1 = "192.168.1.9"
ip2 = "192.168.1.10"

factory = Advantech6017Factory()
reactor.connectTCP(ip1, 502, factory)

factory2 = Advantech6017Factory()
reactor.connectTCP(ip2, 502, factory2)

factories = [factory, factory2]

def process():
try:
reactor.callLater(1, loop, factories )
except Exception as e:
print e

reactor.callWhenRunning(process)
reactor.run()

Below is my script output (with comments):

connection made
connection made
<main.Advantech6017ClientProtocol object at 0xb6e38a2c>
<main.Advantech6017ClientProtocol object at 0xb6e3d1cc>
print_dl: [(True, <pymodbus.register_read_message.ReadInputRegistersResponse object at 0xb6e3d38c>), (True, <pymodbus.register_read_message.ReadInputRegistersResponse object at 0xb6e3d3cc>)]
<main.Advantech6017ClientProtocol object at 0xb6e38a2c>
<main.Advantech6017ClientProtocol object at 0xb6e3d1cc>
print_dl: [(True, <pymodbus.register_read_message.ReadInputRegistersResponse object at 0xb6e3d3ec>), (True, <pymodbus.register_read_message.ReadInputRegistersResponse object at 0xb6e3d40c>)]

unplug device

<main.Advantech6017ClientProtocol object at 0xb6e38a2c>
<main.Advantech6017ClientProtocol object at 0xb6e3d1cc>
<main.Advantech6017ClientProtocol object at 0xb6e38a2c>
<main.Advantech6017ClientProtocol object at 0xb6e3d1cc>

Ctrl-C

print_dl: [(True, <pymodbus.register_read_message.ReadInputRegistersResponse object at 0xb6e3dc8c>), (False, <twisted.python.failure.Failure <class 'pymodbus.exceptions.ConnectionException'>>)]
print_dl: [(True, <pymodbus.register_read_message.ReadInputRegistersResponse object at 0xb6e3d30c>), (False, <twisted.python.failure.Failure <class 'pymodbus.exceptions.ConnectionException'>>)]

pymodbus.client.sync.ModbusTcpClient read_input_registers get none ?

HI,sorry for my poor english!
Why my tcp client get none after perfoming function 'read_input_registers'?My code is:
from pymodbus.client.sync import ModbusTcpClient as ModbusClient

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

 client = ModbusClient('192.1.8.146', port=26)
 client.connect()
 arguments = {
 'read_address':    0,
 'read_count':      1,
 'write_address':   1,
 'write_registers': 1,
}
 rq = client.readwrite_registers(**arguments)
 rr = client.read_input_registers(0,16)
 print rr    
 client.close()

The result is:
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:0x4d 0x4f 0x44 0x42 0x55 0x53
DEBUG:pymodbus.transaction:getting transaction 1
DEBUG:pymodbus.transaction:Running transaction 2
DEBUG:pymodbus.transaction:0x0 0x2 0x0 0x0 0x0 0x23 0x1 0x4 0x20 0x9a 0xf9 0x79 0xc4 0x9a 0xf9 0x79 0xc4 0x9a 0xf9 0x79 0xc4 0x9a 0xf9 0x79 0xc4 0x9a 0xf9 0x79 0xc4 0x0 0x0 0xc0 0x41 0x9a 0xf9 0x79 0xc4 0x66 0x66 0xbe 0x41
DEBUG:pymodbus.transaction:getting transaction 2
None

I use a modbus/tcp  to modbus/rtu gatway as a server,i test it with Modbus Poll,it can get the correct datas,i am sure the device is ok,so i don't know where is going wrong...

Thank you!
Billy apple

Async Client Example

Hi there,
First of all thanks for the awesome work. I am pretty new to this project so I am still trying to get up to speed on this. I've been trying to execute following example.

from twisted.internet import reactor, protocol
from pymodbus.client.async import ModbusClientProtocol

def printResult(result):
    print "Result: %d" % result.bits[0]

def process(client):
    result = client.write_coil(1, True)
    result.addCallback(printResult)
    reactor.callLater(1, reactor.stop)

defer = protocol.ClientCreator(reactor, ModbusClientProtocol
        ).connectTCP("localhost", 502)
defer.addCallback(process)

I've actually changed "localhost" to ip address of my modbus unit. Anyway, It seems like callbacks never get executed. Also, I am not sure how do you pass arguments to process and printResult functions. Also sync example clearly instantiates client. This example does not have client instantiation. I was wondering if I am missing something. I will continue looking through the source code but any hint would be greatly appreciated.
Thank you very much!

no RtuFramer for serial synchronus server

It seems like you cannot use an RtuFramer for a synchronus serial server.

pymodbus.server.async.StartSerialServer(context, identity=None,
    framer=ModbusAsciiFramer, **kwargs):

uses a framer as parameter, ModbusAscii as default.

pymodbus.server.sync.StartSerialServer(context=None, identity=None, **kwargs):
    framer = ModbusAsciiFramer

This one uses only the AsciiFramer. No possibility to use RtuFramer

pymodbus.client.async ModbusClientProtocol mishandling transactions

We are running against Emerson EP204-P200-EN00 RTUs fully async using twisted and have noticed some odd issues with the deque in the async client protocol.

I have noticed that just doing a .popleft() might not be the implementation you intended w/ an async process, since many functions being processed by the reactor are pushing requests through the client and there is no guarantee when they will be processed and returned.

In the case below, we are reading registers every 0.1 in a LoopingCall, and when the device is "ready" we write several registers, handling the deferreds in a DeferredList, then fire off the write_coils. Status register reads are happening all the time, and it looks like we get out of sync with the responses almost immediately.

It appears that the ModbusTransactionManager might be a better solution here. We are currently working on a solution and will issue a pull request, but I wanted to start a dialog sooner.

Here is a snip of the log:
2014-08-20 06:56:32-0400 [-] Log opened.
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] replyTxn: 9 reqTxn: 1
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] replyTxn: 1 reqTxn: 2
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] replyTxn: 2 reqTxn: 3
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] regs written
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] replyTxn: 3 reqTxn: 4
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] *--- Failure #6 ---
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] /home/rob/development/modbus/ctf-scada/pymodbus/transaction.py:235: processIncomingPacket(...)
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] /home/rob/development/modbus/ctf-scada/pymodbus/client/async.py:95: _callback(...)
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] /usr/lib/python2.7/dist-packages/twisted/internet/defer.py:382: callback(...)
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] /usr/lib/python2.7/dist-packages/twisted/internet/defer.py:490: _startRunCallbacks(...)
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] [Capture of Locals and Globals disabled (use captureVars=True)]
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] --- ---
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] /usr/lib/python2.7/dist-packages/twisted/internet/defer.py:577: _runCallbacks(...)
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] /home/rob/development/modbus/ctf-scada/etchasketch/device/rtu/emerson/ep204p00/main.py:129: cb(...)
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] [Capture of Locals and Globals disabled (use captureVars=True)]
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] exceptions.AttributeError: 'WriteSingleRegisterResponse' object has no attribute 'getRegister'
2014-08-20 06:56:32-0400 [ModbusClientProtocol,client] *--- End of Failure #6 ---

Handling of malformed MEI responses

We have a heat pump that manages to confuse pymodbus when asked to identify itself through RTU. When asked for the mandatory information, the response is as follows:

0x01 00x2b 0x0e 0x01 0x01 0x00 0x00 0x01 0x00 0x04 NIBE 0x01 0x08 F1345-60 0x02 0x04 4150 0xab 0x9a

The pump indicate that the MEI response contain only one object, while three are sent, which calculateRtuFrameSize() in mei_message.py doesn't like at all.

I propose this method of verifying the MEI response structure:

@classmethod
def calculateRtuFrameSize(cls, buffer):
    ''' Calculates the size of the message

    :param buffer: A buffer containing the data that have been received.
    :returns: The number of bytes in the response.
    '''
    size = 8 # skip the header information

    while size + 2 < len(buffer):
        _, object_size = struct.unpack('>BB', buffer[size:size+2])
        size += object_size + 2

    return size + 2

Instead of trying to read the specified number of objects, this read objects until the input buffer is exhausted, returning a valid length for a certain class of malformed MEI responses. The same method of parsing the response is used in ReadDeviceInformationResponse.decode().

pymodbus.server.sync: chuid server on bind

Hi,

I've looked around and while I can get the PyModbus server to bind to port 502 as root, this represents a possible security risk and gives us other headaches (like files being created as root). Obviously port 502 can't be bound to by an unprivileged process and a lot of software (e.g. MacroView SCADA) assumes it'll find Modbus on that port, so we're more or less stuck there.

Many daemons will start as root, bind to a port, then drop privileges. Apache httpd is a good example of this. How is this achieved with PyModbus?

setValues is called with incorrect address

Hi,

I'll see if I can get some better data, but I've noticed that pymodbus seems to have a bug when performing a register write. Reading works fine, however when I perform a write register, it first validates the address range, which works, but then tries to call setValues with the wrong register address.

2014-08-19 17:42:40,127 mm-da-modbus-slave.unit001[modbus-slave.py: 411] DEBUG validate[6] 2011:1
2014-08-19 17:42:40,127 mm-da-modbus-slave.unit001[modbus-slave.py: 691] DEBUG set-values[6] 1:1
2014-08-19 17:42:40,127 mm-da-modbus-slave.unit001[modbus-slave.py: 695] DEBUG set-values: 1 = 3

Here, I tried writing to register 2011, it validates that it can write to register 2011, but then when it actually calls setValues, it passes in register 1. We're using the pymodbus 1.2.0-2 Ubuntu package compiled on Ubuntu 12.04.

Read Device Information using ModbusTcpClient

I've looked at the docs for the ModbusTcpClient, there's functions to read coils and registers but I couldn't see one for what Modbus calls "Function 43/14: Read Device Information"

Can you read the device information using a ModbusTcpClient object?

Modbus garbage values in return and error AttributeError: 'ExceptionResponse' object has no attribute 'registers'

Hi Guys,
My modbus system is Asynchronous and I have tried to solve my problem in 2 ways

Way 1: I am trying to read a register in this way:

1.self.client = ModbusClient(ip_add)
2.result = self.client.read_holding_registers(register_start_add,num_of_registers)
3.decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Little)
4.
5. if format_of_reg == 'ASCII': output = decoder.decode_string(num_of_registers)
6. if format_of_reg == 'REAL': output = decoder.decode_32bit_float()
7. if format_of_reg == 'UDINT': output = decoder..decode_16bit_uint()
8. if format_of_reg == 'INT': output = decoder.decode_8bit_int()
9. if format_of_reg == 'UINT': output = decoder.decode_8bit_uint()
10.if format_of_reg== 'bits': output = decoder.decode_bits()
11.
12. print str(output)

I am getting correct output contained in the register but for only those registers which are of ASCII types. For Floating types or others, I am getting garbage values like -2.39030167051e+32 (for float type)

e.g. if my system's modbus register 4 contains the value of current year and is of type UINT, then my query result = self.client.read_holding_registers(4,1) when decoded with line 9 above. it should give me 2013 as output but I am getting a value of '7' as output which is weird.

e.g. if my system's modbus register 12 contains the value of current Time in HH:MM:SS and is of type ASCII then I would get correct output as 12:37:54

Can Anyone let me know, why is this happening?


Way 2:
If instead of using read_holding_registers at line 2, I use read_input_registers and keeping rest of code as such, then as soon as I read it it gives me error as "'ExceptionResponse' object has no attribute 'registers'"

Any help?

SyntaxError: assignment to keyword => True, False = (1 == 1), (0 == 1)

C:\Anaconda>pip install -U pymodbus
Downloading/unpacking pymodbus
Downloading pymodbus-1.2.0.tar.gz (75Kb): 75Kb downloaded
Running setup.py egg_info for package pymodbus
Traceback (most recent call last):
File "", line 14, in
File "C:\Anaconda\build\pymodbus\setup.py", line 26, in
from pymodbus import version, author
File "pymodbus__init__.py", line 37
True, False = (1 == 1), (0 == 1)
^
SyntaxError: assignment to keyword
Complete output from command python setup.py egg_info:
Traceback (most recent call last):

File "", line 14, in

File "C:\Anaconda\build\pymodbus\setup.py", line 26, in

from pymodbus import __version__, __author__

File "pymodbus__init__.py", line 37

True, False = (1 == 1), (0 == 1)

   ^

SyntaxError: assignment to keyword


Command python setup.py egg_info failed with error code 1 in C:\Anaconda\build\p
ymodbus
Storing complete log in \xxxx\AppData\Roaming\pip\pip.log

print sys.version
2.7.5 |Anaconda 1.8.0 (32-bit)| (default, Jul 1 2013, 12:41:55) [MSC v.1500 32 bit (Intel)]

If I comment out those four lines, it works fine.

Bug in parsing error responses.

bugs in parsing error responses. pymodbus don't check func_code >=0x80
from pymodbus.factory import ClientDecoder
from pymodbus.transaction import ModbusTransactionManager , ModbusRtuFramer
framer = ModbusRtuFramer(ClientDecoder())
data='\x00\x90\x02\x00\x01i' #error response from device
framer.processIncomingPacket(data,None)

./bug.py
Traceback (most recent call last):
File "bug.py", line 8, in
framer.processIncomingPacket(data,None)
File "build\bdist.win32\egg\pymodbus\transaction.py", line 425, in processIncomingPacket
File "build\bdist.win32\egg\pymodbus\transaction.py", line 328, in checkFrame
File "build\bdist.win32\egg\pymodbus\transaction.py", line 370, in populateHeader
AttributeError: 'NoneType' object has no attribute 'calculateRtuFrameSize'

This exception is caused by code pdu_class = self.decoder.lookupPduClass(func_code) in transaction.py line 369
ClientDecoder.lookupPduClass at line 181 knows nothing about errors(0x80+func) and returns None...

CHANGELOG

Hi, we started using pymodbus 0.9.0 about a year ago. I can see that current version is 1.1.0, but there is no CHANGELOG file to figure out what was changed between these two releases, and whether moving to 1.1.0 makes sense for us or not.

RTU over TCP

Hi,
I had written a script to pull information from a device through modbus gateway, it worked very well whit version 0.9. Somedays ago i installed 1.1, it can not work anymore. I wirte a brief fllowing:
in v0.9, I created a new class in client/sync.py named ModbusRTUTcpClient, it copied from ModbusTcpClient, the only change is : change BaseModbusClient.init(self, ModbusSocketFramer(ClientDecoder())) to BaseModbusClient.init(self, ModbusRtuFramer(ClientDecoder())).
in v1.1, I found there is framer parameter support, so i use:
client = ModbusTcpClient(host=host, port=port,framer=ModbusRtuFramer)
it cannot work.
Any suggestion? thanks

While using sync.client, _recv() too early after _send()

Hello.

Spent two days figuring this, but this helped an issue. I'm querying a device, that is a bit slow in response via Modbus. Using sync.client and TCP Server ICS-10X from Planet gave me a headache. Was not able to get result of ReadHoldingRegistersRequest():

DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:getting transaction 1
DEBUG:pymodbus.transaction:Running transaction 2
DEBUG:pymodbus.transaction:getting transaction 2

After modifying of ModbusTransactionManager's execute() and putting delay between _send() and _recv() everything works great:

DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.factory:Factory Response[3]
DEBUG:pymodbus.transaction:adding transaction 0
DEBUG:pymodbus.transaction:getting transaction 1
Slave: 3, register 23: 0x4041
DEBUG:pymodbus.transaction:Running transaction 2
DEBUG:pymodbus.factory:Factory Response[3]
DEBUG:pymodbus.transaction:adding transaction 0
DEBUG:pymodbus.transaction:getting transaction 2
Slave: 3, register 24: 0x5268

Don't know if this can be achieved with some more elegant approach but this works for me so far. Would be great if such a delay would be configurable.

RemoteSlaveContext not supporting unit

Is there a reason why, specifically setValues and getValues in, RemoteSlaveContext doesn't support **kwargs to enable for the unit (what I typically call slave id) parameter? I modified this to accommodate for a scenario where I have a bottle instance backed by a RemoteSlaveContext which communicates with multiple slaves. Should I send a PR for this or is this supposed to be handled in some other way?

read_holding_registers returns None on BeagleBone Black, no issue on Windows and Linux VM

I wrote my python script in Windows, and it worked fine, the PLC returned the values I wanted.

edit: I just tried it on my Mint 17 Virtual Machine and it works fine on there too. It's just the BBB that doesn't work /edit

Now I am trying to run it on my BeagleBone Black (running the latest Debian) and it's just returning "None" I don't event get a time out exception. After the the allotted timeout time has passed it just returns None.

I'm using the pymodbus library

Here is my function for the BeagleBone

def checkProxCounter():
    count = 0
    result = 0

    UART.setup("UART1")
    client = ModbusSerialClient(method='rtu',port='/dev/ttyO1',parity= 'O',stopbits=1,bytesize=8,baudrate=9600,timeout=10)
    #client = ModbusSerialClient(method='rtu',port='/dev/ttyS1',parity= 'O',stopbits=1,bytesize=8,baudrate=9600,timeout=2)
    #client = ModbusSerialClient(method='rtu',port='COM2',parity= 'O',stopbits=1,baudrate=9600,timeout=2)

    try:
        if client.connect():
            print ("Port open")
            result = client.read_holding_registers(address=512, count=8,unit=1)

            blah = client.read_discrete_inputs(1,8)

            if blah != None:
                print("{}: {}".format("Blah", blah.bits[0]))


            #print("{}: {}".format("Pre", count))
            if result != None:
                count = int(str(result.registers[0]),16) + int(str(result.registers[1]),16)
                print("{}: {}".format("Count", count))
            else:
                print("results were none")
            client.close()
        else:
            print("Port failed to open")
            count = -2

    except ConnectionException:
        print("ERROR: Serial Port Timed Out")
        count = -1
        pass
    except:
        print("Unknown Exception")
        raise


    return count

Print value in holding register in mode rtu

Hello, I want to read and print the values stored in holding registers 00 to 03, and I succeeded with Modpoll, but when I tried with this code in python, the result is None
ps: My python version is 2.7.3

!/usr/bin/env python

from pymodbus.client.sync import ModbusSerialClient as ModbusClient
client=ModbusClient(method='rtu',port='/dev/ttyUSB0',baudrate=9600,timeout=1)
client.connect()

response=client.read_holding_registers(0,4,unit=1)
print response
client.close()

Could you give a hand on this issue? tks in advance

modbus-scraper.py example doesn't work

I've found and fixed a typo

   if (self.client.connect()): <-- missing colon

and a missing twisted import statement

from twisted.internet import reactor

but now I'm hitting errors that exceed my very modest (practically non-existent) knowledge of python.

Traceback (most recent call last):
File "C:_Work\python work\modbus-scraper.py", line 131, in
main()
File "C:_Work\python work\modbus-scraper.py", line 121, in main
reactor.callWhenRunning(s.start)
AttributeError: 'ClientScraper' object has no attribute 'start'

Using pymodbus within a twisted python app makes pymodbus.client.sync.ModbusUdpClient mistakenly use IPv6

I have only tested with the UDP Client, I can only guess the same applies to TCP.

from twisted.internet import protocol, reactor
from pymodbus.client.sync import ModbusUdpClient

class Echo(protocol.Protocol):
    def dataReceived(self, data):
        self.transport.write(data)

class EchoFactory(protocol.Factory):
    def __init__(self):
        self.test = ModbusUdpClient('10.0.1.2')
        self.test.connect()
    def buildProtocol(self, addr):
        return Echo()

reactor.listenTCP(1234, EchoFactory())
reactor.run()

Result of running this on my computer (in ipython for clarity):

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-11-3ca69b6d2d85> in <module>()
     15 
     16 
---> 17 reactor.listenTCP(1234, EchoFactory())
     18 reactor.run()

<ipython-input-11-3ca69b6d2d85> in __init__(self)
     10     def __init__(self):
     11         self.test = ModbusUdpClient('10.0.1.2')
---> 12         self.test.connect()
     13     def buildProtocol(self, addr):
     14         return Echo()

/usr/lib/python2.7/site-packages/pymodbus/client/sync.pyc in connect(self)
    219         if self.socket: return True
    220         try:
--> 221             family = ModbusUdpClient._get_address_family(self.host)
    222             self.socket = socket.socket(family, socket.SOCK_DGRAM)
    223         except socket.error, ex:

/usr/lib/python2.7/site-packages/pymodbus/client/sync.pyc in _get_address_family(cls, address)
    207         '''
    208         try:
--> 209             _ = socket.inet_pton(socket.AF_INET6, address)
    210         except socket.error: # not a valid ipv6 address
    211             return socket.AF_INET

/usr/lib/python2.7/site-packages/twisted/python/compat.pyc in inet_pton(af, addr)
     63         else:
     64             if len(parts) != (8 - ipv4Component):
---> 65                 raise ValueError("Syntactically invalid address")
     66 
     67         if ipv4Component:

ValueError: Syntactically invalid address

It seems that if you do the socket.inet_pton(socket.AF_INET6, address) within a twisted application, it won't throw a socket.error even if there's no IPv6 addresses available (I don't have support for IPv6 at both the kernel or in the python interpreter).

cannot enable/disable RTS for client and slave

when i use serial RTU and RS-485 wires, how do i set set RTS high and low.

i know i gotta to do it in the source codes, like for read_holding_register request , i need to set it high to send the request and low to receive the response from slave.

and for the slave Linux box, i need to set RTS high to send a reponse back to master and set it low right after that.

where do i do that ?

i know i can setRTS using pyserial.

Slave ID for request not verified when accepting response

It appears that the validation process is not checking that the slave id in the request matches the slave id in the response. For a synchronous client a response from a rogue device should not be considered a valid response when reading coils/holding/input/discrete registers.

Edit: oops, referring to server code.

Thanks for moving to github.

No issue, just wanted to say thanks for moving this to github, a lot easier to keep up with the pace of devleopment.

RTU/Serial Framer Fix Branch Issues

I am opening an issue that can contain all responses about fixing the RTU/serial framer problems. Please keep all comments about the new branch (framer-fix) here so it is easy to track issues. Thanks!

Some help for installing modbuspy on ubuntu

I hope someone can help me because I am not a python expert. I couldn't install modbuspy package on a Windows machine so I'm planning to install ubuntu on a virtual machine. My questions are:

  1. Is that ok if I install ubuntu 14.04 .1lts?
  2. Is that ok if I use python 2.7.8?

thanks in advance

ModbusServerContext doesn't implement __delitem__

ModbusServerContext implements getitem and setitem (Which is awesome by the way, it lets me add/remove/change slaves at runtime)

However, the only access to removing slaves is to leave the slave id, but set the slave object to None. This works, but you get errors like "pymodbus.server.async - Datastore unable to fulfill request: 'NoneType' object has no attribute 'validate'"

Wouldn't it be better if you could simply remove the slaves outright?

Example Non Issue

This isn't an "issue" but rather a request for an example. If I could get an example to read a single register, decode and print that value. The modbus device I'm using is an IDEC D12 model (TCP). The link below has their modbus addressing table (in an excel spreadsheet), which is where my confusion starts. I'd like to read Data Register D0000 (modbus address 400001) and print that decoded value.

http://us.idec.com/CmsContent/Support/AppNotes/PLC/General/7ModbusAddressingTable.xls

Thanks for all the hard work!

read_holding_registers returns always none

Maybe this isn't a real issue but i can't get the library to read registers.
I try to read status data from a SICK FlexiSoft Safety PLC with Modbus Gateway.
Here is a Gist of my snippet.
I can connect to the Safety PLC but if i try to call read_holding_registers(1100,25) i always get none as reply.

This is the adress tabel out of the operation instructions PDF:
modbus

Has anybody an idea what i do wrong?

I've tried Windows7 as well as Arch Linux both with pyModbus V1.2.0 and 1.3.0 so far.

Fix Documentation for Client.Sync

Nowhere does it mention that you have to call client.connect() and the resulting error is attempting to call members on a null socket.

  1. Update the documentation and examples
  2. Gracefully handle the unconnected state (like the enter method).

Synchronous Serial Modbus Client Issue

Hi there,

in factory.py on line 240, where the functions are called from __lookup, the function is given no kwargs. Later on deeper in the code, the transaction ID is not passed to the function which retrieves the data for the correct transaction.

The response returned by this __lookup call then returns transaction with no data, transaction ID 0 and unit ID 0 -- although deeper debugging revealed that the client really received data.

Kind Regards,

Mark

Win7 ImportError: No module named pymodbus.client.sync

It appears to have successfully installed, and the .egg file is in site-packages, but I can't import.

If I run setup.py --version it returns 1.2.0, but when I try to import...

from pymodbus.client.sync import ModbusTcpClient

Traceback (most recent call last):
File "<pyshell#9>", line 1, in
from pymodbus.client.sync import ModbusTcpClient
ImportError: No module named pymodbus.client.sync

INSTALL LOG

setup.py install
running install
running bdist_egg
running egg_info
writing requirements to pymodbus.egg-info\requires.txt
writing pymodbus.egg-info\PKG-INFO
writing top-level names to pymodbus.egg-info\top_level.txt
writing dependency_links to pymodbus.egg-info\dependency_links.txt
warning: manifest_maker: standard file 'setup.py' not found

file ez_setup.py (for module ez_setup) not found
reading manifest file 'pymodbus.egg-info\SOURCES.txt'
writing manifest file 'pymodbus.egg-info\SOURCES.txt'
installing library code to build\bdist.win32\egg
running install_lib
running build_py
file ez_setup.py (for module ez_setup) not found
file ez_setup.py (for module ez_setup) not found
warning: install_lib: 'build\lib' does not exist -- no Python modules to install

creating build\bdist.win32\egg
creating build\bdist.win32\egg\EGG-INFO
copying pymodbus.egg-info\PKG-INFO -> build\bdist.win32\egg\EGG-INFO
copying pymodbus.egg-info\SOURCES.txt -> build\bdist.win32\egg\EGG-INFO
copying pymodbus.egg-info\dependency_links.txt -> build\bdist.win32\egg\EGG-INFO

copying pymodbus.egg-info\requires.txt -> build\bdist.win32\egg\EGG-INFO
copying pymodbus.egg-info\top_level.txt -> build\bdist.win32\egg\EGG-INFO
copying pymodbus.egg-info\zip-safe -> build\bdist.win32\egg\EGG-INFO
creating 'dist\pymodbus-1.2.0-py2.7.egg' and adding 'build\bdist.win32\egg' to i
t
removing 'build\bdist.win32\egg' (and everything under it)
Processing pymodbus-1.2.0-py2.7.egg
Removing c:\python27\lib\site-packages\pymodbus-1.2.0-py2.7.egg
Copying pymodbus-1.2.0-py2.7.egg to c:\python27\lib\site-packages
pymodbus 1.2.0 is already the active version in easy-install.pth

Installed c:\python27\lib\site-packages\pymodbus-1.2.0-py2.7.egg
Processing dependencies for pymodbus==1.2.0
Searching for pyserial==2.7
Best match: pyserial 2.7
Adding pyserial 2.7 to easy-install.pth file

Using c:\python27\lib\site-packages
Searching for twisted==14.0.0
Best match: twisted 14.0.0
Processing twisted-14.0.0-py2.7-win32.egg
twisted 14.0.0 is already the active version in easy-install.pth
Installing cftp.py script to C:\Python27\Scripts
Installing cftp.pyc script to C:\Python27\Scripts
Installing ckeygen.py script to C:\Python27\Scripts
Installing ckeygen.pyc script to C:\Python27\Scripts
Installing conch.py script to C:\Python27\Scripts
Installing conch.pyc script to C:\Python27\Scripts
Installing lore.py script to C:\Python27\Scripts
Installing lore.pyc script to C:\Python27\Scripts
Installing mailmail.py script to C:\Python27\Scripts
Installing mailmail.pyc script to C:\Python27\Scripts
Installing manhole.py script to C:\Python27\Scripts
Installing manhole.pyc script to C:\Python27\Scripts
Installing pyhtmlizer.py script to C:\Python27\Scripts
Installing pyhtmlizer.pyc script to C:\Python27\Scripts
Installing tap2deb.py script to C:\Python27\Scripts
Installing tap2deb.pyc script to C:\Python27\Scripts
Installing tap2rpm.py script to C:\Python27\Scripts
Installing tap2rpm.pyc script to C:\Python27\Scripts
Installing tapconvert.py script to C:\Python27\Scripts
Installing tapconvert.pyc script to C:\Python27\Scripts
Installing tkconch.py script to C:\Python27\Scripts
Installing tkconch.pyc script to C:\Python27\Scripts
Installing trial.py script to C:\Python27\Scripts
Installing trial.pyc script to C:\Python27\Scripts
Installing twistd.py script to C:\Python27\Scripts
Installing twistd.pyc script to C:\Python27\Scripts

Using c:\python27\lib\site-packages\twisted-14.0.0-py2.7-win32.egg
Searching for zope.interface==4.1.1
Best match: zope.interface 4.1.1
Processing zope.interface-4.1.1-py2.7-win32.egg
zope.interface 4.1.1 is already the active version in easy-install.pth

Using c:\python27\lib\site-packages\zope.interface-4.1.1-py2.7-win32.egg
Searching for setuptools==5.2
Best match: setuptools 5.2
Processing setuptools-5.2-py2.7.egg
setuptools 5.2 is already the active version in easy-install.pth
Installing easy_install-script.py script to C:\Python27\Scripts
Installing easy_install.exe script to C:\Python27\Scripts
Installing easy_install.exe.manifest script to C:\Python27\Scripts
Installing easy_install-2.7-script.py script to C:\Python27\Scripts
Installing easy_install-2.7.exe script to C:\Python27\Scripts
Installing easy_install-2.7.exe.manifest script to C:\Python27\Scripts

Using c:\python27\lib\site-packages\setuptools-5.2-py2.7.egg
Finished processing dependencies for pymodbus==1.2.0

twisted port.stopListening() doesn't stop?

I'm building a small gtk3 (pygobject) app, and I want to start/stop the modbus server socket (this is a modbus server, faking out the real hardware)

in my gtk main window, I have this...

from pymodbus.server.async import ModbusServerFactory
self.context = ModbusServerContext(slaves=slaves, single=False)
framer  = ModbusSocketFramer
self.factory = ModbusServerFactory(self.context, framer)

and on the button press...

self.mb_port = reactor.listenTCP(1502, self.factory, interface="0.0.0.0")

This works well, but for the "stop" button, simply calling

self.mb_port.stopListening() #doesn't do anything.

I know this might be deferred, but I don't see it ever finish. There is a client continually making modbus requests, but I still expected this to stop eventually. Am I doing something wrong?

Create a common troubleshooting list

There are a number of errors that can be solved with a simple checklist. Create an example with a number of different options to try and a documentation page describing troubleshooting steps.

Python <=2.6 Sync ModbusTCPClient socket.create_connection: no source_address kwarg

(Context: I'm stuck on Python 2.6 on an embedded box, upgrading to 2.7 or higher isn't under my control at the moment.)

The socket API changed in Python 2.7, in 2.6 and prior socket.create_connection doesn't handle the source_address kwarg. (This shows up in the ModbusTcpClient.connect(), pymodbus/client/sync.py, line 142 or so.)

Is there a better way to handle this besides doing something like the following?

if sys.version_info[:2] < (2, 7):
    # self.socket = old socket.create_connection call w/o source_address
else:
    # self.socket = new socket.create_connection call w/ source_address

RTU sync client always waits for timeout (with possible solution)

The RTU serial port client always waits for the port timeout value, e.g.;
client = ModbusClient(port = 'dev/ttyUSB0', ..... , timeout = 1)
will cause every request to take one second as the read size is always set to 1024 bytes, larger than an actual response. One possible solution is to read the first few bytes of the response and from that determine the complete response size. This is possible for all the common function codes.

This is a modified v1.2.0 /client/sync.py
All changes are in the last 128 lines of the file. Only affects RTU clients.
Only tested for holding register reads, which is all my hardware is set up for right now.

If the response is corrupted somehow the client will either return after reading too few bytes or timeout waiting for too many. A buffer flush would likely be required to recover from reading too few bytes, not sure where to implement that (I'm EEng not Python coder unfortunately).

First Steps /help

I tried to run:

//
from pymodbus.client.sync import ModbusTcpClient

client = ModbusTcpClient('myStaticIP, port=myPort')
client.connect()
rr = client.connect()
print rr
client.write_coil(1, True)
result = client.read_coils(1,1)
print result.bits[0]
client.close()
//

Output is as follows:
//
True
Traceback (most recent call last):
File "./test.py", line 11, in
print result.bits[0]
AttributeError: 'NoneType' object has no attribute 'bits'
//

Tried on Ubuntu 12.10, Linux Mint 15 and BeagleBone (Black). All different boxes, with good ping responses from Modbus client. Modbus client is an IDEC FC5A-D12 running as Modbus TCP Slave.

Any help would be great!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.