[Python-modules-commits] [pymodbus] 01/04: import new upstream version 1.3.0~rc1

Wolfgang Borgert debacle at moszumanska.debian.org
Thu May 18 08:29:46 UTC 2017


This is an automated email from the git hooks/post-receive script.

debacle pushed a commit to branch debian/experimental
in repository pymodbus.

commit 58ca1d365e84ca185099893f6211a7d146e35fee
Author: W. Martin Borgert <debacle at debian.org>
Date:   Wed May 17 21:27:32 2017 +0200

    import new upstream version 1.3.0~rc1
---
 .gitignore                                    |   5 +
 CHANGELOG.rst                                 |   7 +-
 README.rst                                    |   9 +-
 doc/sphinx/examples/index.rst                 |   1 +
 doc/sphinx/examples/modbus-payload-server.rst |   6 +
 examples/common/asynchronous-server.py        |   2 +-
 examples/common/modbus-payload-server.py      |  70 +++++++++
 examples/common/modbus-payload.py             |   6 +-
 examples/common/performance.py                |  17 ++-
 examples/common/synchronous-client-ext.py     |  63 ++++----
 examples/common/synchronous-client.py         |  39 ++---
 examples/common/synchronous-server.py         |   8 +-
 examples/contrib/modicon-payload.py           |   5 +-
 ez_setup.py                                   |  53 ++++---
 pymodbus/__init__.py                          |   8 +-
 pymodbus/bit_read_message.py                  |  15 +-
 pymodbus/bit_write_message.py                 |  15 +-
 pymodbus/client/async.py                      |   2 +-
 pymodbus/client/sync.py                       |  48 ++++++-
 pymodbus/compat.py                            |  96 +++++++++++++
 pymodbus/datastore/context.py                 |  16 ++-
 pymodbus/datastore/store.py                   |  11 +-
 pymodbus/device.py                            |  45 +++---
 pymodbus/diag_message.py                      |  18 ++-
 pymodbus/events.py                            |   4 +-
 pymodbus/exceptions.py                        |   3 -
 pymodbus/factory.py                           |  11 +-
 pymodbus/file_message.py                      |  21 +--
 pymodbus/internal/ptwisted.py                 |  10 +-
 pymodbus/mei_message.py                       |  12 +-
 pymodbus/other_message.py                     |  41 +++---
 pymodbus/payload.py                           |  32 +++--
 pymodbus/pdu.py                               |   7 +-
 pymodbus/register_read_message.py             |  16 ++-
 pymodbus/register_write_message.py            |  14 +-
 pymodbus/server/async.py                      |  20 +--
 pymodbus/server/sync.py                       |  76 ++++++----
 pymodbus/transaction.py                       | 198 +++++++++++++++++++-------
 pymodbus/utilities.py                         |  20 +--
 pymodbus/version.py                           |  16 ++-
 requirements.txt                              |  29 ++--
 setup.cfg                                     |   3 +
 setup.py                                      |   8 +-
 test/test_bit_read_messages.py                |  15 +-
 test/test_bit_write_messages.py               |  27 ++--
 test/test_client_async.py                     |  11 +-
 test/test_client_sync.py                      |  29 ++--
 test/test_device.py                           |  15 +-
 test/test_diag_messages.py                    | 102 ++++++-------
 test/test_events.py                           |  20 +--
 test/test_exceptions.py                       |   2 +-
 test/test_factory.py                          | 110 +++++++-------
 test/test_file_message.py                     |  66 ++++-----
 test/test_interfaces.py                       |   2 +-
 test/test_mei_messages.py                     |  33 +++--
 test/test_other_messages.py                   |  54 +++----
 test/test_payload.py                          |  44 +++---
 test/test_pdu.py                              |  17 +--
 test/test_register_read_messages.py           |  36 ++---
 test/test_register_write_messages.py          |  21 +--
 test/test_remote_datastore.py                 |   2 +-
 test/test_server_async.py                     |  28 +++-
 test/test_server_context.py                   |  15 +-
 test/test_server_sync.py                      |  58 ++++----
 test/test_transaction.py                      |  93 ++++++------
 test/test_utilities.py                        |   6 +-
 test/test_version.py                          |   7 +-
 67 files changed, 1214 insertions(+), 705 deletions(-)

diff --git a/.gitignore b/.gitignore
index 5ba77b1..58a3b23 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,8 @@ build/
 dist/
 pymodbus.egg-info/
 .coverage
+.vscode
+.idea
+.noseids
+
+.idea/
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 6734f82..5133664 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,9 @@
-Version 1.2.0
+Version 1.3.0.rc1
 ------------------------------------------------------------
-
+* Timing improvements over MODBUS Serial interface
+* Modbus RTU use 3.5 char silence before and after transactions
+* Bug fix on FifoTransactionManager , flush stray data before transaction
+* Update repository information
 * Added ability to ignore missing slaves
 * Added ability to revert to ZeroMode
 * Passed a number of extra options through the stack
