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

Wolfgang Borgert debacle at moszumanska.debian.org
Mon May 29 08:07: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 80e112463dbbd632734dbf53c6bb3d9c4792b2e9
Author: W. Martin Borgert <debacle at debian.org>
Date:   Sun May 28 23:03:57 2017 +0200

    import new upstream version 1.3.0~rc2
---
 .coveragerc                             |   2 +
 .gitignore                              |  11 ++
 .travis.yml                             |  32 +++++
 CHANGELOG.rst                           |  10 ++
 Makefile                                |  64 ++++++++++
 README.rst                              |  31 ++++-
 doc/sphinx/conf.py                      | 203 +++++++++-----------------------
 doc/sphinx/examples/bottle-frontend.rst |   2 +-
 doc/sphinx/examples/index.rst           |   1 +
 doc/sphinx/library/sync-client.rst      |   3 -
 examples/common/modbus-payload.py       |  12 +-
 examples/common/synchronous-server.py   |   4 +-
 examples/contrib/message-generator.py   |  11 +-
 pymodbus/client/sync.py                 |   7 +-
 pymodbus/payload.py                     |  17 ++-
 pymodbus/register_read_message.py       |   7 ++
 pymodbus/server/async.py                |   2 +-
 pymodbus/transaction.py                 |   2 +-
 pymodbus/utilities.py                   |  13 +-
 pymodbus/version.py                     |   2 +-
 requirements-checks.txt                 |   4 +
 requirements-tests.txt                  |  12 ++
 requirements.txt                        |   1 +
 scripts/travis.sh                       |  11 ++
 test/test_client_sync.py                |  13 ++
 test/test_mei_messages.py               |   6 +-
 test/test_payload.py                    |  16 ++-
 tox.ini                                 |  16 +++
 28 files changed, 338 insertions(+), 177 deletions(-)

diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 0000000..2049cc7
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,2 @@
+[report]
+show_missing = True
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 58a3b23..3998172 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,14 @@ pymodbus.egg-info/
 .noseids
 
 .idea/
