[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