diff --git a/README.rst b/README.rst
index 5529721..c9b6f77 100644
--- a/README.rst
+++ b/README.rst
@@ -49,6 +49,9 @@ a user to test as many devices as their base operating system will allow (*allow
 in this case means how many Virtual IP addresses are allowed).
 
 For more information please browse the project documentation:
+
+http://riptideio.github.io/pymodbus/ 
+or
 http://readthedocs.org/docs/pymodbus/en/latest/index.html
 
 ------------------------------------------------------------
@@ -72,7 +75,8 @@ need, feel free to submit them so others can benefit.
 Also, if you have questions, please ask them on the mailing list
 so that others can benefit from the results and so that I can
 trace them. I get a lot of email and sometimes these requests
-get lost in the noise: http://groups.google.com/group/pymodbus
+get lost in the noise: http://groups.google.com/group/pymodbus or 
+at gitter:  https://gitter.im/pymodbus_dev/Lobby
 
 ------------------------------------------------------------
 Installing
@@ -123,7 +127,8 @@ License Information
 Pymodbus is built on top of code developed from/by:
   * Copyright (c) 2001-2005 S.W.A.C. GmbH, Germany.
   * Copyright (c) 2001-2005 S.W.A.C. Bohemia s.r.o., Czech Republic.
-  * Hynek Petrak <hynek at swac.cz>
+
+  * Hynek Petrak, https://github.com/HynekPetrak
   * Twisted Matrix
 
 Released under the BSD License
diff --git a/doc/sphinx/examples/index.rst b/doc/sphinx/examples/index.rst
index 10f265e..84f5c94 100644
--- a/doc/sphinx/examples/index.rst
+++ b/doc/sphinx/examples/index.rst
@@ -17,6 +17,7 @@ Example Library Code
    custom-message
    modbus-logging
    modbus-payload
+   modbus-payload-server
    synchronous-client
    synchronous-client-ext
    synchronous-server
diff --git a/doc/sphinx/examples/modbus-payload-server.rst b/doc/sphinx/examples/modbus-payload-server.rst
new file mode 100644
index 0000000..9144f0f
--- /dev/null
+++ b/doc/sphinx/examples/modbus-payload-server.rst
@@ -0,0 +1,6 @@
+==================================================
+Modbus Payload Server Context Building Example
+==================================================
+
+.. literalinclude:: ../../../examples/common/modbus-payload-server.py
+
diff --git a/examples/common/asynchronous-server.py b/examples/common/asynchronous-server.py
index f8d4669..dd41372 100755
--- a/examples/common/asynchronous-server.py
+++ b/examples/common/asynchronous-server.py
@@ -31,7 +31,7 @@ log.setLevel(logging.DEBUG)
 # initialize your data store
 #---------------------------------------------------------------------------# 
 # The datastores only respond to the addresses that they are initialized to.
-# Therefore, if you initialize a DataBlock to addresses of 0x00 to 0xFF, a
+# Therefore, if you initialize a DataBlock to addresses from 0x00 to 0xFF, a
 # request to 0x100 will respond with an invalid address exception. This is
 # because many devices exhibit this kind of behavior (but not all)::
 #
diff --git a/examples/common/modbus-payload-server.py b/examples/common/modbus-payload-server.py
new file mode 100755
index 0000000..3c6d195
--- /dev/null
+++ b/examples/common/modbus-payload-server.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+'''
+Pymodbus Server Payload Example
+--------------------------------------------------------------------------
+
+If you want to initialize a server context with a complicated memory
+layout, you can actually use the payload builder.
+'''
+#---------------------------------------------------------------------------# 
+# import the various server implementations
+#---------------------------------------------------------------------------# 
+from pymodbus.server.sync import StartTcpServer
+
+from pymodbus.device import ModbusDeviceIdentification
+from pymodbus.datastore import ModbusSequentialDataBlock
+from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
+
+#---------------------------------------------------------------------------# 
+# import the payload builder
+#---------------------------------------------------------------------------# 
+
+from pymodbus.constants import Endian
+from pymodbus.payload import BinaryPayloadDecoder
+from pymodbus.payload import BinaryPayloadBuilder
+
+#---------------------------------------------------------------------------# 
+# configure the service logging
+#---------------------------------------------------------------------------# 
+import logging
+logging.basicConfig()
+log = logging.getLogger()
+log.setLevel(logging.DEBUG)
+
+#---------------------------------------------------------------------------# 
+# build your payload
+#---------------------------------------------------------------------------# 
+builder = BinaryPayloadBuilder(endian=Endian.Little)
+builder.add_string('abcdefgh')
+builder.add_32bit_float(22.34)
+builder.add_16bit_uint(0x1234)
+builder.add_8bit_int(0x12)
+builder.add_bits([0,1,0,1,1,0,1,0])
+
+#---------------------------------------------------------------------------# 
+# use that payload in the data store
+#---------------------------------------------------------------------------# 
+# Here we use the same reference block for each underlying store.
+#---------------------------------------------------------------------------# 
+
+block = ModbusSequentialDataBlock(1, builder.to_registers())
+store = ModbusSlaveContext(di = block, co = block, hr = block, ir = block)
+context = ModbusServerContext(slaves=store, single=True)
+
+#---------------------------------------------------------------------------# 
+# initialize the server information
+#---------------------------------------------------------------------------# 
+# If you don't set this or any fields, they are defaulted to empty strings.
+#---------------------------------------------------------------------------# 
+identity = ModbusDeviceIdentification()
+identity.VendorName  = 'Pymodbus'
+identity.ProductCode = 'PM'
+identity.VendorUrl   = 'http://github.com/bashwork/pymodbus/'
+identity.ProductName = 'Pymodbus Server'
+identity.ModelName   = 'Pymodbus Server'
+identity.MajorMinorRevision = '1.0'
+
+#---------------------------------------------------------------------------# 
+# run the server you want
+#---------------------------------------------------------------------------# 
+StartTcpServer(context, identity=identity, address=("localhost", 5020))
diff --git a/examples/common/modbus-payload.py b/examples/common/modbus-payload.py
index 88d0a25..d79926a 100755
--- a/examples/common/modbus-payload.py
+++ b/examples/common/modbus-payload.py
@@ -19,7 +19,7 @@ log.setLevel(logging.INFO)
 #---------------------------------------------------------------------------# 
 # We are going to use a simple client to send our requests
 #---------------------------------------------------------------------------# 