+.tox/
+doc/api/epydoc/html/
+.vscode/
+
+__pycache__/
+pymodbus/__pycache__/
+pymodbus/client/__pycache__/
+pymodbus/datastore/__pycache__/
+pymodbus/internal/__pycache__/
+pymodbus/server/__pycache__/
+test/__pycache__/
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..6817288
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,32 @@
+sudo: false
+language: python
+matrix:
+  include:
+  - os: linux
+    python: "2.7"
+  - os: linux
+    python: "3.4"
+  - os: linux
+    python: "3.5"
+  - os: linux
+    python: "3.6"
+  - os: osx
+    language: generic
+before_install:
+  - if [ $TRAVIS_OS_NAME = osx ]; then brew update; fi
+  - if [ $TRAVIS_OS_NAME = osx ]; then brew install openssl; fi
+
+install:
+#  - scripts/travis.sh pip install pip-accel
+  - scripts/travis.sh pip install coveralls
+  - scripts/travis.sh pip install --requirement=requirements-checks.txt
+  - scripts/travis.sh pip install --requirement=requirements-tests.txt
+  - scripts/travis.sh LC_ALL=C pip install .
+script:
+#  - scripts/travis.sh make check
+  - scripts/travis.sh make test
+after_success:
+  - scripts/travis.sh coveralls
+branches:
+  except:
+    - /^[0-9]/
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 5133664..2ddb972 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,3 +1,13 @@
+
+Version 1.3.0.rc2
+------------------------------------------------------------
+* Fix encoding problem for ReadDeviceInformationRequest method on python3
+* Fix problem with the usage of ord in python3 while cleaning up receive buffer
+* Fix struct unpack errors with BinaryPayloadDecoder on python3 - string vs bytestring error
+* Calculate expected response size for ReadWriteMultipleRegistersRequest
+* Enhancement for ModbusTcpClient, ModbusTcpClient can now accept connection timeout as one of the parameter
+* Misc updates
+
 Version 1.3.0.rc1
 ------------------------------------------------------------
 * Timing improvements over MODBUS Serial interface
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..e9f7d9e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,64 @@
+# Makefile for the `pymodbus' package.
+
+WORKON_HOME ?= $(HOME)/.virtualenvs
+VIRTUAL_ENV ?= $(WORKON_HOME)/pymodbus
+PATH := $(VIRTUAL_ENV)/bin:$(PATH)
+MAKE := $(MAKE) --no-print-directory
+SHELL = bash
+
+default:
+	@echo 'Makefile for pymodbus'
+	@echo
+	@echo 'Usage:'
+	@echo
+	@echo '    make install    install the package in a virtual environment'
+	@echo '    make reset      recreate the virtual environment'
+	@echo '    make check      check coding style (PEP-8, PEP-257)'
+	@echo '    make test       run the test suite, report coverage'
+	@echo '    make tox        run the tests on all Python versions'
+	@echo '    make clean      cleanup all temporary files'
+	@echo
+
+install:
+	@test -d "$(VIRTUAL_ENV)" || mkdir -p "$(VIRTUAL_ENV)"
+	@test -x "$(VIRTUAL_ENV)/bin/python" || virtualenv --quiet "$(VIRTUAL_ENV)"
+	@test -x "$(VIRTUAL_ENV)/bin/pip" || easy_install pip
+	@pip install --quiet --requirement=requirements.txt
+	@pip uninstall --yes pymodbus &>/dev/null || true
+	@pip install --quiet --no-deps --ignore-installed .
+
+reset:
+	$(MAKE) clean
+	rm -Rf "$(VIRTUAL_ENV)"
+	$(MAKE) install
+
+check: install
+	@pip install --upgrade --quiet --requirement=requirements-checks.txt
+	@flake8
+
+test: install
+	@pip install --quiet --requirement=requirements-tests.txt
+	@nosetests --with-coverage --cover-html
+	@coverage report --fail-under=90
+
+tox: install
+	@pip install --quiet tox && tox
+
+docs: install
+	@pip install --quiet sphinx
+	@cd doc/sphinx && sphinx-build -nb html -d doctrees . html
+
+publish: install
+	git push origin && git push --tags origin
+	$(MAKE) clean
+	pip install --quiet twine wheel
+	python setup.py sdist bdist_wheel
+	twine upload dist/*
+	$(MAKE) clean
+
+clean:
+	@rm -Rf *.egg .cache .coverage .tox build dist docs/build htmlcov
+	@find -depth -type d -name __pycache__ -exec rm -Rf {} \;
+	@find -type f -name '*.pyc' -delete
+
+.PHONY: default install reset check test tox docs publish clean
diff --git a/README.rst b/README.rst
index c9b6f77..582926f 100644
--- a/README.rst
+++ b/README.rst
@@ -1,3 +1,9 @@
+.. image:: https://travis-ci.org/riptideio/pymodbus.svg?branch=master
+   :target: https://travis-ci.org/riptideio/pymodbus 
+
+.. image:: https://badges.gitter.im/Join%20Chat.svg
+   :target: https://gitter.im/pymodbus_dev/Lobby
+
 ============================================================
 Summary
 ============================================================
@@ -115,11 +121,34 @@ like your device tested, I accept devices via mail or by IP address.
 That said, the current work mainly involves polishing the library as
 I get time doing such tasks as:
 
+  * Add CI support
+  * Make PEP-8 compatible and flake8 ready
   * Fixing bugs/feature requests
   * Architecture documentation
   * Functional testing against any reference I can find
   * The remaining edges of the protocol (that I think no one uses)
-   
+
+------------------------------------------------------------
+Development Instructions
+------------------------------------------------------------
+The current code base is compatible with both py2 and py3.
+Use make to perform a range of activities
+
+::
+
+    $ make
+       Makefile for pymodbus
+
+    Usage:
+
+     make install    install the package in a virtual environment
+     make reset      recreate the virtual environment
+     make check      check coding style (PEP-8, PEP-257)
+     make test       run the test suite, report coverage
+     make tox        run the tests on all Python versions
+     make clean      cleanup all temporary files 
+
+
 ------------------------------------------------------------
 License Information
 ------------------------------------------------------------
diff --git a/doc/sphinx/conf.py b/doc/sphinx/conf.py
index e223ad5..3faaccc 100644
--- a/doc/sphinx/conf.py
+++ b/doc/sphinx/conf.py
@@ -1,9 +1,10 @@
 # -*- coding: utf-8 -*-
 #
-# PyModbus documentation build configuration file, created by
-# sphinx-quickstart on Tue Apr 14 19:11:16 2009.
+# pymodbus documentation build configuration file, created by
+# sphinx-quickstart on Fri May 26 10:10:53 2017.
 #
-# This file is execfile()d with the current directory set to its containing dir.
+# This file is execfile()d with the current directory set to its
+# containing dir.
 #
 # Note that not all possible configuration values are present in this
 # autogenerated file.
@@ -11,188 +12,98 @@
 # All configuration values have a default; values that are commented out
 # serve to show the default.
 
-import sys, os
-
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.append(os.path.abspath('.'))
+#
+import os
+import sys
+
+sys.path.insert(0, os.path.abspath(os.pardir))
 
-# -- General configuration -----------------------------------------------------
+from pymodbus import __version__, __author__, __maintainer__
 
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage']
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+# Sphinx extension module names.
+extensions = [
+    'sphinx.ext.autodoc',
+    'sphinx.ext.intersphinx',
+    'sphinx.ext.viewcode',
+    'humanfriendly.sphinx',
+]
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
 
+# Sort members by the source order instead of alphabetically.
+autodoc_member_order = 'bysource'
+
+# Paths that contain templates, relative to this directory.
+templates_path = ['templates']
+
 # The suffix of source filenames.
 source_suffix = '.rst'
 
-# The encoding of source files.
-#source_encoding = 'utf-8'
-
 # The master toctree document.
 master_doc = 'index'
 
 # General information about the project.
-project = u'Pymodbus'
-copyright = u'2009, Galen Collins'
+project = u'pymodbus'
+copyright = u'2017, {}, {}'.format(__author__, __maintainer__)
+author = u'{}, {}'.format(__author__, __maintainer__)
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 #
 # The short X.Y version.
-version = '1.0'
+version = __version__
 # The full version, including alpha/beta/rc tags.
-release = '1.0'
+release = __version__
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of documents that shouldn't be included in the build.
-#unused_docs = []
-
-# List of directories, relative to source directory, that shouldn't be searched
-# for source files.
-exclude_trees = ['build']
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = 'en'
 
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['build', '_build', 'Thumbs.db', '.DS_Store']
 
 # If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-show_authors = True
+add_function_parentheses = True
 
 # The name of the Pygments (syntax highlighting) style to use.
 pygments_style = 'sphinx'
 
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
+# Refer to the Python standard library.
+# From: http://twistedmatrix.com/trac/ticket/4582.
+intersphinx_mapping = dict(
+    python=('https://docs.python.org/2', None),
+    capturer=('https://capturer.readthedocs.io/en/latest', None),
+    humanfriendly=('https://humanfriendly.readthedocs.io/en/latest', None),
+)
 
+# -- Options for HTML output --------------------------------------------------
 
-# -- Options for extensions ---------------------------------------------------
-autodoc_default_flags = ['members', 'inherited-members', 'show-inheritance']
-autoclass_content = 'both'
-
-# -- Options for HTML output ---------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages.  Major themes that come with
-# Sphinx are currently 'default' and 'sphinxdoc'.
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
 html_theme = 'default'
 
-# Theme options are theme-specific and customize the look and feel of a theme
-# further.  For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'pymodbusdoc'
 
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
 # so a file named "default.css" will overwrite the builtin "default.css".
 html_static_path = ['static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_use_modindex = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = ''
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'Pymodbus'
-
-
-# -- Options for LaTeX output --------------------------------------------------
-
-# The paper size ('letter' or 'a4').
-#latex_paper_size = 'letter'
-
-# The font size ('10pt', '11pt' or '12pt').
-#latex_font_size = '10pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
-  ('index', 'Pymodbus.tex', ur'Pymodbus Documentation',
-   ur'Galen Collins', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# Additional stuff for the LaTeX preamble.
-#latex_preamble = ''
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_use_modindex = True
diff --git a/doc/sphinx/examples/bottle-frontend.rst b/doc/sphinx/examples/bottle-frontend.rst
index 662f2a7..95507c5 100644
--- a/doc/sphinx/examples/bottle-frontend.rst
+++ b/doc/sphinx/examples/bottle-frontend.rst
@@ -18,5 +18,5 @@ run behind gunicorn, cherrypi, etc wsgi containers.
 Main Program
 --------------------------------------------------
 
-.. literalinclude:: ../../../examples/gui/web/frontend.py
+.. literalinclude:: ../../../examples/gui/bottle/frontend.py
 
diff --git a/doc/sphinx/examples/index.rst b/doc/sphinx/examples/index.rst
index 84f5c94..a41f011 100644
--- a/doc/sphinx/examples/index.rst
+++ b/doc/sphinx/examples/index.rst
@@ -15,6 +15,7 @@ Example Library Code
    asynchronous-server
    asynchronous-processor
    custom-message
+   custom-datablock
    modbus-logging
    modbus-payload
    modbus-payload-server
diff --git a/doc/sphinx/library/sync-client.rst b/doc/sphinx/library/sync-client.rst
index af3059b..5f60a3a 100644
--- a/doc/sphinx/library/sync-client.rst
+++ b/doc/sphinx/library/sync-client.rst
@@ -12,9 +12,6 @@ API Documentation
 
 .. automodule:: pymodbus.client.sync
 
-.. autoclass:: ModbusTransactionManager
-   :members:
-
 .. autoclass:: BaseModbusClient
    :members:
 
diff --git a/examples/common/modbus-payload.py b/examples/common/modbus-payload.py
index d79926a..03dbad3 100755
--- a/examples/common/modbus-payload.py
+++ b/examples/common/modbus-payload.py
@@ -2,6 +2,8 @@
 '''
 Pymodbus Payload Building/Decoding Example
 --------------------------------------------------------------------------
+
+# Run modbus-payload-server.py or synchronous-server.py to check the behavior
 '''
 from pymodbus.constants import Endian
 from pymodbus.payload import BinaryPayloadDecoder
@@ -35,14 +37,14 @@ client.connect()
 # - an 8 bit int 0x12
 # - an 8 bit bitstring [0,1,0,1,1,0,1,0]
 #---------------------------------------------------------------------------# 
-builder = BinaryPayloadBuilder(endian=Endian.Little)
+builder = BinaryPayloadBuilder(endian=Endian.Big)
 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])
 payload = builder.build()
-address = 0x01
+address = 0
 result  = client.write_registers(address, payload, skip_encode=True, unit=1)
 
 #---------------------------------------------------------------------------# 
@@ -58,10 +60,10 @@ result  = client.write_registers(address, payload, skip_encode=True, unit=1)
 # - an 8 bit int 0x12
 # - an 8 bit bitstring [0,1,0,1,1,0,1,0]
 #---------------------------------------------------------------------------# 
-address = 0x01
+address = 0x00
 count   = 8
-result  = client.read_input_registers(address, count,  unit=1)
-decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Little)
+result  = client.read_holding_registers(address, count,  unit=1)
+decoder = BinaryPayloadDecoder.fromRegisters(result.registers, endian=Endian.Big)
 decoded = {
     'string': decoder.decode_string(8),
     'float': decoder.decode_32bit_float(),
diff --git a/examples/common/synchronous-server.py b/examples/common/synchronous-server.py
index 9953da6..72e8301 100755
--- a/examples/common/synchronous-server.py
+++ b/examples/common/synchronous-server.py
@@ -105,7 +105,7 @@ 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 @@ identity.MajorMinorRevision = '1.0'
 #StartSerialServer(context, identity=identity, port='/dev/pts/3', timeout=1)
 
 # RTU:
-StartSerialServer(context, framer=ModbusRtuFramer, identity=identity, port='/dev/ptyp0', timeout=.005, baudrate=9600)
+# StartSerialServer(context, framer=ModbusRtuFramer, identity=identity, port='/dev/ptyp0', timeout=.005, baudrate=9600)
diff --git a/examples/contrib/message-generator.py b/examples/contrib/message-generator.py
index 1145670..b9a1e8f 100755
--- a/examples/contrib/message-generator.py
+++ b/examples/contrib/message-generator.py
@@ -165,11 +165,11 @@ def generate_messages(framer, options):
     messages = _request_messages if options.messages == 'tx' else _response_messages
     for message in messages:
         message = message(**_arguments)
-        print "%-44s = " % message.__class__.__name__,
+        print ("%-44s = " % message.__class__.__name__)
         packet = framer.buildPacket(message)
         if not options.ascii:
             packet = packet.encode('hex') + '\n'
-        print packet,   # because ascii ends with a \r\n
+        print (packet)   # because ascii ends with a \r\n
 
 
 #---------------------------------------------------------------------------# 
@@ -205,6 +205,7 @@ def get_options():
     (opt, arg) = parser.parse_args()
     return opt
 
+
 def main():
     ''' The main runner function
     '''
@@ -213,9 +214,9 @@ def main():
     if option.debug:
         try:
             modbus_log.setLevel(logging.DEBUG)
-    	    logging.basicConfig()
-        except Exception, e:
-    	    print "Logging is not supported on this system"
+            logging.basicConfig()
+        except Exception as e:
+            print("Logging is not supported on this system")
 
     framer = lookup = {
         'tcp':    ModbusSocketFramer,
diff --git a/pymodbus/client/sync.py b/pymodbus/client/sync.py
index 2d93e66..90f09f2 100644
--- a/pymodbus/client/sync.py
+++ b/pymodbus/client/sync.py
@@ -4,6 +4,7 @@ import time
 
 from pymodbus.constants import Defaults
 from pymodbus.factory import ClientDecoder
+from pymodbus.compat import byte2int
 from pymodbus.exceptions import NotImplementedException, ParameterException
 from pymodbus.exceptions import ConnectionException
 from pymodbus.transaction import FifoTransactionManager
@@ -121,6 +122,7 @@ class ModbusTcpClient(BaseModbusClient):
         :param host: The host to connect to (default 127.0.0.1)
         :param port: The modbus port to connect to (default 502)
         :param source_address: The source address tuple to bind to (default ('', 0))
+        :param timeout: The timeout to use for this socket (default Defaults.Timeout)
         :param framer: The modbus framer to use (default ModbusSocketFramer)
 
         .. note:: The host argument will accept ipv4 and ipv6 hosts
@@ -129,6 +131,7 @@ class ModbusTcpClient(BaseModbusClient):
         self.port = port
         self.source_address = kwargs.get('source_address', ('', 0))
         self.socket = None
+        self.timeout  = kwargs.get('timeout',  Defaults.Timeout)
         BaseModbusClient.__init__(self, framer(ClientDecoder()), **kwargs)
 
     def connect(self):
@@ -140,7 +143,7 @@ class ModbusTcpClient(BaseModbusClient):
         try:
             address = (self.host, self.port)
             self.socket = socket.create_connection((self.host, self.port),
-                timeout=Defaults.Timeout, source_address=self.source_address)
+                timeout=self.timeout, source_address=self.source_address)
         except socket.error as msg:
             _logger.error('Connection to (%s, %s) failed: %s' % \
                 (self.host, self.port, msg))
@@ -375,7 +378,7 @@ class ModbusSerialClient(BaseModbusClient):
                 if waitingbytes:
                     result = self.socket.read(waitingbytes)
                     if _logger.isEnabledFor(logging.WARNING):
-                        _logger.warning("cleanup recv buffer before send: " + " ".join([hex(ord(x)) for x in result]))
+                        _logger.warning("cleanup recv buffer before send: " + " ".join([hex(byte2int(x)) for x in result]))
             except NotImplementedError:
                 pass
 
diff --git a/pymodbus/payload.py b/pymodbus/payload.py
index 58097b2..a34a10f 100644
--- a/pymodbus/payload.py
+++ b/pymodbus/payload.py
@@ -10,6 +10,7 @@ from pymodbus.interfaces import IPayloadBuilder
 from pymodbus.constants import Endian
 from pymodbus.utilities import pack_bitstring
 from pymodbus.utilities import unpack_bitstring
+from pymodbus.utilities import make_byte_string
 from pymodbus.exceptions import ParameterException
 
 
@@ -30,7 +31,7 @@ class BinaryPayloadBuilder(IPayloadBuilder):
     def __init__(self, payload=None, endian=Endian.Little):
         ''' Initialize a new instance of the payload builder
 
-        :param payload: Raw payload data to initialize with
+        :param payload: Raw binary payload data to initialize with
         :param endian: The endianess of the payload
         '''
         self._payload = payload or []
@@ -175,6 +176,7 @@ class BinaryPayloadBuilder(IPayloadBuilder):
 
         :param value: The value to add to the buffer
         '''
+        value = make_byte_string(value)
         fstring = self._endian + str(len(value)) + 's'
         self._payload.append(pack(fstring, value))
 
@@ -246,14 +248,16 @@ class BinaryPayloadDecoder(object):
         self._pointer += 1
         fstring = self._endian + 'B'
         handle = self._payload[self._pointer - 1:self._pointer]
+        handle = make_byte_string(handle)
         return unpack(fstring, handle)[0]
 
     def decode_bits(self):
         ''' Decodes a byte worth of bits from the buffer
         '''
         self._pointer += 1
-        fstring = self._endian + 'B'
+        # fstring = self._endian + 'B'
         handle = self._payload[self._pointer - 1:self._pointer]
+        handle = make_byte_string(handle)
         return unpack_bitstring(handle)
 
     def decode_16bit_uint(self):
@@ -262,6 +266,7 @@ class BinaryPayloadDecoder(object):
         self._pointer += 2
         fstring = self._endian + 'H'
         handle = self._payload[self._pointer - 2:self._pointer]
+        handle = make_byte_string(handle)
         return unpack(fstring, handle)[0]
 
     def decode_32bit_uint(self):
@@ -270,6 +275,7 @@ class BinaryPayloadDecoder(object):
         self._pointer += 4
         fstring = self._endian + 'I'
         handle = self._payload[self._pointer - 4:self._pointer]
+        handle = make_byte_string(handle)
         return unpack(fstring, handle)[0]
 
     def decode_64bit_uint(self):
@@ -278,6 +284,7 @@ class BinaryPayloadDecoder(object):
         self._pointer += 8
         fstring = self._endian + 'Q'
         handle = self._payload[self._pointer - 8:self._pointer]
+        handle = make_byte_string(handle)
         return unpack(fstring, handle)[0]
 
     def decode_8bit_int(self):
@@ -286,6 +293,7 @@ class BinaryPayloadDecoder(object):
         self._pointer += 1
         fstring = self._endian + 'b'
         handle = self._payload[self._pointer - 1:self._pointer]
+        handle = make_byte_string(handle)
         return unpack(fstring, handle)[0]
 
     def decode_16bit_int(self):
@@ -294,6 +302,7 @@ class BinaryPayloadDecoder(object):
         self._pointer += 2
         fstring = self._endian + 'h'
         handle = self._payload[self._pointer - 2:self._pointer]
+        handle = make_byte_string(handle)
         return unpack(fstring, handle)[0]
 
     def decode_32bit_int(self):
@@ -302,6 +311,7 @@ class BinaryPayloadDecoder(object):
         self._pointer += 4
         fstring = self._endian + 'i'
         handle = self._payload[self._pointer - 4:self._pointer]
+        handle = make_byte_string(handle)
         return unpack(fstring, handle)[0]
 
     def decode_64bit_int(self):
@@ -310,6 +320,7 @@ class BinaryPayloadDecoder(object):
         self._pointer += 8
         fstring = self._endian + 'q'
         handle = self._payload[self._pointer - 8:self._pointer]
+        handle = make_byte_string(handle)
         return unpack(fstring, handle)[0]
 
     def decode_32bit_float(self):
@@ -318,6 +329,7 @@ class BinaryPayloadDecoder(object):
         self._pointer += 4
         fstring = self._endian + 'f'
         handle = self._payload[self._pointer - 4:self._pointer]
+        handle = make_byte_string(handle)
         return unpack(fstring, handle)[0]
 
     def decode_64bit_float(self):
@@ -326,6 +338,7 @@ class BinaryPayloadDecoder(object):
         self._pointer += 8
         fstring = self._endian + 'd'
         handle = self._payload[self._pointer - 8:self._pointer]
+        handle = make_byte_string(handle)
         return unpack(fstring, handle)[0]
 
     def decode_string(self, size=1):
diff --git a/pymodbus/register_read_message.py b/pymodbus/register_read_message.py
index 0be01b3..0a202bb 100644
--- a/pymodbus/register_read_message.py
+++ b/pymodbus/register_read_message.py
@@ -289,6 +289,13 @@ class ReadWriteMultipleRegistersRequest(ModbusRequest):
                                       self.read_count)
         return ReadWriteMultipleRegistersResponse(registers)
 
+    def get_response_pdu_size(self):
+        """
+        Func_code (1 byte) + Byte Count(1 byte) + 2 * Quantity of Coils (n Bytes)
+        :return: 
+        """
+        return 1 + 1 + 2 * self.read_count
+
     def __str__(self):
         ''' Returns a string representation of the instance
 
diff --git a/pymodbus/server/async.py b/pymodbus/server/async.py
index 6c809ce..0e1649e 100644
--- a/pymodbus/server/async.py
+++ b/pymodbus/server/async.py
@@ -160,7 +160,7 @@ class ModbusUdpProtocol(protocol.DatagramProtocol):
         '''
         _logger.debug("Client Connected [%s:%s]" % addr)
         if _logger.isEnabledFor(logging.DEBUG):
-            _logger.debug(" ".join([hex(ord(x)) for x in data]))
+            _logger.debug(" ".join([hex(byte2int(x)) for x in data]))
         if not self.control.ListenOnly:
             continuation = lambda request: self._execute(request, addr)
             self.framer.processIncomingPacket(data, continuation)
diff --git a/pymodbus/transaction.py b/pymodbus/transaction.py
index b7b2219..78a6326 100644
--- a/pymodbus/transaction.py
+++ b/pymodbus/transaction.py
@@ -95,7 +95,7 @@ class ModbusTransactionManager(object):
                     retries -= 1
                     continue
                 if _logger.isEnabledFor(logging.DEBUG):
-                    _logger.debug("recv: " + " ".join([hex(ord(x)) for x in result]))
+                    _logger.debug("recv: " + " ".join([hex(byte2int(x)) for x in result]))
                 self.client.framer.processIncomingPacket(result, self.addTransaction)
                 break;
             except socket.error as msg:
diff --git a/pymodbus/utilities.py b/pymodbus/utilities.py
index 0b3ec90..66e7536 100644
--- a/pymodbus/utilities.py
+++ b/pymodbus/utilities.py
@@ -5,8 +5,8 @@ Modbus Utilities
 A collection of utilities for packing data, unpacking
 data computing checksums, and decode checksums.
 '''
-from pymodbus.compat import int2byte, byte2int
-
+from pymodbus.compat import int2byte, byte2int, IS_PYTHON3
+from six import string_types
 
 #---------------------------------------------------------------------------#
 # Helpers
@@ -93,6 +93,15 @@ def unpack_bitstring(string):
     return bits
 
 
+def make_byte_string(s):
+    """
+    Returns byte string from a given string, python3 specific fix
+    :param s: 
+    :return: 
+    """
+    if IS_PYTHON3 and isinstance(s, string_types):
+        s = s.encode()
+    return s
 #---------------------------------------------------------------------------#
 # Error Detection Functions
 #---------------------------------------------------------------------------#
diff --git a/pymodbus/version.py b/pymodbus/version.py
index 597c154..bf884ad 100644
--- a/pymodbus/version.py
+++ b/pymodbus/version.py
@@ -41,7 +41,7 @@ class Version(object):
         return '[%s, version %s]' % (self.package, self.short())
 
 
-version = Version('pymodbus', 1, 3, 0, "rc1")
+version = Version('pymodbus', 1, 3, 0, "rc2")
 
 
 version.__name__ = 'pymodbus'  # fix epydoc error
diff --git a/requirements-checks.txt b/requirements-checks.txt
new file mode 100644
index 0000000..a760996
--- /dev/null
+++ b/requirements-checks.txt
@@ -0,0 +1,4 @@
+# Python packages required to run `make check'.
+flake8 >= 2.6.0
+flake8-docstrings >= 0.2.8
+pyflakes >= 1.2.3
diff --git a/requirements-tests.txt b/requirements-tests.txt
new file mode 100644
index 0000000..85623bb
--- /dev/null
+++ b/requirements-tests.txt
@@ -0,0 +1,12 @@
+capturer >= 2.2
+coverage >= 4.2
+mock >= 1.0.1
+nose>=1.3.7
+pep8>=1.7.0
+verboselogs >= 1.5
+Twisted>=17.1.0
+zope.interface>=4.4.0
+pyasn1>=0.2.3
+pycrypto>=2.6.1
+#wsgiref>=0.1.2
+cryptography>=1.8.1
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 4998330..208865b 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,4 @@
+coloredlogs>=7.0
 # -------------------------------------------------------------------
 # if want to use the pymodbus serial stack, uncomment these
 # -------------------------------------------------------------------
diff --git a/scripts/travis.sh b/scripts/travis.sh
new file mode 100755
index 0000000..5308eb1
--- /dev/null
+++ b/scripts/travis.sh
@@ -0,0 +1,11 @@
+#!/bin/bash -e
+
+if [ "$TRAVIS_OS_NAME" = osx ]; then
+  VIRTUAL_ENV="$HOME/.virtualenvs/python2.7"
+  if [ ! -x "$VIRTUAL_ENV/bin/python" ]; then
+    virtualenv "$VIRTUAL_ENV"
+  fi
+  source "$VIRTUAL_ENV/bin/activate"
+fi
+
+eval "$@"
diff --git a/test/test_client_sync.py b/test/test_client_sync.py
index 0cd4c6c..c88d682 100644
--- a/test/test_client_sync.py
+++ b/test/test_client_sync.py
@@ -251,6 +251,19 @@ class SynchronousClientTest(unittest.TestCase):
         self.assertEqual(0, client._send(None))
         self.assertEqual(4, client._send('1234'))
 
+    @patch("serial.Serial")
+    def testSerialClientCleanupBufferBeforeSend(self, mock_serial):
+        ''' Test the serial client send method'''
+        mock_serial.in_waiting = 4
+        mock_serial.read = lambda x: b'1'*x
+        mock_serial.write = lambda x: len(x)
+        client = ModbusSerialClient()
+        self.assertRaises(ConnectionException, lambda: client._send(None))
+        # client.connect()
+        client.socket = mock_serial
+        self.assertEqual(0, client._send(None))
+        self.assertEqual(4, client._send('1234'))
+
     def testSerialClientRecv(self):
         ''' Test the serial client receive method'''
         client = ModbusSerialClient()
diff --git a/test/test_mei_messages.py b/test/test_mei_messages.py
index 980dd54..dc02f7d 100644
--- a/test/test_mei_messages.py
+++ b/test/test_mei_messages.py
@@ -71,9 +71,9 @@ class ModbusMeiMessageTest(unittest.TestCase):
         message  = b'\x0e\x01\x83\x00\x00\x03'
         message += b'\x00\x07Company\x01\x07Product\x02\x07v2.1.12'
         dataset  = {
-            0x00: b'Company',
-            0x01: b'Product',
-            0x02: b'v2.1.12',
+            0x00: 'Company',
+            0x01: 'Product',
+            0x02: 'v2.1.12',
         }
         handle  = ReadDeviceInformationResponse(
             read_code=DeviceInformation.Basic, information=dataset)
diff --git a/test/test_payload.py b/test/test_payload.py
index 1b7b557..157f584 100644
--- a/test/test_payload.py
+++ b/test/test_payload.py
@@ -79,7 +79,7 @@ class ModbusPayloadUtilityTests(unittest.TestCase):
         builder.add_64bit_int(-4)
         builder.add_32bit_float(1.25)
         builder.add_64bit_float(6.25)
-        builder.add_string(b'test')
+        builder.add_string('test')
         builder.add_bits(self.bitstring)
         self.assertEqual(self.big_endian_payload, builder.to_string())
... 51 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