-client = ModbusClient('127.0.0.1')
+client = ModbusClient('127.0.0.1', port=5020)
 client.connect()
 
 #---------------------------------------------------------------------------# 
@@ -43,7 +43,7 @@ builder.add_8bit_int(0x12)
 builder.add_bits([0,1,0,1,1,0,1,0])
 payload = builder.build()
 address = 0x01
-result  = client.write_registers(address, payload, skip_encode=True)
+result  = client.write_registers(address, payload, skip_encode=True, unit=1)
 
 #---------------------------------------------------------------------------# 
 # If you need to decode a collection of registers in a weird layout, the
@@ -60,7 +60,7 @@ result  = client.write_registers(address, payload, skip_encode=True)
 #---------------------------------------------------------------------------# 
 address = 0x01
 count   = 8
-result  = client.read_input_registers(address, count)
+result  = client.read_input_registers(address, count,  unit=1)
 decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Little)
 decoded = {
     'string': decoder.decode_string(8),
diff --git a/examples/common/performance.py b/examples/common/performance.py
index f476f62..11ee8f8 100755
--- a/examples/common/performance.py
+++ b/examples/common/performance.py
@@ -13,13 +13,15 @@ import logging, os
 from time import time
 from multiprocessing import log_to_stderr
 from pymodbus.client.sync import ModbusTcpClient
+from pymodbus.client.sync import ModbusSerialClient
 
 #---------------------------------------------------------------------------# 
 # choose between threads or processes
 #---------------------------------------------------------------------------# 
 #from multiprocessing import Process as Worker
 from threading import Thread as Worker
-
+from threading import Lock
+_thread_lock = Lock()
 #---------------------------------------------------------------------------# 
 # initialize the test
 #---------------------------------------------------------------------------# 
@@ -29,8 +31,8 @@ from threading import Thread as Worker
 # * cycles  - the total number of requests to send
 # * host    - the host to send the requests to
 #---------------------------------------------------------------------------# 
-workers = 1
-cycles  = 10000
+workers = 10
+cycles  = 1000
 host    = '127.0.0.1'
 
 
@@ -54,10 +56,12 @@ def single_client_test(host, cycles):
 
     try:
         count  = 0
-        client = ModbusTcpClient(host)
+        # client = ModbusTcpClient(host, port=5020)
+        client = ModbusSerialClient(method="rtu", port="/dev/ttyp0", baudrate=9600)
         while count < cycles:
-            result = client.read_holding_registers(10, 1).getRegister(0)
-            count += 1
+            with _thread_lock:
+                result = client.read_holding_registers(10, 1, unit=1).getRegister(0)
+                count += 1
     except: logger.exception("failed to run test successfully")
     logger.debug("finished worker: %d" % os.getpid())
 
@@ -76,3 +80,4 @@ any(p.start() for p in procs)   # start the workers
 any(p.join()  for p in procs)   # wait for the workers to finish
 stop  = time()
 print "%d requests/second" % ((1.0 * cycles) / (stop - start))
+print "time taken to complete %s cycle by %s workers is %s seconds" % (cycles, workers, stop-start)
diff --git a/examples/common/synchronous-client-ext.py b/examples/common/synchronous-client-ext.py
index 19f1fe3..5f84bae 100755
--- a/examples/common/synchronous-client-ext.py
+++ b/examples/common/synchronous-client-ext.py
@@ -10,9 +10,9 @@ modbus protocol.
 #---------------------------------------------------------------------------# 
 # import the various server implementations
 #---------------------------------------------------------------------------# 
-from pymodbus.client.sync import ModbusTcpClient as ModbusClient
+# from pymodbus.client.sync import ModbusTcpClient as ModbusClient
 #from pymodbus.client.sync import ModbusUdpClient as ModbusClient
-#from pymodbus.client.sync import ModbusSerialClient as ModbusClient
+from pymodbus.client.sync import ModbusSerialClient as ModbusClient
 
 #---------------------------------------------------------------------------# 
 # configure the client logging
@@ -32,7 +32,8 @@ log.setLevel(logging.DEBUG)
 # It should be noted that you can supply an ipv4 or an ipv6 host address for
 # both the UDP and TCP clients.
 #---------------------------------------------------------------------------# 
-client = ModbusClient('127.0.0.1')
+client = ModbusClient(method='rtu', port="/dev/ttyp0")
+# client = ModbusClient('127.0.0.1', port=5020)
 client.connect()
 
 #---------------------------------------------------------------------------# 
@@ -65,35 +66,35 @@ from pymodbus.mei_message import *
 #---------------------------------------------------------------------------# 
 # information requests
 #---------------------------------------------------------------------------# 
-rq = ReadDeviceInformationRequest()
+rq = ReadDeviceInformationRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                             # not supported by reference
 assert(rr.function_code < 0x80)                 # test that we are not an error
-assert(rr.information[0] == 'proconX Pty Ltd')  # test the vendor name
-assert(rr.information[1] == 'FT-MBSV')          # test the product code
-assert(rr.information[2] == 'EXPERIMENTAL')     # test the code revision
+assert(rr.information[0] == 'Pymodbus')  # test the vendor name
+assert(rr.information[1] == 'PM')          # test the product code
+assert(rr.information[2] == '1.0')     # test the code revision
 
-rq = ReportSlaveIdRequest()
+rq = ReportSlaveIdRequest(unit=1)
 rr = client.execute(rq)
-assert(rr == None)                              # not supported by reference
+# assert(rr == None)                              # not supported by reference
 #assert(rr.function_code < 0x80)                # test that we are not an error
 #assert(rr.identifier  == 0x00)                 # test the slave identifier
 #assert(rr.status  == 0x00)                     # test that the status is ok
 
-rq = ReadExceptionStatusRequest()
+rq = ReadExceptionStatusRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                             # not supported by reference
-assert(rr.function_code < 0x80)                 # test that we are not an error
-assert(rr.status == 0x55)                       # test the status code
+#assert(rr.function_code < 0x80)                 # test that we are not an error
+#assert(rr.status == 0x55)                       # test the status code
 
-rq = GetCommEventCounterRequest()
+rq = GetCommEventCounterRequest(unit=1)
 rr = client.execute(rq)
-assert(rr == None)                              # not supported by reference
+#assert(rr == None)                              # not supported by reference
 #assert(rr.function_code < 0x80)                # test that we are not an error
 #assert(rr.status == True)                      # test the status code
 #assert(rr.count == 0x00)                       # test the status code
 
-rq = GetCommEventLogRequest()
+rq = GetCommEventLogRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                             # not supported by reference
 #assert(rr.function_code < 0x80)                # test that we are not an error
@@ -105,68 +106,68 @@ rr = client.execute(rq)
 #---------------------------------------------------------------------------# 
 # diagnostic requests
 #---------------------------------------------------------------------------# 
-rq = ReturnQueryDataRequest()
+rq = ReturnQueryDataRequest(unit=1)
 rr = client.execute(rq)
-assert(rr == None)                             # not supported by reference
+# assert(rr == None)                             # not supported by reference
 #assert(rr.message[0] == 0x0000)               # test the resulting message
 
-rq = RestartCommunicationsOptionRequest()
+rq = RestartCommunicationsOptionRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 #assert(rr.message == 0x0000)                  # test the resulting message
 
-rq = ReturnDiagnosticRegisterRequest()
+rq = ReturnDiagnosticRegisterRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 
-rq = ChangeAsciiInputDelimiterRequest()
+rq = ChangeAsciiInputDelimiterRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 
-rq = ForceListenOnlyModeRequest()
+rq = ForceListenOnlyModeRequest(unit=1)
 client.execute(rq)                             # does not send a response
 
 rq = ClearCountersRequest()
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 
-rq = ReturnBusCommunicationErrorCountRequest()
+rq = ReturnBusCommunicationErrorCountRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 
-rq = ReturnBusExceptionErrorCountRequest()
+rq = ReturnBusExceptionErrorCountRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 
-rq = ReturnSlaveMessageCountRequest()
+rq = ReturnSlaveMessageCountRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 
-rq = ReturnSlaveNoResponseCountRequest()
+rq = ReturnSlaveNoResponseCountRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 
-rq = ReturnSlaveNAKCountRequest()
+rq = ReturnSlaveNAKCountRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 
-rq = ReturnSlaveBusyCountRequest()
+rq = ReturnSlaveBusyCountRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 
-rq = ReturnSlaveBusCharacterOverrunCountRequest()
+rq = ReturnSlaveBusCharacterOverrunCountRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 
-rq = ReturnIopOverrunCountRequest()
+rq = ReturnIopOverrunCountRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 
-rq = ClearOverrunCountRequest()
+rq = ClearOverrunCountRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 
-rq = GetClearModbusPlusRequest()
+rq = GetClearModbusPlusRequest(unit=1)
 rr = client.execute(rq)
 #assert(rr == None)                            # not supported by reference
 
diff --git a/examples/common/synchronous-client.py b/examples/common/synchronous-client.py
index 373a5bb..503e6fc 100755
--- a/examples/common/synchronous-client.py
+++ b/examples/common/synchronous-client.py
@@ -18,7 +18,7 @@ the guard construct that is available in python 2.5 and up::
 #---------------------------------------------------------------------------# 
 from pymodbus.client.sync import ModbusTcpClient as ModbusClient
 #from pymodbus.client.sync import ModbusUdpClient as ModbusClient
-#from pymodbus.client.sync import ModbusSerialClient as ModbusClient
+# from pymodbus.client.sync import ModbusSerialClient as ModbusClient
 
 #---------------------------------------------------------------------------# 
 # configure the client logging
@@ -55,9 +55,9 @@ log.setLevel(logging.DEBUG)
 #
 #    client = ModbusClient('localhost', retries=3, retry_on_empty=True)
 #---------------------------------------------------------------------------# 
-client = ModbusClient('localhost', port=502)
+client = ModbusClient('localhost', port=5020)
 #client = ModbusClient(method='ascii', port='/dev/pts/2', timeout=1)
-#client = ModbusClient(method='rtu', port='/dev/pts/2', timeout=1)
+# client = ModbusClient(method='rtu', port='/dev/ttyp0', timeout=1)
 client.connect()
 
 #---------------------------------------------------------------------------# 
@@ -67,7 +67,7 @@ client.connect()
 # individual request. This can be done by specifying the `unit` parameter
 # which defaults to `0x00`
 #---------------------------------------------------------------------------# 
-rr = client.read_coils(1, 1, unit=0x02)
+rr = client.read_coils(1, 1, unit=0x01)
 
 #---------------------------------------------------------------------------# 
 # example requests
@@ -81,39 +81,46 @@ rr = client.read_coils(1, 1, unit=0x02)
 # Keep both of these cases in mind when testing as the following will
 # _only_ pass with the supplied async modbus server (script supplied).
 #---------------------------------------------------------------------------# 
-rq = client.write_coil(1, True)
-rr = client.read_coils(1,1)
+rq = client.write_coil(0, True, unit=1)
+rr = client.read_coils(0, 1, unit=1)
 assert(rq.function_code < 0x80)     # test that we are not an error
 assert(rr.bits[0] == True)          # test the expected value
 
-rq = client.write_coils(1, [True]*8)
-rr = client.read_coils(1,8)
+rq = client.write_coils(1, [True]*8, unit=1)
+rr = client.read_coils(1, 8, unit=1)
 assert(rq.function_code < 0x80)     # test that we are not an error
 assert(rr.bits == [True]*8)         # test the expected value
 
-rq = client.write_coils(1, [False]*8)
-rr = client.read_discrete_inputs(1,8)
+rq = client.write_coils(1, [False]*8, unit=1)
+rr = client.read_coils(1, 8, unit=1)
 assert(rq.function_code < 0x80)     # test that we are not an error
 assert(rr.bits == [False]*8)         # test the expected value
 
-rq = client.write_register(1, 10)
-rr = client.read_holding_registers(1,1)
+
+rr = client.read_discrete_inputs(0, 8, unit=1)
+assert(rq.function_code < 0x80)     # test that we are not an error
+
+rq = client.write_register(1, 10, unit=1)
+rr = client.read_holding_registers(1, 1, unit=1)
 assert(rq.function_code < 0x80)     # test that we are not an error
 assert(rr.registers[0] == 10)       # test the expected value
 
-rq = client.write_registers(1, [10]*8)
-rr = client.read_input_registers(1,8)
+rq = client.write_registers(1, [10]*8, unit=1)
+rr = client.read_holding_registers(1, 8, unit=1)
 assert(rq.function_code < 0x80)     # test that we are not an error
 assert(rr.registers == [10]*8)      # test the expected value
 
+rr = client.read_input_registers(1, 8, unit=1)
+assert(rq.function_code < 0x80)     # test that we are not an error
+
 arguments = {
     'read_address':    1,
     'read_count':      8,
     'write_address':   1,
     'write_registers': [20]*8,
 }
-rq = client.readwrite_registers(**arguments)
-rr = client.read_input_registers(1,8)
+rq = client.readwrite_registers(unit=1, **arguments)
+rr = client.read_holding_registers(1, 8, unit=1)
 assert(rq.function_code < 0x80)     # test that we are not an error
 assert(rq.registers == [20]*8)      # test the expected value
 assert(rr.registers == [20]*8)      # test the expected value
diff --git a/examples/common/synchronous-server.py b/examples/common/synchronous-server.py
index f463864..9953da6 100755
--- a/examples/common/synchronous-server.py
+++ b/examples/common/synchronous-server.py
@@ -96,16 +96,16 @@ context = ModbusServerContext(slaves=store, single=True)
 identity = ModbusDeviceIdentification()
 identity.VendorName  = 'Pymodbus'
 identity.ProductCode = 'PM'
-identity.VendorUrl   = 'http://github.com/bashwork/pymodbus/'
+identity.VendorUrl   = 'http://github.com/riptideio/pymodbus/'
 identity.ProductName = 'Pymodbus Server'
 identity.ModelName   = 'Pymodbus Server'
 identity.MajorMinorRevision = '1.0'
 
-#---------------------------------------------------------------------------# 
+#---------------------------------------------------------------------------#
 # run the server you want
 #---------------------------------------------------------------------------# 
 # Tcp:
-StartTcpServer(context, identity=identity, address=("localhost", 5020))
+# StartTcpServer(context, identity=identity, address=("localhost", 5020))
 
 # Udp:
 #StartUdpServer(context, identity=identity, address=("localhost", 502))
@@ -114,4 +114,4 @@ StartTcpServer(context, identity=identity, address=("localhost", 5020))
 #StartSerialServer(context, identity=identity, port='/dev/pts/3', timeout=1)
 
 # RTU:
-#StartSerialServer(context, framer=ModbusRtuFramer, identity=identity, port='/dev/pts/3', timeout=.005)
+StartSerialServer(context, framer=ModbusRtuFramer, identity=identity, port='/dev/ptyp0', timeout=.005, baudrate=9600)
diff --git a/examples/contrib/modicon-payload.py b/examples/contrib/modicon-payload.py
index 2351c52..2803ebf 100644
--- a/examples/contrib/modicon-payload.py
+++ b/examples/contrib/modicon-payload.py
@@ -155,13 +155,16 @@ class ModiconPayloadDecoder(object):
         second  = decoder.decode_16bit_uint()
     '''
 
-    def __init__(self, payload):
+    def __init__(self, payload, endian):
+
         ''' Initialize a new payload decoder
 
         :param payload: The payload to decode with
         '''
         self._payload = payload
         self._pointer = 0x00
+        self._endian = endian
+
 
     @staticmethod
     def fromRegisters(registers, endian=Endian.Little):
diff --git a/ez_setup.py b/ez_setup.py
index d24e845..0f92ac8 100755
--- a/ez_setup.py
+++ b/ez_setup.py
@@ -1,4 +1,5 @@
 #!python
+from __future__ import print_function
 """Bootstrap setuptools installation
 
 If you want to use setuptools in your package's setup.py, just include this
@@ -14,8 +15,10 @@ the appropriate options to ``use_setuptools()``.
 This file can also be run as a script to install or upgrade setuptools.
 """
 import sys
-DEFAULT_VERSION = "0.6c9"
+
+DEFAULT_VERSION = "0.6c11"
 DEFAULT_URL     = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
+IS_PYTHON3 = sys.version_info[0] == 3
 
 md5_data = {
     'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
@@ -28,6 +31,14 @@ md5_data = {
     'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
     'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
     'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
+    'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
+    'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
+    'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
+    'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
+    'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
+    'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
+    'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
+    'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
     'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
     'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
     'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
@@ -58,14 +69,16 @@ import sys, os
 try: from hashlib import md5
 except ImportError: from md5 import md5
 
+
+def print_error(msg, **kwargs):
+    print(msg, file=sys.stderr, **kwargs)
+
+
 def _validate_md5(egg_name, data):
     if egg_name in md5_data:
         digest = md5(data).hexdigest()
         if digest != md5_data[egg_name]:
-            print >>sys.stderr, (
-                "md5 validation of %s failed!  (Possible download problem?)"
-                % egg_name
-            )
+            print_error("md5 validation of %s failed!  (Possible download problem?)" % egg_name)
             sys.exit(2)
     return data
 
@@ -95,20 +108,20 @@ def use_setuptools(
         return do_download()       
     try:
         pkg_resources.require("setuptools>="+version); return
-    except pkg_resources.VersionConflict, e:
+    except pkg_resources.VersionConflict as e:
         if was_imported:
-            print >>sys.stderr, (
+            print_error((
             "The required version of setuptools (>=%s) is not available, and\n"
             "can't be installed while this script is running. Please install\n"
             " a more recent version first, using 'easy_install -U setuptools'."
             "\n\n(Currently using %r)"
-            ) % (version, e.args[0])
+            ) % (version, e.args[0]))
             sys.exit(2)
-        else:
-            del pkg_resources, sys.modules['pkg_resources']    # reload ok
-            return do_download()
     except pkg_resources.DistributionNotFound:
-        return do_download()
+        pass
+
+    del pkg_resources, sys.modules['pkg_resources']    # reload ok
+    return do_download()
 
 def download_setuptools(
     version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
@@ -121,7 +134,7 @@ def download_setuptools(
     with a '/'). `to_dir` is the directory where the egg will be downloaded.
     `delay` is the number of seconds to pause before an actual download attempt.
     """
-    import urllib2, shutil
+    import urllib.request, urllib.error, urllib.parse, shutil
     egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
     url = download_base + egg_name
     saveto = os.path.join(to_dir, egg_name)
@@ -147,7 +160,7 @@ and place it in this directory before rerunning this script.)
                     version, download_base, delay, url
                 ); from time import sleep; sleep(delay)
             log.warn("Downloading %s", url)
-            src = urllib2.urlopen(url)
+            src = urllib.request.urlopen(url)
             # Read/write all in one block, so we don't create a corrupt file
             # if the download is interrupted.
             data = _validate_md5(egg_name, src.read())
@@ -208,10 +221,10 @@ def main(argv, version=DEFAULT_VERSION):
                 os.unlink(egg)
     else:
         if setuptools.__version__ == '0.0.1':
-            print >>sys.stderr, (
+            print((
             "You have an obsolete version of setuptools installed.  Please\n"
             "remove it from your system entirely before rerunning this script."
-            )
+            ), file=sys.stderr)
             sys.exit(2)
 
     req = "setuptools>="+version
@@ -230,8 +243,8 @@ def main(argv, version=DEFAULT_VERSION):
             from setuptools.command.easy_install import main
             main(argv)
         else:
-            print "Setuptools version",version,"or greater has been installed."
-            print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
+            print("Setuptools version",version,"or greater has been installed.")
+            print('(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)')
 
 def update_md5(filenames):
     """Update our built-in md5 registry"""
@@ -244,7 +257,7 @@ def update_md5(filenames):
         md5_data[base] = md5(f.read()).hexdigest()
         f.close()
 
-    data = ["    %r: %r,\n" % it for it in md5_data.items()]
+    data = ["    %r: %r,\n" % it for it in list(md5_data.items())]
     data.sort()
     repl = "".join(data)
 
@@ -254,7 +267,7 @@ def update_md5(filenames):
 
     match = re.search("\nmd5_data = {\n([^}]+)}", src)
     if not match:
-        print >>sys.stderr, "Internal error!"
+        print("Internal error!", file=sys.stderr)
         sys.exit(2)
 
     src = src[:match.start(1)] + repl + src[match.end(1):]
diff --git a/pymodbus/__init__.py b/pymodbus/__init__.py
index a204ceb..8319957 100644
--- a/pymodbus/__init__.py
+++ b/pymodbus/__init__.py
@@ -14,6 +14,7 @@ Released under the the BSD license
 import pymodbus.version as __version
 __version__ = __version.version.short()
 __author__  = 'Galen Collins'
+__maintainer__ = 'dhoomakethu'
 
 #---------------------------------------------------------------------------#
 # Block unhandled logging
@@ -28,10 +29,3 @@ except ImportError:
 
 __logging.getLogger(__name__).addHandler(__null())
 
-#---------------------------------------------------------------------------#
-# Define True and False if we don't have them (2.3.2)
-#---------------------------------------------------------------------------#
-try:
-    True, False
-except NameError:
-    True, False = (1 == 1), (0 == 1)
diff --git a/pymodbus/bit_read_message.py b/pymodbus/bit_read_message.py
index f0dd6e3..abe6cc1 100644
--- a/pymodbus/bit_read_message.py
+++ b/pymodbus/bit_read_message.py
@@ -8,13 +8,13 @@ from pymodbus.pdu import ModbusRequest
 from pymodbus.pdu import ModbusResponse
 from pymodbus.pdu import ModbusExceptions as merror
 from pymodbus.utilities import pack_bitstring, unpack_bitstring
+from pymodbus.compat import byte2int
 
 
 class ReadBitsRequestBase(ModbusRequest):
     ''' Base class for Messages Requesting bit values '''
 
     _rtu_frame_size = 8
-
     def __init__(self, address, count, **kwargs):
         ''' Initializes the read request data
 
@@ -23,7 +23,7 @@ class ReadBitsRequestBase(ModbusRequest):
         '''
         ModbusRequest.__init__(self, **kwargs)
         self.address = address
-        self.count   = count
+        self.count = count
 
     def encode(self):
         ''' Encodes a request pdu
@@ -38,7 +38,14 @@ class ReadBitsRequestBase(ModbusRequest):
         :param data: The packet data to decode
         '''
         self.address, self.count = struct.unpack('>HH', data)
-
+    
+    def get_response_pdu_size(self):
+        """
+        Func_code (1 byte) + Byte Count(1 byte) + Quantity of Coils (n Bytes)
+        :return: 
+        """
+        return 1 + 1 + self.count
+    
     def __str__(self):
         ''' Returns a string representation of the instance
 
@@ -74,7 +81,7 @@ class ReadBitsResponseBase(ModbusResponse):
 
         :param data: The packet data to decode
         '''
-        self.byte_count = struct.unpack(">B", data[0])[0]
+        self.byte_count = byte2int(data[0])
         self.bits = unpack_bitstring(data[1:])
 
     def setBit(self, address, value=1):
diff --git a/pymodbus/bit_write_message.py b/pymodbus/bit_write_message.py
index 64f291d..641c1cf 100644
--- a/pymodbus/bit_write_message.py
+++ b/pymodbus/bit_write_message.py
@@ -83,6 +83,13 @@ class WriteSingleCoilRequest(ModbusRequest):
         values = context.getValues(self.function_code, self.address, 1)
         return WriteSingleCoilResponse(self.address, values[0])
 
+    def get_response_pdu_size(self):
+        """
+        Func_code (1 byte) + Output Address (2 byte) + Output Value  (2 Bytes)
+        :return: 
+        """
+        return 1 + 2 + 2
+
     def __str__(self):
         ''' Returns a string representation of the instance
 
@@ -148,7 +155,7 @@ class WriteMultipleCoilsRequest(ModbusRequest):
     '''
     function_code = 15
     _rtu_byte_count_pos = 6
-
+    
     def __init__(self, address=None, values=None, **kwargs):
         ''' Initializes a new instance
 
@@ -160,7 +167,7 @@ class WriteMultipleCoilsRequest(ModbusRequest):
         if not values: values = []
         elif not hasattr(values, '__iter__'): values = [values]
         self.values  = values
-        self.byte_count = (len(self.values) + 7) / 8
+        self.byte_count = (len(self.values) + 7) // 8
 
     def encode(self):
         ''' Encodes write coils request
@@ -168,7 +175,7 @@ class WriteMultipleCoilsRequest(ModbusRequest):
         :returns: The byte encoded message
         '''
         count   = len(self.values)
-        self.byte_count = (count + 7) / 8
+        self.byte_count = (count + 7) // 8
         packet  = struct.pack('>HHB', self.address, count, self.byte_count)
         packet += pack_bitstring(self.values)
         return packet
@@ -191,7 +198,7 @@ class WriteMultipleCoilsRequest(ModbusRequest):
         count = len(self.values)
         if not (1 <= count <= 0x07b0):
             return self.doException(merror.IllegalValue)
-        if (self.byte_count != (count + 7) / 8):
+        if (self.byte_count != (count + 7) // 8):
             return self.doException(merror.IllegalValue)
         if not context.validate(self.function_code, self.address, count):
             return self.doException(merror.IllegalAddress)
diff --git a/pymodbus/client/async.py b/pymodbus/client/async.py
index 5f19e58..6dc332f 100644
--- a/pymodbus/client/async.py
+++ b/pymodbus/client/async.py
@@ -81,7 +81,7 @@ class ModbusClientProtocol(protocol.Protocol, ModbusClientMixin):
         '''
         _logger.debug("Client disconnected from modbus server: %s" % reason)
         self._connected = False
-        for tid in self.transaction:
+        for tid in list(self.transaction):
             self.transaction.getTransaction(tid).errback(Failure(
                 ConnectionException('Connection lost during request')))
 
diff --git a/pymodbus/client/sync.py b/pymodbus/client/sync.py
index 079b4e9..2d93e66 100644
--- a/pymodbus/client/sync.py
+++ b/pymodbus/client/sync.py
@@ -1,5 +1,6 @@
 import socket
 import serial
+import time
 
 from pymodbus.constants import Defaults
 from pymodbus.factory import ClientDecoder
@@ -140,7 +141,7 @@ class ModbusTcpClient(BaseModbusClient):
             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:
+        except socket.error as msg:
             _logger.error('Connection to (%s, %s) failed: %s' % \
                 (self.host, self.port, msg))
             self.close()
@@ -229,7 +230,7 @@ class ModbusUdpClient(BaseModbusClient):
             family = ModbusUdpClient._get_address_family(self.host)
             self.socket = socket.socket(family, socket.SOCK_DGRAM)
             self.socket.settimeout(self.timeout)
-        except socket.error, ex:
+        except socket.error as ex:
             _logger.error('Unable to create udp socket %s' % ex)
             self.close()
         return self.socket != None
@@ -303,6 +304,9 @@ class ModbusSerialClient(BaseModbusClient):
         self.parity   = kwargs.get('parity',   Defaults.Parity)
         self.baudrate = kwargs.get('baudrate', Defaults.Baudrate)
         self.timeout  = kwargs.get('timeout',  Defaults.Timeout)
+        if self.method == "rtu":
+            self._last_frame_end = 0.0
+            self._silent_interval = 3.5 * (1 + 8 + 2) / self.baudrate
 
     @staticmethod
     def __implementation(method):
@@ -328,9 +332,11 @@ class ModbusSerialClient(BaseModbusClient):
             self.socket = serial.Serial(port=self.port, timeout=self.timeout,
                 bytesize=self.bytesize, stopbits=self.stopbits,
                 baudrate=self.baudrate, parity=self.parity)
-        except serial.SerialException, msg:
+        except serial.SerialException as msg:
             _logger.error(msg)
             self.close()
+        if self.method == "rtu":
+            self._last_frame_end = time.time()
         return self.socket != None
 
     def close(self):
@@ -343,13 +349,40 @@ class ModbusSerialClient(BaseModbusClient):
     def _send(self, request):
         ''' Sends data on the underlying socket
 
+        If receive buffer still holds some data then flush it.
+
+        Sleep if last send finished less than 3.5 character
+        times ago.
+
         :param request: The encoded request to send
         :return: The number of bytes written
         '''
         if not self.socket:
             raise ConnectionException(self.__str__())
         if request:
-            return self.socket.write(request)
+            ts = time.time()
+            if self.method == "rtu":
+                if ts < self._last_frame_end + self._silent_interval:
+                    _logger.debug("will sleep to wait for 3.5 char")
... 4111 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/pymodbus.git



More information about the Python-modules-commits mailing list