diff --git a/.gitignore b/.gitignore index bd252e573..1a62fbcd8 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,10 @@ test/__pycache__/ **/pymodbus.db /.eggs/ /.cache/ +/doc/sphinx/doctrees/ +/doc_new/ +/doc/quality/ +/doc/pymodbus.pdf +/doc/sphinx/ +/doc/html/ +/doc/_build/ diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 000000000..6bc8ba793 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,9 @@ +# Build PDF & ePub +formats: + - epub + - pdf +requirements_file: requirements-docs.txt +python: + extra_requirements: + - twisted + - documents diff --git a/Makefile b/Makefile index e9f7d9ef5..4fb5fe634 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,8 @@ default: @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 ' make docs creates sphinx documentation in html' + @echo ' make clean cleanup all temporary files' @echo install: @@ -45,8 +46,8 @@ tox: install @pip install --quiet tox && tox docs: install - @pip install --quiet sphinx - @cd doc/sphinx && sphinx-build -nb html -d doctrees . html + @pip install --quiet --requirement=requirements-docs.txt + @cd doc && make html publish: install git push origin && git push --tags origin diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 000000000..e805f2538 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = PyModbus +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/doc/changelog.rst b/doc/changelog.rst new file mode 100644 index 000000000..4d7817ae3 --- /dev/null +++ b/doc/changelog.rst @@ -0,0 +1 @@ +.. include:: ../CHANGELOG.rst \ No newline at end of file diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 000000000..fc92ce5fb --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# +# PyModbus documentation build configuration file, created by +# sphinx-quickstart on Wed Dec 20 12:31:10 2017. +# +# 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. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# 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. +# +import os +import sys +parent_dir = os.path.abspath(os.pardir) +# examples = os.path.join(parent_dir, "examples") +example_contrib = os.path.join(parent_dir, "examples/contrib") +example_common = os.path.join(parent_dir, "examples/common") +example_gui = os.path.join(parent_dir, "examples/gui") + +sys.path.insert(0, os.path.abspath(os.pardir)) +sys.path.append(example_common) +sys.path.append(example_contrib) +sys.path.append(example_gui) +# sys.path.extend([examples, example_common, example_contrib, example_gui]) +# sys.path.insert(0, os.path.abspath('../')) + + +# -- 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. +extensions = ['sphinx.ext.autodoc'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'PyModbus' +copyright = u'2017, Sanjay' +author = u'Sanjay' + +# 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 = u'1.4.0' +# The full version, including alpha/beta/rc tags. +release = u'1.4.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# 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 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'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + '**': [ + 'relations.html', # needs 'show_related': True theme option to display + 'searchbox.html', + ] +} + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'PyModbusdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'PyModbus.tex', u'PyModbus Documentation', + u'Sanjay', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'pymodbus', u'PyModbus Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'PyModbus', u'PyModbus Documentation', + author, 'PyModbus', 'One line description of project.', + 'Miscellaneous'), +] + + + diff --git a/doc/sphinx/index.rst b/doc/index.rst similarity index 69% rename from doc/sphinx/index.rst rename to doc/index.rst index 7017018f2..9b5491d09 100644 --- a/doc/sphinx/index.rst +++ b/doc/index.rst @@ -1,18 +1,20 @@ .. PyModbus documentation master file, created by - sphinx-quickstart on Tue Apr 14 19:11:16 2009. + sphinx-quickstart on Wed Dec 20 12:31:10 2017. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Welcome to PyModbus's documentation! ==================================== -Contents: - .. toctree:: :maxdepth: 2 + :caption: Contents: + + readme.rst + changelog.rst + source/example/modules.rst + source/library/modules.rst - examples/index.rst - library/index.rst Indices and tables ================== @@ -20,4 +22,3 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` * :ref:`search` - diff --git a/doc/pymodbus.pdf b/doc/pymodbus.pdf deleted file mode 100644 index d3dc1fff8..000000000 Binary files a/doc/pymodbus.pdf and /dev/null differ diff --git a/doc/quality/current.coverage b/doc/quality/current.coverage deleted file mode 100644 index 376726edb..000000000 --- a/doc/quality/current.coverage +++ /dev/null @@ -1,41 +0,0 @@ -Name Stmts Miss Cover Missing ---------------------------------------------------------------- -pymodbus 15 6 60% 24-27, 36-37 -pymodbus.bit_read_message 68 0 100% -pymodbus.bit_write_message 95 0 100% -pymodbus.client 0 0 100% -pymodbus.client.async 70 0 100% -pymodbus.client.common 36 0 100% -pymodbus.client.sync 147 0 100% -pymodbus.constants 36 0 100% -pymodbus.datastore 5 0 100% -pymodbus.datastore.context 50 0 100% -pymodbus.datastore.remote 31 0 100% -pymodbus.datastore.store 67 0 100% -pymodbus.device 159 0 100% -pymodbus.diag_message 202 0 100% -pymodbus.events 60 0 100% -pymodbus.exceptions 22 0 100% -pymodbus.factory 77 0 100% -pymodbus.file_message 181 0 100% -pymodbus.interfaces 46 0 100% -pymodbus.internal 0 0 100% -pymodbus.internal.ptwisted 16 2 88% 29-30 -pymodbus.mei_message 70 0 100% -pymodbus.other_message 145 0 100% -pymodbus.payload 140 2 99% 205, 224 -pymodbus.pdu 72 0 100% -pymodbus.register_read_message 124 0 100% -pymodbus.register_write_message 91 2 98% 39, 148 -pymodbus.server 0 0 100% -pymodbus.server.async 113 39 65% 55-58, 65-74, 81-86, 151-156, 163-172, 180-184 -pymodbus.server.sync 186 0 100% -pymodbus.transaction 275 53 81% 63-81, 116-117, 259, 263, 403, 433-442, 577-586, 656, 733-742, 768-769 -pymodbus.utilities 67 0 100% -pymodbus.version 13 0 100% ---------------------------------------------------------------- -TOTAL 2679 104 96% ----------------------------------------------------------------------- -Ran 255 tests in 0.981s - -OK diff --git a/doc/quality/current.lint b/doc/quality/current.lint deleted file mode 100644 index 848d63e86..000000000 --- a/doc/quality/current.lint +++ /dev/null @@ -1,19 +0,0 @@ -running lint -pymodbus/__init__.py:25: redefinition of unused 'NullHandler' from line 23 -pymodbus/factory.py:12: 'from pymodbus.bit_read_message import *' used; unable to detect undefined names -pymodbus/factory.py:13: 'from pymodbus.bit_write_message import *' used; unable to detect undefined names -pymodbus/factory.py:14: 'from pymodbus.diag_message import *' used; unable to detect undefined names -pymodbus/factory.py:15: 'from pymodbus.file_message import *' used; unable to detect undefined names -pymodbus/factory.py:16: 'from pymodbus.other_message import *' used; unable to detect undefined names -pymodbus/factory.py:17: 'from pymodbus.register_read_message import *' used; unable to detect undefined names -pymodbus/factory.py:18: 'from pymodbus.register_write_message import *' used; unable to detect undefined names -pymodbus/server/async.py:230: local variable 'handle' is assigned to but never used -pymodbus/server/sync.py:16: 'from pymodbus.transaction import *' used; unable to detect undefined names -pymodbus/client/common.py:3: 'from pymodbus.bit_read_message import *' used; unable to detect undefined names -pymodbus/client/common.py:4: 'from pymodbus.bit_write_message import *' used; unable to detect undefined names -pymodbus/client/common.py:5: 'from pymodbus.register_read_message import *' used; unable to detect undefined names -pymodbus/client/common.py:6: 'from pymodbus.register_write_message import *' used; unable to detect undefined names -pymodbus/client/common.py:7: 'from pymodbus.diag_message import *' used; unable to detect undefined names -pymodbus/client/common.py:8: 'from pymodbus.file_message import *' used; unable to detect undefined names -pymodbus/client/common.py:9: 'from pymodbus.other_message import *' used; unable to detect undefined names -pymodbus/client/sync.py:8: 'from pymodbus.transaction import *' used; unable to detect undefined names diff --git a/doc/quality/current.pep8 b/doc/quality/current.pep8 deleted file mode 100644 index ba5cbbaf1..000000000 --- a/doc/quality/current.pep8 +++ /dev/null @@ -1,568 +0,0 @@ -running pep8 -pymodbus/__init__.py:16:11: E221 multiple spaces before operator -pymodbus/bit_read_message.py:26:19: E221 multiple spaces before operator -pymodbus/bit_read_message.py:143:80: E501 line too long (80 characters) -pymodbus/bit_read_message.py:202:80: E501 line too long (80 characters) -pymodbus/bit_write_message.py:19:14: E221 multiple spaces before operator -pymodbus/bit_write_message.py:58:15: E221 multiple spaces before operator -pymodbus/bit_write_message.py:59:22: E701 multiple statements on one line (colon) -pymodbus/bit_write_message.py:60:13: E701 multiple statements on one line (colon) -pymodbus/bit_write_message.py:117:15: E221 multiple spaces before operator -pymodbus/bit_write_message.py:118:22: E701 multiple statements on one line (colon) -pymodbus/bit_write_message.py:119:13: E701 multiple statements on one line (colon) -pymodbus/bit_write_message.py:160:22: E701 multiple statements on one line (colon) -pymodbus/bit_write_message.py:161:45: E701 multiple statements on one line (colon) -pymodbus/bit_write_message.py:162:20: E221 multiple spaces before operator -pymodbus/bit_write_message.py:170:14: E221 multiple spaces before operator -pymodbus/bit_write_message.py:172:15: E221 multiple spaces before operator -pymodbus/constants.py:74:9: E221 multiple spaces before operator -pymodbus/constants.py:75:12: E221 multiple spaces before operator -pymodbus/constants.py:76:12: E221 multiple spaces before operator -pymodbus/constants.py:77:15: E221 multiple spaces before operator -pymodbus/constants.py:79:15: E221 multiple spaces before operator -pymodbus/constants.py:80:11: E221 multiple spaces before operator -pymodbus/constants.py:81:13: E221 multiple spaces before operator -pymodbus/constants.py:82:11: E221 multiple spaces before operator -pymodbus/constants.py:83:13: E221 multiple spaces before operator -pymodbus/constants.py:84:13: E221 multiple spaces before operator -pymodbus/constants.py:118:12: E221 multiple spaces before operator -pymodbus/constants.py:119:10: E221 multiple spaces before operator -pymodbus/constants.py:120:7: E221 multiple spaces before operator -pymodbus/constants.py:121:8: E221 multiple spaces before operator -pymodbus/constants.py:122:12: E221 multiple spaces before operator -pymodbus/constants.py:145:9: E221 multiple spaces before operator -pymodbus/constants.py:146:8: E221 multiple spaces before operator -pymodbus/constants.py:163:18: E221 multiple spaces before operator -pymodbus/constants.py:193:10: E221 multiple spaces before operator -pymodbus/constants.py:194:12: E221 multiple spaces before operator -pymodbus/constants.py:210:12: E221 multiple spaces before operator -pymodbus/device.py:30:13: E126 continuation line over-indented for hanging indent -pymodbus/device.py:88:41: E203 whitespace before ':' -pymodbus/device.py:89:41: E203 whitespace before ':' -pymodbus/device.py:90:41: E203 whitespace before ':' -pymodbus/device.py:91:41: E203 whitespace before ':' -pymodbus/device.py:92:41: E203 whitespace before ':' -pymodbus/device.py:93:41: E203 whitespace before ':' -pymodbus/device.py:94:41: E203 whitespace before ':' -pymodbus/device.py:96:41: E203 whitespace before ':' -pymodbus/device.py:97:41: E203 whitespace before ':' -pymodbus/device.py:98:41: E203 whitespace before ':' -pymodbus/device.py:99:41: E203 whitespace before ':' -pymodbus/device.py:100:41: E203 whitespace before ':' -pymodbus/device.py:101:41: E203 whitespace before ':' -pymodbus/device.py:102:41: E203 whitespace before ':' -pymodbus/device.py:103:41: E203 whitespace before ':' -pymodbus/device.py:105:41: E203 whitespace before ':' -pymodbus/device.py:106:41: E203 whitespace before ':' -pymodbus/device.py:107:41: E203 whitespace before ':' -pymodbus/device.py:108:41: E203 whitespace before ':' -pymodbus/device.py:109:41: E203 whitespace before ':' -pymodbus/device.py:110:41: E203 whitespace before ':' -pymodbus/device.py:111:41: E203 whitespace before ':' -pymodbus/device.py:112:41: E203 whitespace before ':' -pymodbus/device.py:113:41: E203 whitespace before ':' -pymodbus/device.py:114:41: E203 whitespace before ':' -pymodbus/device.py:115:41: E203 whitespace before ':' -pymodbus/device.py:116:41: E203 whitespace before ':' -pymodbus/device.py:117:41: E203 whitespace before ':' -pymodbus/device.py:118:41: E203 whitespace before ':' -pymodbus/device.py:120:41: E203 whitespace before ':' -pymodbus/device.py:121:41: E203 whitespace before ':' -pymodbus/device.py:122:41: E203 whitespace before ':' -pymodbus/device.py:123:41: E203 whitespace before ':' -pymodbus/device.py:124:41: E203 whitespace before ':' -pymodbus/device.py:125:41: E203 whitespace before ':' -pymodbus/device.py:126:41: E203 whitespace before ':' -pymodbus/device.py:127:41: E203 whitespace before ':' -pymodbus/device.py:128:41: E203 whitespace before ':' -pymodbus/device.py:129:41: E203 whitespace before ':' -pymodbus/device.py:131:41: E203 whitespace before ':' -pymodbus/device.py:132:41: E203 whitespace before ':' -pymodbus/device.py:133:41: E203 whitespace before ':' -pymodbus/device.py:134:41: E203 whitespace before ':' -pymodbus/device.py:135:41: E203 whitespace before ':' -pymodbus/device.py:136:41: E203 whitespace before ':' -pymodbus/device.py:137:41: E203 whitespace before ':' -pymodbus/device.py:138:41: E203 whitespace before ':' -pymodbus/device.py:88:55: E261 at least two spaces before inline comment -pymodbus/device.py:89:55: E261 at least two spaces before inline comment -pymodbus/device.py:90:55: E261 at least two spaces before inline comment -pymodbus/device.py:91:55: E261 at least two spaces before inline comment -pymodbus/device.py:92:55: E261 at least two spaces before inline comment -pymodbus/device.py:93:55: E261 at least two spaces before inline comment -pymodbus/device.py:94:55: E261 at least two spaces before inline comment -pymodbus/device.py:131:55: E261 at least two spaces before inline comment -pymodbus/device.py:132:55: E261 at least two spaces before inline comment -pymodbus/device.py:133:55: E261 at least two spaces before inline comment -pymodbus/device.py:134:55: E261 at least two spaces before inline comment -pymodbus/device.py:135:55: E261 at least two spaces before inline comment -pymodbus/device.py:136:55: E261 at least two spaces before inline comment -pymodbus/device.py:137:55: E261 at least two spaces before inline comment -pymodbus/device.py:138:55: E261 at least two spaces before inline comment -pymodbus/device.py:175:53: E225 missing whitespace around operator -pymodbus/device.py:273:15: E221 multiple spaces before operator -pymodbus/device.py:274:16: E221 multiple spaces before operator -pymodbus/device.py:275:23: E221 multiple spaces before operator -pymodbus/device.py:276:14: E221 multiple spaces before operator -pymodbus/device.py:277:16: E221 multiple spaces before operator -pymodbus/device.py:278:14: E221 multiple spaces before operator -pymodbus/device.py:289:80: E501 line too long (81 characters) -pymodbus/device.py:290:80: E501 line too long (81 characters) -pymodbus/device.py:289:45: E231 missing whitespace after ',' -pymodbus/device.py:289:47: E231 missing whitespace after ',' -pymodbus/device.py:290:45: E231 missing whitespace after ',' -pymodbus/device.py:290:47: E231 missing whitespace after ',' -pymodbus/device.py:291:45: E231 missing whitespace after ',' -pymodbus/device.py:291:47: E231 missing whitespace after ',' -pymodbus/device.py:292:45: E231 missing whitespace after ',' -pymodbus/device.py:292:47: E231 missing whitespace after ',' -pymodbus/device.py:289:33: E272 multiple spaces before keyword -pymodbus/device.py:290:35: E272 multiple spaces before keyword -pymodbus/device.py:315:17: E201 whitespace after '{' -pymodbus/device.py:315:47: E202 whitespace before '}' -pymodbus/device.py:315:27: E231 missing whitespace after ':' -pymodbus/device.py:401:12: E221 multiple spaces before operator -pymodbus/device.py:442:25: E701 multiple statements on one line (colon) -pymodbus/device.py:449:15: E221 multiple spaces before operator -pymodbus/device.py:451:22: E221 multiple spaces before operator -pymodbus/device.py:452:17: E221 multiple spaces before operator -pymodbus/device.py:453:20: E221 multiple spaces before operator -pymodbus/device.py:454:13: E221 multiple spaces before operator -pymodbus/device.py:455:14: E221 multiple spaces before operator -pymodbus/device.py:456:24: E221 multiple spaces before operator -pymodbus/device.py:457:10: E221 multiple spaces before operator -pymodbus/device.py:478:11: E221 multiple spaces before operator -pymodbus/device.py:479:13: E221 multiple spaces before operator -pymodbus/device.py:527:12: E221 multiple spaces before operator -pymodbus/device.py:528:11: E221 multiple spaces before operator -pymodbus/device.py:529:9: E221 multiple spaces before operator -pymodbus/device.py:612:9: E126 continuation line over-indented for hanging indent -pymodbus/diag_message.py:135:80: E501 line too long (81 characters) -pymodbus/diag_message.py:174:13: E701 multiple statements on one line (colon) -pymodbus/diag_message.py:200:13: E701 multiple statements on one line (colon) -pymodbus/diag_message.py:224:25: E221 multiple spaces before operator -pymodbus/diag_message.py:225:13: E701 multiple statements on one line (colon) -pymodbus/diag_message.py:254:25: E221 multiple spaces before operator -pymodbus/diag_message.py:255:13: E701 multiple statements on one line (colon) -pymodbus/diag_message.py:349:19: E221 multiple spaces before operator -pymodbus/diag_message.py:593:80: E501 line too long (80 characters) -pymodbus/diag_message.py:596:80: E501 line too long (80 characters) -pymodbus/diag_message.py:612:80: E501 line too long (82 characters) -pymodbus/diag_message.py:615:80: E501 line too long (80 characters) -pymodbus/diag_message.py:702:23: E261 at least two spaces before inline comment -pymodbus/diag_message.py:705:13: E701 multiple statements on one line (colon) -pymodbus/diag_message.py:725:80: E501 line too long (80 characters) -pymodbus/diag_message.py:731:80: E501 line too long (90 characters) -pymodbus/diag_message.py:732:80: E501 line too long (82 characters) -pymodbus/diag_message.py:737:80: E501 line too long (96 characters) -pymodbus/events.py:54:21: E221 multiple spaces before operator -pymodbus/events.py:55:20: E221 multiple spaces before operator -pymodbus/events.py:63:13: E221 multiple spaces before operator -pymodbus/events.py:74:21: E221 multiple spaces before operator -pymodbus/events.py:75:20: E221 multiple spaces before operator -pymodbus/events.py:105:18: E221 multiple spaces before operator -pymodbus/events.py:106:25: E221 multiple spaces before operator -pymodbus/events.py:107:24: E221 multiple spaces before operator -pymodbus/events.py:108:23: E221 multiple spaces before operator -pymodbus/events.py:110:20: E221 multiple spaces before operator -pymodbus/events.py:118:13: E128 continuation line under-indented for visual indent -pymodbus/events.py:119:13: E221 multiple spaces before operator -pymodbus/events.py:130:18: E221 multiple spaces before operator -pymodbus/events.py:131:25: E221 multiple spaces before operator -pymodbus/events.py:132:24: E221 multiple spaces before operator -pymodbus/events.py:133:23: E221 multiple spaces before operator -pymodbus/events.py:135:20: E221 multiple spaces before operator -pymodbus/factory.py:44:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:45:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:46:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:47:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:48:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:49:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:50:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:51:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:52:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:54:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:56:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:57:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:58:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:59:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:61:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:62:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:63:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:64:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:66:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:69:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:70:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:71:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:72:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:73:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:74:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:75:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:76:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:77:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:78:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:79:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:80:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:81:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:82:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:83:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:84:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:85:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:87:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:94:80: E501 line too long (83 characters) -pymodbus/factory.py:138:23: E701 multiple statements on one line (colon) -pymodbus/factory.py:152:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:153:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:154:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:155:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:156:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:157:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:158:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:159:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:160:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:162:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:164:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:165:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:166:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:167:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:169:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:170:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:171:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:172:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:174:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:177:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:178:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:179:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:180:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:181:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:182:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:183:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:184:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:185:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:186:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:187:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:188:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:189:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:190:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:191:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:192:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:193:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:195:13: E126 continuation line over-indented for hanging indent -pymodbus/factory.py:202:80: E501 line too long (83 characters) -pymodbus/factory.py:249:23: E701 multiple statements on one line (colon) -pymodbus/file_message.py:30:28: E221 multiple spaces before operator -pymodbus/file_message.py:31:25: E221 multiple spaces before operator -pymodbus/file_message.py:32:27: E221 multiple spaces before operator -pymodbus/file_message.py:33:25: E221 multiple spaces before operator -pymodbus/file_message.py:34:80: E501 line too long (87 characters) -pymodbus/file_message.py:34:27: E221 multiple spaces before operator -pymodbus/file_message.py:35:80: E501 line too long (87 characters) -pymodbus/file_message.py:41:12: E127 continuation line over-indented for visual indent -pymodbus/file_message.py:42:12: E127 continuation line over-indented for visual indent -pymodbus/file_message.py:43:12: E127 continuation line over-indented for visual indent -pymodbus/file_message.py:44:12: E127 continuation line over-indented for visual indent -pymodbus/file_message.py:41:32: E221 multiple spaces before operator -pymodbus/file_message.py:42:34: E221 multiple spaces before operator -pymodbus/file_message.py:43:34: E221 multiple spaces before operator -pymodbus/file_message.py:44:32: E221 multiple spaces before operator -pymodbus/file_message.py:92:21: E221 multiple spaces before operator -pymodbus/file_message.py:102:17: E128 continuation line under-indented for visual indent -pymodbus/file_message.py:113:62: E225 missing whitespace around operator -pymodbus/file_message.py:115:17: E128 continuation line under-indented for visual indent -pymodbus/file_message.py:114:19: E221 multiple spaces before operator -pymodbus/file_message.py:116:34: E701 multiple statements on one line (colon) -pymodbus/file_message.py:154:14: E221 multiple spaces before operator -pymodbus/file_message.py:169:80: E501 line too long (87 characters) -pymodbus/file_message.py:169:84: E225 missing whitespace around operator -pymodbus/file_message.py:170:41: E261 at least two spaces before inline comment -pymodbus/file_message.py:172:17: E128 continuation line under-indented for visual indent -pymodbus/file_message.py:173:38: E701 multiple statements on one line (colon) -pymodbus/file_message.py:192:21: E221 multiple spaces before operator -pymodbus/file_message.py:199:80: E501 line too long (85 characters) -pymodbus/file_message.py:203:17: E128 continuation line under-indented for visual indent -pymodbus/file_message.py:215:62: E225 missing whitespace around operator -pymodbus/file_message.py:217:18: E221 multiple spaces before operator -pymodbus/file_message.py:219:17: E128 continuation line under-indented for visual indent -pymodbus/file_message.py:220:17: E128 continuation line under-indented for visual indent -pymodbus/file_message.py:218:19: E221 multiple spaces before operator -pymodbus/file_message.py:221:34: E701 multiple statements on one line (colon) -pymodbus/file_message.py:248:21: E221 multiple spaces before operator -pymodbus/file_message.py:255:80: E501 line too long (85 characters) -pymodbus/file_message.py:259:17: E128 continuation line under-indented for visual indent -pymodbus/file_message.py:271:62: E225 missing whitespace around operator -pymodbus/file_message.py:273:18: E221 multiple spaces before operator -pymodbus/file_message.py:275:17: E128 continuation line under-indented for visual indent -pymodbus/file_message.py:276:17: E128 continuation line under-indented for visual indent -pymodbus/file_message.py:274:19: E221 multiple spaces before operator -pymodbus/file_message.py:277:34: E701 multiple statements on one line (colon) -pymodbus/file_message.py:298:21: E221 multiple spaces before operator -pymodbus/file_message.py:300:21: E221 multiple spaces before operator -pymodbus/file_message.py:331:80: E501 line too long (83 characters) -pymodbus/file_message.py:350:21: E221 multiple spaces before operator -pymodbus/file_message.py:352:21: E221 multiple spaces before operator -pymodbus/mei_message.py:43:13: E128 continuation line under-indented for visual indent -pymodbus/mei_message.py:66:13: E128 continuation line under-indented for visual indent -pymodbus/mei_message.py:91:17: E261 at least two spaces before inline comment -pymodbus/mei_message.py:94:69: E225 missing whitespace around operator -pymodbus/mei_message.py:108:31: E261 at least two spaces before inline comment -pymodbus/mei_message.py:111:35: E261 at least two spaces before inline comment -pymodbus/mei_message.py:120:13: E128 continuation line under-indented for visual indent -pymodbus/mei_message.py:121:13: E128 continuation line under-indented for visual indent -pymodbus/mei_message.py:138:40: E261 at least two spaces before inline comment -pymodbus/mei_message.py:141:80: E501 line too long (80 characters) -pymodbus/mei_message.py:141:77: E225 missing whitespace around operator -pymodbus/mei_message.py:143:53: E225 missing whitespace around operator -pymodbus/other_message.py:187:23: E701 multiple statements on one line (colon) -pymodbus/other_message.py:188:13: E701 multiple statements on one line (colon) -pymodbus/other_message.py:257:28: E203 whitespace before ':' -pymodbus/other_message.py:258:28: E203 whitespace before ':' -pymodbus/other_message.py:259:28: E203 whitespace before ':' -pymodbus/other_message.py:260:28: E203 whitespace before ':' -pymodbus/other_message.py:301:23: E701 multiple statements on one line (colon) -pymodbus/other_message.py:302:13: E701 multiple statements on one line (colon) -pymodbus/other_message.py:303:15: E221 multiple spaces before operator -pymodbus/other_message.py:329:80: E501 line too long (91 characters) -pymodbus/other_message.py:400:23: E701 multiple statements on one line (colon) -pymodbus/other_message.py:401:13: E701 multiple statements on one line (colon) -pymodbus/payload.py:36:21: E221 multiple spaces before operator -pymodbus/payload.py:61:27: E225 missing whitespace around operator -pymodbus/payload.py:186:21: E221 multiple spaces before operator -pymodbus/pdu.py:79:13: E701 multiple statements on one line (colon) -pymodbus/pdu.py:97:17: E128 continuation line under-indented for visual indent -pymodbus/pdu.py:129:20: E221 multiple spaces before operator -pymodbus/pdu.py:130:19: E221 multiple spaces before operator -pymodbus/pdu.py:131:17: E221 multiple spaces before operator -pymodbus/pdu.py:132:17: E221 multiple spaces before operator -pymodbus/pdu.py:133:16: E221 multiple spaces before operator -pymodbus/pdu.py:134:14: E221 multiple spaces before operator -pymodbus/pdu.py:135:22: E221 multiple spaces before operator -pymodbus/pdu.py:136:27: E221 multiple spaces before operator -pymodbus/pdu.py:137:22: E221 multiple spaces before operator -pymodbus/register_read_message.py:128:80: E501 line too long (80 characters) -pymodbus/register_read_message.py:178:80: E501 line too long (80 characters) -pymodbus/register_read_message.py:226:26: E221 multiple spaces before operator -pymodbus/register_read_message.py:227:24: E221 multiple spaces before operator -pymodbus/register_read_message.py:228:27: E221 multiple spaces before operator -pymodbus/register_read_message.py:241:17: E128 continuation line under-indented for visual indent -pymodbus/register_read_message.py:242:17: E128 continuation line under-indented for visual indent -pymodbus/register_read_message.py:241:54: E502 the backslash is redundant between brackets -pymodbus/register_read_message.py:253:9: E122 continuation line missing indentation or outdented -pymodbus/register_read_message.py:254:9: E122 continuation line missing indentation or outdented -pymodbus/register_read_message.py:255:29: E221 multiple spaces before operator -pymodbus/register_write_message.py:133:22: E701 multiple statements on one line (colon) -pymodbus/register_write_message.py:134:45: E701 multiple statements on one line (colon) -pymodbus/register_write_message.py:155:9: E122 continuation line missing indentation or outdented -pymodbus/transaction.py:9:24: E272 multiple spaces before keyword -pymodbus/transaction.py:11:24: E272 multiple spaces before keyword -pymodbus/transaction.py:12:24: E272 multiple spaces before keyword -pymodbus/transaction.py:66:80: E501 line too long (85 characters) -pymodbus/transaction.py:67:22: E702 multiple statements on one line (semicolon) -pymodbus/transaction.py:146:31: E231 missing whitespace after ':' -pymodbus/transaction.py:146:40: E231 missing whitespace after ':' -pymodbus/transaction.py:146:49: E231 missing whitespace after ':' -pymodbus/transaction.py:146:58: E231 missing whitespace after ':' -pymodbus/transaction.py:147:21: E221 multiple spaces before operator -pymodbus/transaction.py:148:21: E221 multiple spaces before operator -pymodbus/transaction.py:159:13: E122 continuation line missing indentation or outdented -pymodbus/transaction.py:160:21: E126 continuation line over-indented for hanging indent -pymodbus/transaction.py:179:31: E231 missing whitespace after ':' -pymodbus/transaction.py:179:40: E231 missing whitespace after ':' -pymodbus/transaction.py:179:49: E231 missing whitespace after ':' -pymodbus/transaction.py:179:58: E231 missing whitespace after ':' -pymodbus/transaction.py:244:17: E701 multiple statements on one line (colon) -pymodbus/transaction.py:253:13: E128 continuation line under-indented for visual indent -pymodbus/transaction.py:254:13: E128 continuation line under-indented for visual indent -pymodbus/transaction.py:255:13: E128 continuation line under-indented for visual indent -pymodbus/transaction.py:305:21: E221 multiple spaces before operator -pymodbus/transaction.py:306:19: E221 multiple spaces before operator -pymodbus/transaction.py:308:21: E221 multiple spaces before operator -pymodbus/transaction.py:380:14: E221 multiple spaces before operator -pymodbus/transaction.py:381:12: E221 multiple spaces before operator -pymodbus/transaction.py:383:19: E701 multiple statements on one line (colon) -pymodbus/transaction.py:423:17: E701 multiple statements on one line (colon) -pymodbus/transaction.py:432:13: E128 continuation line under-indented for visual indent -pymodbus/transaction.py:433:13: E128 continuation line under-indented for visual indent -pymodbus/transaction.py:463:31: E231 missing whitespace after ':' -pymodbus/transaction.py:463:45: E231 missing whitespace after ':' -pymodbus/transaction.py:463:54: E231 missing whitespace after ':' -pymodbus/transaction.py:464:21: E221 multiple spaces before operator -pymodbus/transaction.py:465:21: E221 multiple spaces before operator -pymodbus/transaction.py:466:19: E221 multiple spaces before operator -pymodbus/transaction.py:467:21: E221 multiple spaces before operator -pymodbus/transaction.py:478:23: E701 multiple statements on one line (colon) -pymodbus/transaction.py:479:21: E203 whitespace before ':' -pymodbus/transaction.py:499:31: E231 missing whitespace after ':' -pymodbus/transaction.py:499:45: E231 missing whitespace after ':' -pymodbus/transaction.py:499:54: E231 missing whitespace after ':' -pymodbus/transaction.py:524:14: E221 multiple spaces before operator -pymodbus/transaction.py:525:12: E221 multiple spaces before operator -pymodbus/transaction.py:527:19: E701 multiple statements on one line (colon) -pymodbus/transaction.py:567:17: E701 multiple statements on one line (colon) -pymodbus/transaction.py:576:16: E221 multiple spaces before operator -pymodbus/transaction.py:577:15: E221 multiple spaces before operator -pymodbus/transaction.py:620:31: E231 missing whitespace after ':' -pymodbus/transaction.py:620:45: E231 missing whitespace after ':' -pymodbus/transaction.py:620:54: E231 missing whitespace after ':' -pymodbus/transaction.py:621:21: E221 multiple spaces before operator -pymodbus/transaction.py:622:21: E221 multiple spaces before operator -pymodbus/transaction.py:623:19: E221 multiple spaces before operator -pymodbus/transaction.py:624:21: E221 multiple spaces before operator -pymodbus/transaction.py:635:23: E701 multiple statements on one line (colon) -pymodbus/transaction.py:636:21: E203 whitespace before ':' -pymodbus/transaction.py:643:80: E501 line too long (85 characters) -pymodbus/transaction.py:655:31: E231 missing whitespace after ':' -pymodbus/transaction.py:655:45: E231 missing whitespace after ':' -pymodbus/transaction.py:655:54: E231 missing whitespace after ':' -pymodbus/transaction.py:680:14: E221 multiple spaces before operator -pymodbus/transaction.py:681:12: E221 multiple spaces before operator -pymodbus/transaction.py:683:19: E701 multiple statements on one line (colon) -pymodbus/transaction.py:723:17: E701 multiple statements on one line (colon) -pymodbus/transaction.py:733:13: E128 continuation line under-indented for visual indent -pymodbus/transaction.py:734:13: E128 continuation line under-indented for visual indent -pymodbus/transaction.py:749:31: E701 multiple statements on one line (colon) -pymodbus/transaction.py:750:17: E701 multiple statements on one line (colon) -pymodbus/utilities.py:64:15: E701 multiple statements on one line (colon) -pymodbus/utilities.py:69:13: E701 multiple statements on one line (colon) -pymodbus/utilities.py:110:17: E701 multiple statements on one line (colon) -pymodbus/utilities.py:131:51: E702 multiple statements on one line (semicolon) -pymodbus/client/async.py:115:17: E701 multiple statements on one line (colon) -pymodbus/client/async.py:130:32: E261 at least two spaces before inline comment -pymodbus/client/async.py:187:17: E701 multiple statements on one line (colon) -pymodbus/client/async.py:198:32: E261 at least two spaces before inline comment -pymodbus/client/sync.py:47:80: E501 line too long (80 characters) -pymodbus/client/sync.py:60:80: E501 line too long (80 characters) -pymodbus/client/sync.py:68:80: E501 line too long (80 characters) -pymodbus/client/sync.py:79:80: E501 line too long (81 characters) -pymodbus/client/sync.py:93:80: E501 line too long (81 characters) -pymodbus/client/sync.py:137:23: E701 multiple statements on one line (colon) -pymodbus/client/sync.py:139:80: E501 line too long (92 characters) -pymodbus/client/sync.py:143:17: E128 continuation line under-indented for visual indent -pymodbus/client/sync.py:142:65: E502 the backslash is redundant between brackets -pymodbus/client/sync.py:145:28: E711 comparison to None should be 'if cond is not None:' -pymodbus/client/sync.py:212:29: E261 at least two spaces before inline comment -pymodbus/client/sync.py:221:23: E701 multiple statements on one line (colon) -pymodbus/client/sync.py:228:28: E711 comparison to None should be 'if cond is not None:' -pymodbus/client/sync.py:289:20: E221 multiple spaces before operator -pymodbus/client/sync.py:290:20: E221 multiple spaces before operator -pymodbus/client/sync.py:293:18: E221 multiple spaces before operator -pymodbus/client/sync.py:296:20: E221 multiple spaces before operator -pymodbus/client/sync.py:298:21: E221 multiple spaces before operator -pymodbus/client/sync.py:308:31: E701 multiple statements on one line (colon) -pymodbus/client/sync.py:308:32: E272 multiple spaces before keyword -pymodbus/client/sync.py:309:29: E701 multiple statements on one line (colon) -pymodbus/client/sync.py:309:30: E272 multiple spaces before keyword -pymodbus/client/sync.py:310:32: E701 multiple statements on one line (colon) -pymodbus/client/sync.py:318:23: E701 multiple statements on one line (colon) -pymodbus/client/sync.py:321:17: E128 continuation line under-indented for visual indent -pymodbus/client/sync.py:322:17: E128 continuation line under-indented for visual indent -pymodbus/client/sync.py:326:28: E711 comparison to None should be 'if cond is not None:' -pymodbus/server/async.py:218:5: E128 continuation line under-indented for visual indent -pymodbus/server/async.py:218:5: E125 continuation line does not distinguish itself from next logical line -pymodbus/server/async.py:236:43: E261 at least two spaces before inline comment -pymodbus/server/sync.py:78:80: E501 line too long (81 characters) -pymodbus/server/sync.py:80:80: E501 line too long (81 characters) -pymodbus/server/sync.py:84:80: E501 line too long (80 characters) -pymodbus/server/sync.py:91:80: E501 line too long (80 characters) -pymodbus/server/sync.py:110:34: E701 multiple statements on one line (colon) -pymodbus/server/sync.py:113:19: E701 multiple statements on one line (colon) -pymodbus/server/sync.py:140:28: E701 multiple statements on one line (colon) -pymodbus/server/sync.py:144:34: E701 multiple statements on one line (colon) -pymodbus/server/sync.py:148:19: E701 multiple statements on one line (colon) -pymodbus/server/sync.py:177:28: E701 multiple statements on one line (colon) -pymodbus/server/sync.py:181:34: E701 multiple statements on one line (colon) -pymodbus/server/sync.py:185:19: E701 multiple statements on one line (colon) -pymodbus/server/sync.py:224:30: E272 multiple spaces before keyword -pymodbus/server/sync.py:224:20: E221 multiple spaces before operator -pymodbus/server/sync.py:232:13: E128 continuation line under-indented for visual indent -pymodbus/server/sync.py:248:35: E701 multiple statements on one line (colon) -pymodbus/server/sync.py:273:30: E272 multiple spaces before keyword -pymodbus/server/sync.py:273:20: E221 multiple spaces before operator -pymodbus/server/sync.py:281:13: E128 continuation line under-indented for visual indent -pymodbus/server/sync.py:289:33: E261 at least two spaces before inline comment -pymodbus/server/sync.py:298:35: E701 multiple statements on one line (colon) -pymodbus/server/sync.py:329:30: E272 multiple spaces before keyword -pymodbus/server/sync.py:329:20: E221 multiple spaces before operator -pymodbus/server/sync.py:336:20: E221 multiple spaces before operator -pymodbus/server/sync.py:339:20: E221 multiple spaces before operator -pymodbus/server/sync.py:341:21: E221 multiple spaces before operator -pymodbus/server/sync.py:342:20: E221 multiple spaces before operator -pymodbus/server/sync.py:350:23: E701 multiple statements on one line (colon) -pymodbus/server/sync.py:353:17: E128 continuation line under-indented for visual indent -pymodbus/server/sync.py:354:17: E128 continuation line under-indented for visual indent -pymodbus/server/sync.py:358:28: E711 comparison to None should be 'if cond is not None:' -pymodbus/server/sync.py:370:13: E128 continuation line under-indented for visual indent -pymodbus/server/sync.py:381:19: E701 multiple statements on one line (colon) -pymodbus/internal/ptwisted.py:53:15: E701 multiple statements on one line (colon) -pymodbus/datastore/context.py:9:15: E702 multiple statements on one line (semicolon) -pymodbus/datastore/context.py:101:20: E221 multiple spaces before operator -pymodbus/datastore/context.py:128:23: E701 multiple statements on one line (colon) -pymodbus/datastore/context.py:131:13: E701 multiple statements on one line (colon) -pymodbus/datastore/context.py:139:23: E701 multiple statements on one line (colon) -pymodbus/datastore/context.py:142:80: E501 line too long (82 characters) -pymodbus/datastore/context.py:142:13: E701 multiple statements on one line (colon) -pymodbus/datastore/database.py:13:15: E702 multiple statements on one line (semicolon) -pymodbus/datastore/database.py:83:80: E501 line too long (80 characters) -pymodbus/datastore/database.py:85:80: E501 line too long (80 characters) -pymodbus/datastore/database.py:95:13: E128 continuation line under-indented for visual indent -pymodbus/datastore/database.py:110:14: E221 multiple spaces before operator -pymodbus/datastore/database.py:128:28: E203 whitespace before ':' -pymodbus/datastore/database.py:129:28: E203 whitespace before ':' -pymodbus/datastore/database.py:130:28: E203 whitespace before ':' -pymodbus/datastore/database.py:142:14: E221 multiple spaces before operator -pymodbus/datastore/database.py:143:15: E221 multiple spaces before operator -pymodbus/datastore/database.py:154:14: E221 multiple spaces before operator -pymodbus/datastore/database.py:155:14: E221 multiple spaces before operator -pymodbus/datastore/database.py:156:31: E221 multiple spaces before operator -pymodbus/datastore/database.py:158:15: E221 multiple spaces before operator -pymodbus/datastore/database.py:168:14: E221 multiple spaces before operator -pymodbus/datastore/modredis.py:8:15: E702 multiple statements on one line (semicolon) -pymodbus/datastore/modredis.py:80:80: E501 line too long (80 characters) -pymodbus/datastore/modredis.py:82:80: E501 line too long (80 characters) -pymodbus/datastore/modredis.py:97:16: E203 whitespace before ':' -pymodbus/datastore/modredis.py:98:16: E203 whitespace before ':' -pymodbus/datastore/modredis.py:99:16: E203 whitespace before ':' -pymodbus/datastore/modredis.py:100:16: E203 whitespace before ':' -pymodbus/datastore/modredis.py:103:16: E203 whitespace before ':' -pymodbus/datastore/modredis.py:104:16: E203 whitespace before ':' -pymodbus/datastore/modredis.py:105:16: E203 whitespace before ':' -pymodbus/datastore/modredis.py:106:16: E203 whitespace before ':' -pymodbus/datastore/modredis.py:109:16: E203 whitespace before ':' -pymodbus/datastore/modredis.py:110:16: E203 whitespace before ':' -pymodbus/datastore/modredis.py:111:16: E203 whitespace before ':' -pymodbus/datastore/modredis.py:112:16: E203 whitespace before ':' -pymodbus/datastore/modredis.py:115:80: E501 line too long (80 characters) -pymodbus/datastore/modredis.py:117:80: E501 line too long (80 characters) -pymodbus/datastore/modredis.py:118:15: E221 multiple spaces before operator -pymodbus/datastore/modredis.py:132:16: E221 multiple spaces before operator -pymodbus/datastore/modredis.py:176:80: E501 line too long (92 characters) -pymodbus/datastore/modredis.py:176:14: E221 multiple spaces before operator -pymodbus/datastore/modredis.py:183:80: E501 line too long (80 characters) -pymodbus/datastore/modredis.py:185:80: E501 line too long (80 characters) -pymodbus/datastore/modredis.py:186:15: E221 multiple spaces before operator -pymodbus/datastore/modredis.py:201:16: E221 multiple spaces before operator -pymodbus/datastore/remote.py:98:32: E701 multiple statements on one line (colon) -pymodbus/datastore/remote.py:99:32: E701 multiple statements on one line (colon) -pymodbus/datastore/remote.py:100:13: E701 multiple statements on one line (colon) -pymodbus/datastore/store.py:144:13: E701 multiple statements on one line (colon) -pymodbus/datastore/store.py:163:15: E221 multiple spaces before operator -pymodbus/datastore/store.py:204:13: E701 multiple statements on one line (colon) -pymodbus/datastore/store.py:216:44: E225 missing whitespace around operator -pymodbus/datastore/store.py:225:22: E701 multiple statements on one line (colon) -4 E122 continuation line missing indentation or outdented -1 E125 continuation line does not distinguish itself from next logical line -77 E126 continuation line over-indented for hanging indent -4 E127 continuation line over-indented for visual indent -34 E128 continuation line under-indented for visual indent -1 E201 whitespace after '{' -1 E202 whitespace before '}' -68 E203 whitespace before ':' -154 E221 multiple spaces before operator -10 E225 missing whitespace around operator -29 E231 missing whitespace after ',' -26 E261 at least two spaces before inline comment -10 E272 multiple spaces before keyword -47 E501 line too long (80 characters) -2 E502 the backslash is redundant between brackets -72 E701 multiple statements on one line (colon) -5 E702 multiple statements on one line (semicolon) -4 E711 comparison to None should be 'if cond is not None:' diff --git a/doc/readme.rst b/doc/readme.rst new file mode 100644 index 000000000..6b2b3ec68 --- /dev/null +++ b/doc/readme.rst @@ -0,0 +1 @@ +.. include:: ../README.rst \ No newline at end of file diff --git a/doc/source/example/asynchronous_client.rst b/doc/source/example/asynchronous_client.rst new file mode 100644 index 000000000..c9a0b03e1 --- /dev/null +++ b/doc/source/example/asynchronous_client.rst @@ -0,0 +1,4 @@ +================================================== +Asynchronous Client Example +================================================== +.. literalinclude:: ../../../examples/common/asynchronous_client.py \ No newline at end of file diff --git a/doc/source/example/asynchronous_processor.rst b/doc/source/example/asynchronous_processor.rst new file mode 100644 index 000000000..b5b5ffd76 --- /dev/null +++ b/doc/source/example/asynchronous_processor.rst @@ -0,0 +1,4 @@ +================================================== +Asynchronous Processor Example +================================================== +.. literalinclude:: ../../../examples/common/asynchronous_processor.py \ No newline at end of file diff --git a/doc/sphinx/examples/asynchronous-server.rst b/doc/source/example/asynchronous_server.rst similarity index 65% rename from doc/sphinx/examples/asynchronous-server.rst rename to doc/source/example/asynchronous_server.rst index 14aeef298..7b66a52bf 100644 --- a/doc/sphinx/examples/asynchronous-server.rst +++ b/doc/source/example/asynchronous_server.rst @@ -1,6 +1,4 @@ ================================================== Asynchronous Server Example ================================================== - -.. literalinclude:: ../../../examples/common/asynchronous-server.py - +.. literalinclude:: ../../../examples/common/asynchronous_server.py \ No newline at end of file diff --git a/doc/sphinx/html/_sources/examples/custom-message.rst.txt b/doc/source/example/bcd_payload.rst similarity index 53% rename from doc/sphinx/html/_sources/examples/custom-message.rst.txt rename to doc/source/example/bcd_payload.rst index 2ced10cbc..a1c9a2c23 100644 --- a/doc/sphinx/html/_sources/examples/custom-message.rst.txt +++ b/doc/source/example/bcd_payload.rst @@ -1,6 +1,4 @@ ================================================== -Custom Message Example +Bcd Payload Example ================================================== - -.. literalinclude:: ../../../examples/common/custom-message.py - +.. literalinclude:: ../../../examples/contrib/bcd_payload.py \ No newline at end of file diff --git a/doc/sphinx/examples/callback-server.rst b/doc/source/example/callback_server.rst similarity index 65% rename from doc/sphinx/examples/callback-server.rst rename to doc/source/example/callback_server.rst index e57475216..2dff5d612 100644 --- a/doc/sphinx/examples/callback-server.rst +++ b/doc/source/example/callback_server.rst @@ -1,6 +1,4 @@ ================================================== Callback Server Example ================================================== - -.. literalinclude:: ../../../examples/common/callback-server.py - +.. literalinclude:: ../../../examples/common/callback_server.py \ No newline at end of file diff --git a/doc/sphinx/examples/modbus-scraper.rst b/doc/source/example/changing_framers.rst similarity index 53% rename from doc/sphinx/examples/modbus-scraper.rst rename to doc/source/example/changing_framers.rst index 9931c4a62..1b2b372a1 100644 --- a/doc/sphinx/examples/modbus-scraper.rst +++ b/doc/source/example/changing_framers.rst @@ -1,6 +1,4 @@ ================================================== -Modbus Scraper Example +Changing Framers Example ================================================== - -.. literalinclude:: ../../../examples/contrib/modbus-scraper.py - +.. literalinclude:: ../../../examples/common/changing_framers.py \ No newline at end of file diff --git a/doc/sphinx/examples/bcd-payload.rst b/doc/source/example/concurrent_client.rst similarity index 52% rename from doc/sphinx/examples/bcd-payload.rst rename to doc/source/example/concurrent_client.rst index a95c5e7a6..235c91c47 100644 --- a/doc/sphinx/examples/bcd-payload.rst +++ b/doc/source/example/concurrent_client.rst @@ -1,6 +1,4 @@ ================================================== -Binary Coded Decimal Example +Concurrent Client Example ================================================== - -.. literalinclude:: ../../../examples/contrib/bcd-payload.py - +.. literalinclude:: ../../../examples/contrib/concurrent_client.py \ No newline at end of file diff --git a/doc/sphinx/examples/custom-datablock.rst b/doc/source/example/custom_datablock.rst similarity index 65% rename from doc/sphinx/examples/custom-datablock.rst rename to doc/source/example/custom_datablock.rst index 7139c0f08..21b9dc27a 100644 --- a/doc/sphinx/examples/custom-datablock.rst +++ b/doc/source/example/custom_datablock.rst @@ -1,6 +1,4 @@ ================================================== Custom Datablock Example ================================================== - -.. literalinclude:: ../../../examples/common/custom-datablock.py - +.. literalinclude:: ../../../examples/common/custom_datablock.py \ No newline at end of file diff --git a/doc/sphinx/examples/custom-message.rst b/doc/source/example/custom_message.rst similarity index 65% rename from doc/sphinx/examples/custom-message.rst rename to doc/source/example/custom_message.rst index 2ced10cbc..069d33101 100644 --- a/doc/sphinx/examples/custom-message.rst +++ b/doc/source/example/custom_message.rst @@ -1,6 +1,4 @@ ================================================== Custom Message Example ================================================== - -.. literalinclude:: ../../../examples/common/custom-message.py - +.. literalinclude:: ../../../examples/common/custom_message.py \ No newline at end of file diff --git a/doc/source/example/dbstore_update_server.rst b/doc/source/example/dbstore_update_server.rst new file mode 100644 index 000000000..1e27abd56 --- /dev/null +++ b/doc/source/example/dbstore_update_server.rst @@ -0,0 +1,4 @@ +================================================== +Dbstore Update Server Example +================================================== +.. literalinclude:: ../../../examples/common/dbstore_update_server.py \ No newline at end of file diff --git a/doc/sphinx/html/_sources/examples/modbus-logging.rst.txt b/doc/source/example/gui_common.rst similarity index 53% rename from doc/sphinx/html/_sources/examples/modbus-logging.rst.txt rename to doc/source/example/gui_common.rst index 710e5bd4d..ec177a635 100644 --- a/doc/sphinx/html/_sources/examples/modbus-logging.rst.txt +++ b/doc/source/example/gui_common.rst @@ -1,6 +1,4 @@ ================================================== -Modbus Logging Example +Gui Common Example ================================================== - -.. literalinclude:: ../../../examples/common/modbus-logging.py - +.. literalinclude:: ../../../examples/gui/gui_common.py \ No newline at end of file diff --git a/doc/source/example/libmodbus_client.rst b/doc/source/example/libmodbus_client.rst new file mode 100644 index 000000000..b68ed1045 --- /dev/null +++ b/doc/source/example/libmodbus_client.rst @@ -0,0 +1,4 @@ +================================================== +Libmodbus Client Example +================================================== +.. literalinclude:: ../../../examples/contrib/libmodbus_client.py \ No newline at end of file diff --git a/doc/sphinx/examples/changing-framers.rst b/doc/source/example/message_generator.rst similarity index 52% rename from doc/sphinx/examples/changing-framers.rst rename to doc/source/example/message_generator.rst index 3679aa43f..0a06b5953 100644 --- a/doc/sphinx/examples/changing-framers.rst +++ b/doc/source/example/message_generator.rst @@ -1,6 +1,4 @@ ================================================== -Changing Default Framers +Message Generator Example ================================================== - -.. literalinclude:: ../../../examples/common/changing-framers.py - +.. literalinclude:: ../../../examples/contrib/message_generator.py \ No newline at end of file diff --git a/doc/source/example/message_parser.rst b/doc/source/example/message_parser.rst new file mode 100644 index 000000000..f5aa06c9b --- /dev/null +++ b/doc/source/example/message_parser.rst @@ -0,0 +1,4 @@ +================================================== +Message Parser Example +================================================== +.. literalinclude:: ../../../examples/contrib/message_parser.py \ No newline at end of file diff --git a/doc/sphinx/examples/modbus-logging.rst b/doc/source/example/modbus_logging.rst similarity index 65% rename from doc/sphinx/examples/modbus-logging.rst rename to doc/source/example/modbus_logging.rst index 710e5bd4d..2c548c985 100644 --- a/doc/sphinx/examples/modbus-logging.rst +++ b/doc/source/example/modbus_logging.rst @@ -1,6 +1,4 @@ ================================================== Modbus Logging Example ================================================== - -.. literalinclude:: ../../../examples/common/modbus-logging.py - +.. literalinclude:: ../../../examples/common/modbus_logging.py \ No newline at end of file diff --git a/doc/source/example/modbus_mapper.rst b/doc/source/example/modbus_mapper.rst new file mode 100644 index 000000000..18b92c504 --- /dev/null +++ b/doc/source/example/modbus_mapper.rst @@ -0,0 +1,4 @@ +================================================== +Modbus Mapper Example +================================================== +.. literalinclude:: ../../../examples/contrib/modbus_mapper.py \ No newline at end of file diff --git a/doc/source/example/modbus_payload.rst b/doc/source/example/modbus_payload.rst new file mode 100644 index 000000000..4b0861ecb --- /dev/null +++ b/doc/source/example/modbus_payload.rst @@ -0,0 +1,4 @@ +================================================== +Modbus Payload Example +================================================== +.. literalinclude:: ../../../examples/common/modbus_payload.py \ No newline at end of file diff --git a/doc/source/example/modbus_payload_server.rst b/doc/source/example/modbus_payload_server.rst new file mode 100644 index 000000000..e9ba210cb --- /dev/null +++ b/doc/source/example/modbus_payload_server.rst @@ -0,0 +1,4 @@ +================================================== +Modbus Payload Server Example +================================================== +.. literalinclude:: ../../../examples/common/modbus_payload_server.py \ No newline at end of file diff --git a/doc/source/example/modbus_saver.rst b/doc/source/example/modbus_saver.rst new file mode 100644 index 000000000..bdba22817 --- /dev/null +++ b/doc/source/example/modbus_saver.rst @@ -0,0 +1,4 @@ +================================================== +Modbus Saver Example +================================================== +.. literalinclude:: ../../../examples/contrib/modbus_saver.py \ No newline at end of file diff --git a/doc/sphinx/html/_sources/examples/modbus-scraper.rst.txt b/doc/source/example/modbus_scraper.rst similarity index 65% rename from doc/sphinx/html/_sources/examples/modbus-scraper.rst.txt rename to doc/source/example/modbus_scraper.rst index 9931c4a62..5bf9ccea9 100644 --- a/doc/sphinx/html/_sources/examples/modbus-scraper.rst.txt +++ b/doc/source/example/modbus_scraper.rst @@ -1,6 +1,4 @@ ================================================== Modbus Scraper Example ================================================== - -.. literalinclude:: ../../../examples/contrib/modbus-scraper.py - +.. literalinclude:: ../../../examples/contrib/modbus_scraper.py \ No newline at end of file diff --git a/doc/sphinx/examples/modbus-simulator.rst b/doc/source/example/modbus_simulator.rst similarity index 65% rename from doc/sphinx/examples/modbus-simulator.rst rename to doc/source/example/modbus_simulator.rst index 5adcee5ee..d6883f030 100644 --- a/doc/sphinx/examples/modbus-simulator.rst +++ b/doc/source/example/modbus_simulator.rst @@ -1,5 +1,4 @@ ================================================== Modbus Simulator Example ================================================== - -.. literalinclude:: ../../../examples/contrib/modbus-simulator.py +.. literalinclude:: ../../../examples/contrib/modbus_simulator.py \ No newline at end of file diff --git a/doc/source/example/modicon_payload.rst b/doc/source/example/modicon_payload.rst new file mode 100644 index 000000000..ac0cb4d2c --- /dev/null +++ b/doc/source/example/modicon_payload.rst @@ -0,0 +1,4 @@ +================================================== +Modicon Payload Example +================================================== +.. literalinclude:: ../../../examples/contrib/modicon_payload.py \ No newline at end of file diff --git a/doc/source/example/modules.rst b/doc/source/example/modules.rst new file mode 100644 index 000000000..6d6460349 --- /dev/null +++ b/doc/source/example/modules.rst @@ -0,0 +1,39 @@ +=================== +Examples +=================== +=== + +.. toctree:: + :maxdepth: 4 + + asynchronous_client + asynchronous_processor + asynchronous_server + callback_server + changing_framers + custom_datablock + custom_message + dbstore_update_server + modbus_logging + modbus_payload + modbus_payload_server + performance + synchronous_client + synchronous_client_ext + synchronous_server + updating_server + bcd_payload + concurrent_client + libmodbus_client + message_generator + message_parser + modbus_mapper + modbus_saver + modbus_scraper + modbus_simulator + modicon_payload + remote_server_context + serial_forwarder + sunspec_client + thread_safe_datastore + gui_common diff --git a/doc/source/example/performance.rst b/doc/source/example/performance.rst new file mode 100644 index 000000000..86cef1169 --- /dev/null +++ b/doc/source/example/performance.rst @@ -0,0 +1,4 @@ +================== +performance module +================== +.. literalinclude:: ../../../examples/common/performance.py diff --git a/doc/sphinx/examples/remote-server-context.rst b/doc/source/example/remote_server_context.rst similarity index 81% rename from doc/sphinx/examples/remote-server-context.rst rename to doc/source/example/remote_server_context.rst index 2a2ac3c05..0450e6ef6 100644 --- a/doc/sphinx/examples/remote-server-context.rst +++ b/doc/source/example/remote_server_context.rst @@ -1,6 +1,4 @@ ================================================== -Remote Single Server Context +Remote Server Context Example ================================================== - -.. literalinclude:: ../../../examples/contrib/remote_server_context.py - +.. literalinclude:: ../../../examples/contrib/remote_server_context.py \ No newline at end of file diff --git a/doc/source/example/serial_forwarder.rst b/doc/source/example/serial_forwarder.rst new file mode 100644 index 000000000..1a8fba691 --- /dev/null +++ b/doc/source/example/serial_forwarder.rst @@ -0,0 +1,4 @@ +================================================== +Serial Forwarder Example +================================================== +.. literalinclude:: ../../../examples/contrib/serial_forwarder.py \ No newline at end of file diff --git a/doc/source/example/sunspec_client.rst b/doc/source/example/sunspec_client.rst new file mode 100644 index 000000000..48b284b97 --- /dev/null +++ b/doc/source/example/sunspec_client.rst @@ -0,0 +1,4 @@ +================================================== +Sunspec Client Example +================================================== +.. literalinclude:: ../../../examples/contrib/sunspec_client.py \ No newline at end of file diff --git a/doc/source/example/synchronous_client.rst b/doc/source/example/synchronous_client.rst new file mode 100644 index 000000000..6df8cc562 --- /dev/null +++ b/doc/source/example/synchronous_client.rst @@ -0,0 +1,4 @@ +================================================== +Synchronous Client Example +================================================== +.. literalinclude:: ../../../examples/common/synchronous_client.py \ No newline at end of file diff --git a/doc/source/example/synchronous_client_ext.rst b/doc/source/example/synchronous_client_ext.rst new file mode 100644 index 000000000..c26074cf5 --- /dev/null +++ b/doc/source/example/synchronous_client_ext.rst @@ -0,0 +1,4 @@ +================================================== +Synchronous Client Ext Example +================================================== +.. literalinclude:: ../../../examples/common/synchronous_client_ext.py \ No newline at end of file diff --git a/doc/sphinx/examples/synchronous-server.rst b/doc/source/example/synchronous_server.rst similarity index 65% rename from doc/sphinx/examples/synchronous-server.rst rename to doc/source/example/synchronous_server.rst index 1db715d7f..15f0db3d9 100644 --- a/doc/sphinx/examples/synchronous-server.rst +++ b/doc/source/example/synchronous_server.rst @@ -1,6 +1,4 @@ ================================================== Synchronous Server Example ================================================== - -.. literalinclude:: ../../../examples/common/synchronous-server.py - +.. literalinclude:: ../../../examples/common/synchronous_server.py \ No newline at end of file diff --git a/doc/sphinx/examples/thread-safe-datastore.rst b/doc/source/example/thread_safe_datastore.rst similarity index 95% rename from doc/sphinx/examples/thread-safe-datastore.rst rename to doc/source/example/thread_safe_datastore.rst index 7a965a3f4..f4414be0a 100644 --- a/doc/sphinx/examples/thread-safe-datastore.rst +++ b/doc/source/example/thread_safe_datastore.rst @@ -1,6 +1,4 @@ ================================================== Thread Safe Datastore Example ================================================== - -.. literalinclude:: ../../../examples/contrib/thread_safe_datastore.py - +.. literalinclude:: ../../../examples/contrib/thread_safe_datastore.py \ No newline at end of file diff --git a/doc/sphinx/html/_sources/examples/updating-server.rst.txt b/doc/source/example/updating_server.rst similarity index 65% rename from doc/sphinx/html/_sources/examples/updating-server.rst.txt rename to doc/source/example/updating_server.rst index 07d1baac0..d7fbcafcc 100644 --- a/doc/sphinx/html/_sources/examples/updating-server.rst.txt +++ b/doc/source/example/updating_server.rst @@ -1,6 +1,4 @@ ================================================== Updating Server Example ================================================== - -.. literalinclude:: ../../../examples/common/updating-server.py - +.. literalinclude:: ../../../examples/common/updating_server.py \ No newline at end of file diff --git a/doc/source/library/modules.rst b/doc/source/library/modules.rst new file mode 100644 index 000000000..f36970d42 --- /dev/null +++ b/doc/source/library/modules.rst @@ -0,0 +1,7 @@ +Pymodbus +======== + +.. toctree:: + :maxdepth: 4 + + pymodbus diff --git a/doc/source/library/pymodbus.client.rst b/doc/source/library/pymodbus.client.rst new file mode 100644 index 000000000..391658189 --- /dev/null +++ b/doc/source/library/pymodbus.client.rst @@ -0,0 +1,38 @@ +pymodbus\.client package +======================== + +Submodules +---------- + +pymodbus\.client\.async module +------------------------------ + +.. automodule:: pymodbus.client.async + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.client\.common module +------------------------------- + +.. automodule:: pymodbus.client.common + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.client\.sync module +----------------------------- + +.. automodule:: pymodbus.client.sync + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: pymodbus.client + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/library/pymodbus.datastore.database.rst b/doc/source/library/pymodbus.datastore.database.rst new file mode 100644 index 000000000..d0321e6d5 --- /dev/null +++ b/doc/source/library/pymodbus.datastore.database.rst @@ -0,0 +1,30 @@ +pymodbus\.datastore\.database package +===================================== + +Submodules +---------- + +pymodbus\.datastore\.database\.redis\_datastore module +------------------------------------------------------ + +.. automodule:: pymodbus.datastore.database.redis_datastore + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.datastore\.database\.sql\_datastore module +---------------------------------------------------- + +.. automodule:: pymodbus.datastore.database.sql_datastore + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: pymodbus.datastore.database + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/library/pymodbus.datastore.rst b/doc/source/library/pymodbus.datastore.rst new file mode 100644 index 000000000..2aa8a3b93 --- /dev/null +++ b/doc/source/library/pymodbus.datastore.rst @@ -0,0 +1,45 @@ +pymodbus\.datastore package +=========================== + +Subpackages +----------- + +.. toctree:: + + pymodbus.datastore.database + +Submodules +---------- + +pymodbus\.datastore\.context module +----------------------------------- + +.. automodule:: pymodbus.datastore.context + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.datastore\.remote module +---------------------------------- + +.. automodule:: pymodbus.datastore.remote + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.datastore\.store module +--------------------------------- + +.. automodule:: pymodbus.datastore.store + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: pymodbus.datastore + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/library/pymodbus.internal.rst b/doc/source/library/pymodbus.internal.rst new file mode 100644 index 000000000..35467c8a5 --- /dev/null +++ b/doc/source/library/pymodbus.internal.rst @@ -0,0 +1,22 @@ +pymodbus\.internal package +========================== + +Submodules +---------- + +pymodbus\.internal\.ptwisted module +----------------------------------- + +.. automodule:: pymodbus.internal.ptwisted + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: pymodbus.internal + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/library/pymodbus.rst b/doc/source/library/pymodbus.rst new file mode 100644 index 000000000..9517ad686 --- /dev/null +++ b/doc/source/library/pymodbus.rst @@ -0,0 +1,184 @@ +Pymodbus package +================ + +Subpackages +----------- + +.. toctree:: + + pymodbus.client + pymodbus.datastore + pymodbus.internal + pymodbus.server + +Submodules +---------- + +pymodbus\.bit\_read\_message module +----------------------------------- + +.. automodule:: pymodbus.bit_read_message + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.bit\_write\_message module +------------------------------------ + +.. automodule:: pymodbus.bit_write_message + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.compat module +----------------------- + +.. automodule:: pymodbus.compat + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.constants module +-------------------------- + +.. automodule:: pymodbus.constants + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.device module +----------------------- + +.. automodule:: pymodbus.device + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.diag\_message module +------------------------------ + +.. automodule:: pymodbus.diag_message + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.events module +----------------------- + +.. automodule:: pymodbus.events + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.exceptions module +--------------------------- + +.. automodule:: pymodbus.exceptions + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.factory module +------------------------ + +.. automodule:: pymodbus.factory + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.file\_message module +------------------------------ + +.. automodule:: pymodbus.file_message + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.interfaces module +--------------------------- + +.. automodule:: pymodbus.interfaces + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.mei\_message module +----------------------------- + +.. automodule:: pymodbus.mei_message + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.other\_message module +------------------------------- + +.. automodule:: pymodbus.other_message + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.payload module +------------------------ + +.. automodule:: pymodbus.payload + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.pdu module +-------------------- + +.. automodule:: pymodbus.pdu + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.register\_read\_message module +---------------------------------------- + +.. automodule:: pymodbus.register_read_message + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.register\_write\_message module +----------------------------------------- + +.. automodule:: pymodbus.register_write_message + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.transaction module +---------------------------- + +.. automodule:: pymodbus.transaction + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.utilities module +-------------------------- + +.. automodule:: pymodbus.utilities + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.version module +------------------------ + +.. automodule:: pymodbus.version + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: pymodbus + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/library/pymodbus.server.rst b/doc/source/library/pymodbus.server.rst new file mode 100644 index 000000000..973bb5b55 --- /dev/null +++ b/doc/source/library/pymodbus.server.rst @@ -0,0 +1,30 @@ +pymodbus\.server package +======================== + +Submodules +---------- + +pymodbus\.server\.async module +------------------------------ + +.. automodule:: pymodbus.server.async + :members: + :undoc-members: + :show-inheritance: + +pymodbus\.server\.sync module +----------------------------- + +.. automodule:: pymodbus.server.sync + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: pymodbus.server + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/sphinx/Makefile b/doc/sphinx/Makefile deleted file mode 100644 index 9ea4a8dfa..000000000 --- a/doc/sphinx/Makefile +++ /dev/null @@ -1,88 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf build/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html - @echo - @echo "Build finished. The HTML pages are in build/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) build/dirhtml - @echo - @echo "Build finished. The HTML pages are in build/dirhtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) build/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in build/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) build/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in build/qthelp, like this:" - @echo "# qcollectiongenerator build/qthelp/PyModbus.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile build/qthelp/PyModbus.qhc" - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex - @echo - @echo "Build finished; the LaTeX files are in build/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes - @echo - @echo "The overview file is in build/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in build/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) build/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in build/doctest/output.txt." diff --git a/doc/sphinx/conf.py b/doc/sphinx/conf.py deleted file mode 100644 index 3faaccc37..000000000 --- a/doc/sphinx/conf.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- coding: utf-8 -*- -# -# 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. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# 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. -# -import os -import sys - -sys.path.insert(0, os.path.abspath(os.pardir)) - -from pymodbus import __version__, __author__, __maintainer__ - -# -- 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 master toctree document. -master_doc = 'index' - -# General information about the project. -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 = __version__ -# The full version, including alpha/beta/rc tags. -release = __version__ - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# 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' - -# 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 - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# 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 -------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'default' - -# 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'] diff --git a/doc/sphinx/doctrees/environment.pickle b/doc/sphinx/doctrees/environment.pickle deleted file mode 100644 index 97c03334b..000000000 Binary files a/doc/sphinx/doctrees/environment.pickle and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/asynchronous-client.doctree b/doc/sphinx/doctrees/examples/asynchronous-client.doctree deleted file mode 100644 index bba09eeb2..000000000 Binary files a/doc/sphinx/doctrees/examples/asynchronous-client.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/asynchronous-processor.doctree b/doc/sphinx/doctrees/examples/asynchronous-processor.doctree deleted file mode 100644 index 72c7735d1..000000000 Binary files a/doc/sphinx/doctrees/examples/asynchronous-processor.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/asynchronous-server.doctree b/doc/sphinx/doctrees/examples/asynchronous-server.doctree deleted file mode 100644 index f960e7245..000000000 Binary files a/doc/sphinx/doctrees/examples/asynchronous-server.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/bcd-payload.doctree b/doc/sphinx/doctrees/examples/bcd-payload.doctree deleted file mode 100644 index 6f70e2287..000000000 Binary files a/doc/sphinx/doctrees/examples/bcd-payload.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/bottle-frontend.doctree b/doc/sphinx/doctrees/examples/bottle-frontend.doctree deleted file mode 100644 index 239d7da26..000000000 Binary files a/doc/sphinx/doctrees/examples/bottle-frontend.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/callback-server.doctree b/doc/sphinx/doctrees/examples/callback-server.doctree deleted file mode 100644 index f0b5ac74a..000000000 Binary files a/doc/sphinx/doctrees/examples/callback-server.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/changing-framers.doctree b/doc/sphinx/doctrees/examples/changing-framers.doctree deleted file mode 100644 index c7b4a142b..000000000 Binary files a/doc/sphinx/doctrees/examples/changing-framers.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/concurrent-client.doctree b/doc/sphinx/doctrees/examples/concurrent-client.doctree deleted file mode 100644 index 37ba5671d..000000000 Binary files a/doc/sphinx/doctrees/examples/concurrent-client.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/custom-datablock.doctree b/doc/sphinx/doctrees/examples/custom-datablock.doctree deleted file mode 100644 index 6342b4628..000000000 Binary files a/doc/sphinx/doctrees/examples/custom-datablock.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/custom-message.doctree b/doc/sphinx/doctrees/examples/custom-message.doctree deleted file mode 100644 index 8779f1c1f..000000000 Binary files a/doc/sphinx/doctrees/examples/custom-message.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/database-datastore.doctree b/doc/sphinx/doctrees/examples/database-datastore.doctree deleted file mode 100644 index b02a1f3c0..000000000 Binary files a/doc/sphinx/doctrees/examples/database-datastore.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/gtk-frontend.doctree b/doc/sphinx/doctrees/examples/gtk-frontend.doctree deleted file mode 100644 index d18a345c0..000000000 Binary files a/doc/sphinx/doctrees/examples/gtk-frontend.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/index.doctree b/doc/sphinx/doctrees/examples/index.doctree deleted file mode 100644 index 8e0a735b2..000000000 Binary files a/doc/sphinx/doctrees/examples/index.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/libmodbus-client.doctree b/doc/sphinx/doctrees/examples/libmodbus-client.doctree deleted file mode 100644 index 7ac317fa2..000000000 Binary files a/doc/sphinx/doctrees/examples/libmodbus-client.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/message-generator.doctree b/doc/sphinx/doctrees/examples/message-generator.doctree deleted file mode 100644 index f1c8e740c..000000000 Binary files a/doc/sphinx/doctrees/examples/message-generator.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/message-parser.doctree b/doc/sphinx/doctrees/examples/message-parser.doctree deleted file mode 100644 index 136037c4c..000000000 Binary files a/doc/sphinx/doctrees/examples/message-parser.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/modbus-logging.doctree b/doc/sphinx/doctrees/examples/modbus-logging.doctree deleted file mode 100644 index c22c357c5..000000000 Binary files a/doc/sphinx/doctrees/examples/modbus-logging.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/modbus-payload-server.doctree b/doc/sphinx/doctrees/examples/modbus-payload-server.doctree deleted file mode 100644 index e91de84c1..000000000 Binary files a/doc/sphinx/doctrees/examples/modbus-payload-server.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/modbus-payload.doctree b/doc/sphinx/doctrees/examples/modbus-payload.doctree deleted file mode 100644 index 37ad8a6ec..000000000 Binary files a/doc/sphinx/doctrees/examples/modbus-payload.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/modbus-scraper.doctree b/doc/sphinx/doctrees/examples/modbus-scraper.doctree deleted file mode 100644 index c21e58e59..000000000 Binary files a/doc/sphinx/doctrees/examples/modbus-scraper.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/modbus-simulator.doctree b/doc/sphinx/doctrees/examples/modbus-simulator.doctree deleted file mode 100644 index 3d5b66c9a..000000000 Binary files a/doc/sphinx/doctrees/examples/modbus-simulator.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/modicon-payload.doctree b/doc/sphinx/doctrees/examples/modicon-payload.doctree deleted file mode 100644 index f8dbe9511..000000000 Binary files a/doc/sphinx/doctrees/examples/modicon-payload.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/performance.doctree b/doc/sphinx/doctrees/examples/performance.doctree deleted file mode 100644 index 414dbca74..000000000 Binary files a/doc/sphinx/doctrees/examples/performance.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/redis-datastore.doctree b/doc/sphinx/doctrees/examples/redis-datastore.doctree deleted file mode 100644 index e5d0f9925..000000000 Binary files a/doc/sphinx/doctrees/examples/redis-datastore.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/remote-server-context.doctree b/doc/sphinx/doctrees/examples/remote-server-context.doctree deleted file mode 100644 index 0d823732d..000000000 Binary files a/doc/sphinx/doctrees/examples/remote-server-context.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/serial-forwarder.doctree b/doc/sphinx/doctrees/examples/serial-forwarder.doctree deleted file mode 100644 index 9f3e19026..000000000 Binary files a/doc/sphinx/doctrees/examples/serial-forwarder.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/synchronous-client-ext.doctree b/doc/sphinx/doctrees/examples/synchronous-client-ext.doctree deleted file mode 100644 index 91674e5f6..000000000 Binary files a/doc/sphinx/doctrees/examples/synchronous-client-ext.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/synchronous-client.doctree b/doc/sphinx/doctrees/examples/synchronous-client.doctree deleted file mode 100644 index f7f7b1691..000000000 Binary files a/doc/sphinx/doctrees/examples/synchronous-client.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/synchronous-server.doctree b/doc/sphinx/doctrees/examples/synchronous-server.doctree deleted file mode 100644 index 7959497a8..000000000 Binary files a/doc/sphinx/doctrees/examples/synchronous-server.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/thread-safe-datastore.doctree b/doc/sphinx/doctrees/examples/thread-safe-datastore.doctree deleted file mode 100644 index 606ce7966..000000000 Binary files a/doc/sphinx/doctrees/examples/thread-safe-datastore.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/tk-frontend.doctree b/doc/sphinx/doctrees/examples/tk-frontend.doctree deleted file mode 100644 index c7f6716b3..000000000 Binary files a/doc/sphinx/doctrees/examples/tk-frontend.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/updating-server.doctree b/doc/sphinx/doctrees/examples/updating-server.doctree deleted file mode 100644 index 3d6b43252..000000000 Binary files a/doc/sphinx/doctrees/examples/updating-server.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/examples/wx-frontend.doctree b/doc/sphinx/doctrees/examples/wx-frontend.doctree deleted file mode 100644 index e3f93f075..000000000 Binary files a/doc/sphinx/doctrees/examples/wx-frontend.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/index.doctree b/doc/sphinx/doctrees/index.doctree deleted file mode 100644 index 1bac3bb45..000000000 Binary files a/doc/sphinx/doctrees/index.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/async-client.doctree b/doc/sphinx/doctrees/library/async-client.doctree deleted file mode 100644 index 549c6a58e..000000000 Binary files a/doc/sphinx/doctrees/library/async-client.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/async-server.doctree b/doc/sphinx/doctrees/library/async-server.doctree deleted file mode 100644 index 0c5f143c0..000000000 Binary files a/doc/sphinx/doctrees/library/async-server.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/bit-read-message.doctree b/doc/sphinx/doctrees/library/bit-read-message.doctree deleted file mode 100644 index c850597c5..000000000 Binary files a/doc/sphinx/doctrees/library/bit-read-message.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/bit-write-message.doctree b/doc/sphinx/doctrees/library/bit-write-message.doctree deleted file mode 100644 index 41ee0ee23..000000000 Binary files a/doc/sphinx/doctrees/library/bit-write-message.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/client-common.doctree b/doc/sphinx/doctrees/library/client-common.doctree deleted file mode 100644 index 56437d3ea..000000000 Binary files a/doc/sphinx/doctrees/library/client-common.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/constants.doctree b/doc/sphinx/doctrees/library/constants.doctree deleted file mode 100644 index b606376fb..000000000 Binary files a/doc/sphinx/doctrees/library/constants.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/datastore/context.doctree b/doc/sphinx/doctrees/library/datastore/context.doctree deleted file mode 100644 index 9c8c53ff7..000000000 Binary files a/doc/sphinx/doctrees/library/datastore/context.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/datastore/index.doctree b/doc/sphinx/doctrees/library/datastore/index.doctree deleted file mode 100644 index 9159561b4..000000000 Binary files a/doc/sphinx/doctrees/library/datastore/index.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/datastore/remote.doctree b/doc/sphinx/doctrees/library/datastore/remote.doctree deleted file mode 100644 index acae54db8..000000000 Binary files a/doc/sphinx/doctrees/library/datastore/remote.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/datastore/store.doctree b/doc/sphinx/doctrees/library/datastore/store.doctree deleted file mode 100644 index 1ebacf7de..000000000 Binary files a/doc/sphinx/doctrees/library/datastore/store.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/device.doctree b/doc/sphinx/doctrees/library/device.doctree deleted file mode 100644 index b8952ec2c..000000000 Binary files a/doc/sphinx/doctrees/library/device.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/diag-message.doctree b/doc/sphinx/doctrees/library/diag-message.doctree deleted file mode 100644 index e21c8c32a..000000000 Binary files a/doc/sphinx/doctrees/library/diag-message.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/events.doctree b/doc/sphinx/doctrees/library/events.doctree deleted file mode 100644 index b8773d81f..000000000 Binary files a/doc/sphinx/doctrees/library/events.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/exceptions.doctree b/doc/sphinx/doctrees/library/exceptions.doctree deleted file mode 100644 index ae59f9a71..000000000 Binary files a/doc/sphinx/doctrees/library/exceptions.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/factory.doctree b/doc/sphinx/doctrees/library/factory.doctree deleted file mode 100644 index 6f955affc..000000000 Binary files a/doc/sphinx/doctrees/library/factory.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/file-message.doctree b/doc/sphinx/doctrees/library/file-message.doctree deleted file mode 100644 index 01b9070c4..000000000 Binary files a/doc/sphinx/doctrees/library/file-message.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/index.doctree b/doc/sphinx/doctrees/library/index.doctree deleted file mode 100644 index 5afbde909..000000000 Binary files a/doc/sphinx/doctrees/library/index.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/interfaces.doctree b/doc/sphinx/doctrees/library/interfaces.doctree deleted file mode 100644 index 4ac498043..000000000 Binary files a/doc/sphinx/doctrees/library/interfaces.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/mei-message.doctree b/doc/sphinx/doctrees/library/mei-message.doctree deleted file mode 100644 index 5689b22ad..000000000 Binary files a/doc/sphinx/doctrees/library/mei-message.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/other-message.doctree b/doc/sphinx/doctrees/library/other-message.doctree deleted file mode 100644 index 707b782c9..000000000 Binary files a/doc/sphinx/doctrees/library/other-message.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/payload.doctree b/doc/sphinx/doctrees/library/payload.doctree deleted file mode 100644 index 35bce27dd..000000000 Binary files a/doc/sphinx/doctrees/library/payload.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/pdu.doctree b/doc/sphinx/doctrees/library/pdu.doctree deleted file mode 100644 index b148c8e71..000000000 Binary files a/doc/sphinx/doctrees/library/pdu.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/pymodbus.doctree b/doc/sphinx/doctrees/library/pymodbus.doctree deleted file mode 100644 index 340baffdd..000000000 Binary files a/doc/sphinx/doctrees/library/pymodbus.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/register-read-message.doctree b/doc/sphinx/doctrees/library/register-read-message.doctree deleted file mode 100644 index d0ca283c4..000000000 Binary files a/doc/sphinx/doctrees/library/register-read-message.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/register-write-message.doctree b/doc/sphinx/doctrees/library/register-write-message.doctree deleted file mode 100644 index b28e508a3..000000000 Binary files a/doc/sphinx/doctrees/library/register-write-message.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/sync-client.doctree b/doc/sphinx/doctrees/library/sync-client.doctree deleted file mode 100644 index 1bd7de384..000000000 Binary files a/doc/sphinx/doctrees/library/sync-client.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/sync-server.doctree b/doc/sphinx/doctrees/library/sync-server.doctree deleted file mode 100644 index e8946211e..000000000 Binary files a/doc/sphinx/doctrees/library/sync-server.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/transaction.doctree b/doc/sphinx/doctrees/library/transaction.doctree deleted file mode 100644 index f1388e7f5..000000000 Binary files a/doc/sphinx/doctrees/library/transaction.doctree and /dev/null differ diff --git a/doc/sphinx/doctrees/library/utilities.doctree b/doc/sphinx/doctrees/library/utilities.doctree deleted file mode 100644 index 0749c3e1d..000000000 Binary files a/doc/sphinx/doctrees/library/utilities.doctree and /dev/null differ diff --git a/doc/sphinx/examples/asynchronous-client.rst b/doc/sphinx/examples/asynchronous-client.rst deleted file mode 100644 index 7f5b7d3c3..000000000 --- a/doc/sphinx/examples/asynchronous-client.rst +++ /dev/null @@ -1,16 +0,0 @@ -================================================== -Asynchronous Client Example -================================================== - -The asynchronous client functions in the same way as the synchronous -client, however, the asynchronous client uses twisted to return deferreds -for the response result. Just like the synchronous version, it works against -TCP, UDP, serial ASCII, and serial RTU devices. - -Below an asynchronous tcp client is demonstrated running against a -reference server. If you do not have a device to test with, feel free -to run a pymodbus server instance or start the reference tester in -the tools directory. - -.. literalinclude:: ../../../examples/common/asynchronous-client.py - diff --git a/doc/sphinx/examples/asynchronous-processor.rst b/doc/sphinx/examples/asynchronous-processor.rst deleted file mode 100644 index 4afd8504e..000000000 --- a/doc/sphinx/examples/asynchronous-processor.rst +++ /dev/null @@ -1,15 +0,0 @@ -================================================== -Asynchronous Processor Example -================================================== - -Below is a simplified asynchronous client skeleton that was -submitted by a user of the library. It can be used as a guide -for implementing more complex pollers or state machines. - -Feel free to test it against whatever device you currently have -available. If you do not have a device to test with, feel free -to run a pymodbus server instance or start the reference tester in -the tools directory. - -.. literalinclude:: ../../../examples/common/asynchronous-processor.py - diff --git a/doc/sphinx/examples/bottle-frontend.rst b/doc/sphinx/examples/bottle-frontend.rst deleted file mode 100644 index 95507c5a8..000000000 --- a/doc/sphinx/examples/bottle-frontend.rst +++ /dev/null @@ -1,22 +0,0 @@ -================================================== -Bottle Web Frontend Example -================================================== - --------------------------------------------------- -Summary --------------------------------------------------- - -This is a simple example of adding a live REST api -on top of a running pymodbus server. This uses the -bottle microframework to achieve this. - -The example can be hosted under twisted as well as -the bottle internal server and can furthermore be -run behind gunicorn, cherrypi, etc wsgi containers. - --------------------------------------------------- -Main Program --------------------------------------------------- - -.. literalinclude:: ../../../examples/gui/bottle/frontend.py - diff --git a/doc/sphinx/examples/concurrent-client.rst b/doc/sphinx/examples/concurrent-client.rst deleted file mode 100644 index 1a3799ac9..000000000 --- a/doc/sphinx/examples/concurrent-client.rst +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Modbus Concurrent Client Example -================================================== - -.. literalinclude:: ../../../examples/contrib/concurrent-client.py - diff --git a/doc/sphinx/examples/database-datastore.rst b/doc/sphinx/examples/database-datastore.rst deleted file mode 100644 index 9186be812..000000000 --- a/doc/sphinx/examples/database-datastore.rst +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Database Datastore Example -================================================== - -.. literalinclude:: ../../../examples/contrib/database-datastore.py - diff --git a/doc/sphinx/examples/gtk-frontend.rst b/doc/sphinx/examples/gtk-frontend.rst deleted file mode 100644 index 3efc72644..000000000 --- a/doc/sphinx/examples/gtk-frontend.rst +++ /dev/null @@ -1,26 +0,0 @@ -================================================== -Glade/GTK Frontend Example -================================================== - -Main Program --------------------------------------------------- - -This is an example simulator that is written using the pygtk -bindings. Although it currently does not have a frontend for -modifying the context values, it does allow one to expose N -virtual modbus devices to a network which is useful for testing -data center monitoring tools. - -.. note:: The virtual networking code will only work on linux - -.. literalinclude:: ../../../examples/gui/gtk/simulator.py - :language: python - -Glade Layout File --------------------------------------------------- - -The following is the glade layout file that is used by this script: - -.. literalinclude:: ../../../examples/gui/gtk/simulator.glade - :language: xml - diff --git a/doc/sphinx/examples/index.rst b/doc/sphinx/examples/index.rst deleted file mode 100644 index a41f01129..000000000 --- a/doc/sphinx/examples/index.rst +++ /dev/null @@ -1,60 +0,0 @@ - -Pymodbus Library Examples -==================================== - -*What follows is a collection of examples using the pymodbus -library in various ways* - -Example Library Code --------------------------------------------------- - -.. toctree:: - :maxdepth: 2 - - asynchronous-client - asynchronous-server - asynchronous-processor - custom-message - custom-datablock - modbus-logging - modbus-payload - modbus-payload-server - synchronous-client - synchronous-client-ext - synchronous-server - performance - updating-server - callback-server - changing-framers - thread-safe-datastore - -Custom Pymodbus Code --------------------------------------------------- - -.. toctree:: - :maxdepth: 2 - - redis-datastore - database-datastore - bcd-payload - modicon-payload - message-generator - message-parser - serial-forwarder - modbus-scraper - modbus-simulator - concurrent-client - libmodbus-client - remote-server-context - -Example Frontend Code --------------------------------------------------- - -.. toctree:: - :maxdepth: 2 - - gtk-frontend - tk-frontend - wx-frontend - bottle-frontend - diff --git a/doc/sphinx/examples/libmodbus-client.rst b/doc/sphinx/examples/libmodbus-client.rst deleted file mode 100644 index 17ac8e2cf..000000000 --- a/doc/sphinx/examples/libmodbus-client.rst +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Libmodbus Client Facade -================================================== - -.. literalinclude:: ../../../examples/contrib/libmodbus-client.py - diff --git a/doc/sphinx/examples/message-generator.rst b/doc/sphinx/examples/message-generator.rst deleted file mode 100644 index 605554c45..000000000 --- a/doc/sphinx/examples/message-generator.rst +++ /dev/null @@ -1,26 +0,0 @@ -================================================== -Modbus Message Generator Example -================================================== - -This is an example of a utility that will build -examples of modbus messages in all the available -formats in the pymodbus package. - --------------------------------------------------- -Program Source --------------------------------------------------- - -.. literalinclude:: ../../../examples/contrib/message-generator.py - --------------------------------------------------- -Example Request Messages --------------------------------------------------- - -.. literalinclude:: ../../../examples/contrib/tx-messages - --------------------------------------------------- -Example Response Messages --------------------------------------------------- - -.. literalinclude:: ../../../examples/contrib/rx-messages - diff --git a/doc/sphinx/examples/message-parser.rst b/doc/sphinx/examples/message-parser.rst deleted file mode 100644 index 0bbaee9fc..000000000 --- a/doc/sphinx/examples/message-parser.rst +++ /dev/null @@ -1,55 +0,0 @@ -================================================== -Modbus Message Parsing Example -================================================== - -This is an example of a parser to decode raw messages -to a readable description. It will attempt to decode -a message to the request and response version of a -message if possible. Here is an example output:: - - $./message-parser.py -b -m 000112340006ff076d - ================================================================================ - Decoding Message 000112340006ff076d - ================================================================================ - ServerDecoder - -------------------------------------------------------------------------------- - name = ReadExceptionStatusRequest - check = 0x0 - unit_id = 0xff - transaction_id = 0x1 - protocol_id = 0x1234 - documentation = - This function code is used to read the contents of eight Exception Status - outputs in a remote device. The function provides a simple method for - accessing this information, because the Exception Output references are - known (no output reference is needed in the function). - - ClientDecoder - -------------------------------------------------------------------------------- - name = ReadExceptionStatusResponse - check = 0x0 - status = 0x6d - unit_id = 0xff - transaction_id = 0x1 - protocol_id = 0x1234 - documentation = - The normal response contains the status of the eight Exception Status - outputs. The outputs are packed into one data byte, with one bit - per output. The status of the lowest output reference is contained - in the least significant bit of the byte. The contents of the eight - Exception Status outputs are device specific. - --------------------------------------------------- -Program Source --------------------------------------------------- - -.. literalinclude:: ../../../examples/contrib/message-parser.py - --------------------------------------------------- -Example Messages --------------------------------------------------- - -See the documentation for the message generator -for a collection of messages that can be parsed -by this utility. - diff --git a/doc/sphinx/examples/modbus-payload-server.rst b/doc/sphinx/examples/modbus-payload-server.rst deleted file mode 100644 index 9144f0f53..000000000 --- a/doc/sphinx/examples/modbus-payload-server.rst +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Modbus Payload Server Context Building Example -================================================== - -.. literalinclude:: ../../../examples/common/modbus-payload-server.py - diff --git a/doc/sphinx/examples/modbus-payload.rst b/doc/sphinx/examples/modbus-payload.rst deleted file mode 100644 index 79e46dfdb..000000000 --- a/doc/sphinx/examples/modbus-payload.rst +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Modbus Payload Building/Decoding Example -================================================== - -.. literalinclude:: ../../../examples/common/modbus-payload.py - diff --git a/doc/sphinx/examples/modicon-payload.rst b/doc/sphinx/examples/modicon-payload.rst deleted file mode 100644 index 997a12f50..000000000 --- a/doc/sphinx/examples/modicon-payload.rst +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Modicon Encoded Example -================================================== - -.. literalinclude:: ../../../examples/contrib/modicon-payload.py - diff --git a/doc/sphinx/examples/performance.rst b/doc/sphinx/examples/performance.rst deleted file mode 100644 index 93185bdea..000000000 --- a/doc/sphinx/examples/performance.rst +++ /dev/null @@ -1,11 +0,0 @@ -================================================== -Synchronous Client Performance Check -================================================== - -Below is a quick example of how to test the performance of a tcp modbus -device using the synchronous tcp client. If you do not have a device -to test with, feel free to run a pymodbus server instance or start -the reference tester in the tools directory. - -.. literalinclude:: ../../../examples/common/performance.py - diff --git a/doc/sphinx/examples/redis-datastore.rst b/doc/sphinx/examples/redis-datastore.rst deleted file mode 100644 index bb5554e04..000000000 --- a/doc/sphinx/examples/redis-datastore.rst +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Redis Datastore Example -================================================== - -.. literalinclude:: ../../../examples/contrib/redis-datastore.py - diff --git a/doc/sphinx/examples/serial-forwarder.rst b/doc/sphinx/examples/serial-forwarder.rst deleted file mode 100644 index 87f6e0a0c..000000000 --- a/doc/sphinx/examples/serial-forwarder.rst +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Synchronous Serial Forwarder -================================================== - -.. literalinclude:: ../../../examples/contrib/serial-forwarder.py - diff --git a/doc/sphinx/examples/synchronous-client-ext.rst b/doc/sphinx/examples/synchronous-client-ext.rst deleted file mode 100644 index 5012ec8b0..000000000 --- a/doc/sphinx/examples/synchronous-client-ext.rst +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Synchronous Client Extended Example -================================================== - -.. literalinclude:: ../../../examples/common/synchronous-client-ext.py - diff --git a/doc/sphinx/examples/synchronous-client.rst b/doc/sphinx/examples/synchronous-client.rst deleted file mode 100644 index b90563402..000000000 --- a/doc/sphinx/examples/synchronous-client.rst +++ /dev/null @@ -1,19 +0,0 @@ -================================================== -Synchronous Client Example -================================================== - -It should be noted that each request will block waiting for the result. If asynchronous -behaviour is required, please use the asynchronous client implementations. -The synchronous client, works against TCP, UDP, serial ASCII, and serial RTU devices. - -The synchronous client exposes the most popular methods of the modbus protocol, -however, if you want to execute other methods against the device, -simple create a request instance and pass it to the execute method. - -Below an synchronous tcp client is demonstrated running against a -reference server. If you do not have a device to test with, feel free -to run a pymodbus server instance or start the reference tester in -the tools directory. - -.. literalinclude:: ../../../examples/common/synchronous-client.py - diff --git a/doc/sphinx/examples/tk-frontend.rst b/doc/sphinx/examples/tk-frontend.rst deleted file mode 100644 index 1849d0abc..000000000 --- a/doc/sphinx/examples/tk-frontend.rst +++ /dev/null @@ -1,17 +0,0 @@ -================================================== -TK Frontend Example -================================================== - -Main Program --------------------------------------------------- - -This is an example simulator that is written using the native tk -toolkit. Although it currently does not have a frontend for -modifying the context values, it does allow one to expose N -virtual modbus devices to a network which is useful for testing -data center monitoring tools. - -.. note:: The virtual networking code will only work on linux - -.. literalinclude:: ../../../examples/gui/tk/simulator.py - diff --git a/doc/sphinx/examples/updating-server.rst b/doc/sphinx/examples/updating-server.rst deleted file mode 100644 index 07d1baac0..000000000 --- a/doc/sphinx/examples/updating-server.rst +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Updating Server Example -================================================== - -.. literalinclude:: ../../../examples/common/updating-server.py - diff --git a/doc/sphinx/examples/wx-frontend.rst b/doc/sphinx/examples/wx-frontend.rst deleted file mode 100644 index 5d68142c0..000000000 --- a/doc/sphinx/examples/wx-frontend.rst +++ /dev/null @@ -1,17 +0,0 @@ -================================================== -WX Frontend Example -================================================== - -Main Program --------------------------------------------------- - -This is an example simulator that is written using the python wx -bindings. Although it currently does not have a frontend for -modifying the context values, it does allow one to expose N -virtual modbus devices to a network which is useful for testing -data center monitoring tools. - -.. note:: The virtual networking code will only work on linux - -.. literalinclude:: ../../../examples/gui/wx/simulator.py - diff --git a/doc/sphinx/html/.buildinfo b/doc/sphinx/html/.buildinfo deleted file mode 100644 index 72a1539e3..000000000 --- a/doc/sphinx/html/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: a869ccec57cd788c41a89393439ff025 -tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/doc/sphinx/html/_modules/index.html b/doc/sphinx/html/_modules/index.html deleted file mode 100644 index 1133838f3..000000000 --- a/doc/sphinx/html/_modules/index.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - - Overview: module code — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/bit_read_message.html b/doc/sphinx/html/_modules/pymodbus/bit_read_message.html deleted file mode 100644 index 53fb041ba..000000000 --- a/doc/sphinx/html/_modules/pymodbus/bit_read_message.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - - - - pymodbus.bit_read_message — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.bit_read_message

-"""
-Bit Reading Request/Response messages
---------------------------------------
-
-"""
-import struct
-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
-
-
-
[docs]class ReadBitsRequestBase(ModbusRequest): - ''' Base class for Messages Requesting bit values ''' - - _rtu_frame_size = 8 -
[docs] def __init__(self, address, count, **kwargs): - ''' Initializes the read request data - - :param address: The start address to read from - :param count: The number of bits after 'address' to read - ''' - ModbusRequest.__init__(self, **kwargs) - self.address = address - self.count = count
- -
[docs] def encode(self): - ''' Encodes a request pdu - - :returns: The encoded pdu - ''' - return struct.pack('>HH', self.address, self.count)
- -
[docs] def decode(self, data): - ''' Decodes a request pdu - - :param data: The packet data to decode - ''' - self.address, self.count = struct.unpack('>HH', data)
- -
[docs] 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
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :returns: A string representation of the instance - ''' - return "ReadBitRequest(%d,%d)" % (self.address, self.count)
- - -
[docs]class ReadBitsResponseBase(ModbusResponse): - ''' Base class for Messages responding to bit-reading values ''' - - _rtu_byte_count_pos = 2 - -
[docs] def __init__(self, values, **kwargs): - ''' Initializes a new instance - - :param values: The requested values to be returned - ''' - ModbusResponse.__init__(self, **kwargs) - self.bits = values or []
- -
[docs] def encode(self): - ''' Encodes response pdu - - :returns: The encoded packet message - ''' - result = pack_bitstring(self.bits) - packet = struct.pack(">B", len(result)) + result - return packet
- -
[docs] def decode(self, data): - ''' Decodes response pdu - - :param data: The packet data to decode - ''' - self.byte_count = byte2int(data[0]) - self.bits = unpack_bitstring(data[1:])
- -
[docs] def setBit(self, address, value=1): - ''' Helper function to set the specified bit - - :param address: The bit to set - :param value: The value to set the bit to - ''' - self.bits[address] = (value != 0)
- -
[docs] def resetBit(self, address): - ''' Helper function to set the specified bit to 0 - - :param address: The bit to reset - ''' - self.setBit(address, 0)
- -
[docs] def getBit(self, address): - ''' Helper function to get the specified bit's value - - :param address: The bit to query - :returns: The value of the requested bit - ''' - return self.bits[address]
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :returns: A string representation of the instance - ''' - return "ReadBitResponse(%d)" % len(self.bits)
- - -
[docs]class ReadCoilsRequest(ReadBitsRequestBase): - ''' - This function code is used to read from 1 to 2000(0x7d0) contiguous status - of coils in a remote device. The Request PDU specifies the starting - address, ie the address of the first coil specified, and the number of - coils. In the PDU Coils are addressed starting at zero. Therefore coils - numbered 1-16 are addressed as 0-15. - ''' - function_code = 1 - -
[docs] def __init__(self, address=None, count=None, **kwargs): - ''' Initializes a new instance - - :param address: The address to start reading from - :param count: The number of bits to read - ''' - ReadBitsRequestBase.__init__(self, address, count, **kwargs)
- -
[docs] def execute(self, context): - ''' Run a read coils request against a datastore - - Before running the request, we make sure that the request is in - the max valid range (0x001-0x7d0). Next we make sure that the - request is valid against the current datastore. - - :param context: The datastore to request from - :returns: The initializes response message, exception message otherwise - ''' - if not (1 <= self.count <= 0x7d0): - return self.doException(merror.IllegalValue) - if not context.validate(self.function_code, self.address, self.count): - return self.doException(merror.IllegalAddress) - values = context.getValues(self.function_code, self.address, self.count) - return ReadCoilsResponse(values)
- - -
[docs]class ReadCoilsResponse(ReadBitsResponseBase): - ''' - The coils in the response message are packed as one coil per bit of - the data field. Status is indicated as 1= ON and 0= OFF. The LSB of the - first data byte contains the output addressed in the query. The other - coils follow toward the high order end of this byte, and from low order - to high order in subsequent bytes. - - If the returned output quantity is not a multiple of eight, the - remaining bits in the final data byte will be padded with zeros - (toward the high order end of the byte). The Byte Count field specifies - the quantity of complete bytes of data. - ''' - function_code = 1 - -
[docs] def __init__(self, values=None, **kwargs): - ''' Intializes a new instance - - :param values: The request values to respond with - ''' - ReadBitsResponseBase.__init__(self, values, **kwargs)
- - -
[docs]class ReadDiscreteInputsRequest(ReadBitsRequestBase): - ''' - This function code is used to read from 1 to 2000(0x7d0) contiguous status - of discrete inputs in a remote device. The Request PDU specifies the - starting address, ie the address of the first input specified, and the - number of inputs. In the PDU Discrete Inputs are addressed starting at - zero. Therefore Discrete inputs numbered 1-16 are addressed as 0-15. - ''' - function_code = 2 - -
[docs] def __init__(self, address=None, count=None, **kwargs): - ''' Intializes a new instance - - :param address: The address to start reading from - :param count: The number of bits to read - ''' - ReadBitsRequestBase.__init__(self, address, count, **kwargs)
- -
[docs] def execute(self, context): - ''' Run a read discrete input request against a datastore - - Before running the request, we make sure that the request is in - the max valid range (0x001-0x7d0). Next we make sure that the - request is valid against the current datastore. - - :param context: The datastore to request from - :returns: The initializes response message, exception message otherwise - ''' - if not (1 <= self.count <= 0x7d0): - return self.doException(merror.IllegalValue) - if not context.validate(self.function_code, self.address, self.count): - return self.doException(merror.IllegalAddress) - values = context.getValues(self.function_code, self.address, self.count) - return ReadDiscreteInputsResponse(values)
- - -
[docs]class ReadDiscreteInputsResponse(ReadBitsResponseBase): - ''' - The discrete inputs in the response message are packed as one input per - bit of the data field. Status is indicated as 1= ON; 0= OFF. The LSB of - the first data byte contains the input addressed in the query. The other - inputs follow toward the high order end of this byte, and from low order - to high order in subsequent bytes. - - If the returned input quantity is not a multiple of eight, the - remaining bits in the final data byte will be padded with zeros - (toward the high order end of the byte). The Byte Count field specifies - the quantity of complete bytes of data. - ''' - function_code = 2 - -
[docs] def __init__(self, values=None, **kwargs): - ''' Intializes a new instance - - :param values: The request values to respond with - ''' - ReadBitsResponseBase.__init__(self, values, **kwargs)
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "ReadCoilsRequest", "ReadCoilsResponse", - "ReadDiscreteInputsRequest", "ReadDiscreteInputsResponse", -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/bit_write_message.html b/doc/sphinx/html/_modules/pymodbus/bit_write_message.html deleted file mode 100644 index c1a379119..000000000 --- a/doc/sphinx/html/_modules/pymodbus/bit_write_message.html +++ /dev/null @@ -1,353 +0,0 @@ - - - - - - - - pymodbus.bit_write_message — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.bit_write_message

-"""
-Bit Writing Request/Response
-------------------------------
-
-TODO write mask request/response
-"""
-import struct
-from pymodbus.constants import ModbusStatus
-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
-
-#---------------------------------------------------------------------------#
-# Local Constants
-#---------------------------------------------------------------------------#
-# These are defined in the spec to turn a coil on/off
-#---------------------------------------------------------------------------#
-_turn_coil_on  = struct.pack(">H", ModbusStatus.On)
-_turn_coil_off = struct.pack(">H", ModbusStatus.Off)
-
-
-
[docs]class WriteSingleCoilRequest(ModbusRequest): - ''' - This function code is used to write a single output to either ON or OFF - in a remote device. - - The requested ON/OFF state is specified by a constant in the request - data field. A value of FF 00 hex requests the output to be ON. A value - of 00 00 requests it to be OFF. All other values are illegal and will - not affect the output. - - The Request PDU specifies the address of the coil to be forced. Coils - are addressed starting at zero. Therefore coil numbered 1 is addressed - as 0. The requested ON/OFF state is specified by a constant in the Coil - Value field. A value of 0XFF00 requests the coil to be ON. A value of - 0X0000 requests the coil to be off. All other values are illegal and - will not affect the coil. - ''' - function_code = 5 - _rtu_frame_size = 8 - -
[docs] def __init__(self, address=None, value=None, **kwargs): - ''' Initializes a new instance - - :param address: The variable address to write - :param value: The value to write at address - ''' - ModbusRequest.__init__(self, **kwargs) - self.address = address - self.value = bool(value)
- -
[docs] def encode(self): - ''' Encodes write coil request - - :returns: The byte encoded message - ''' - result = struct.pack('>H', self.address) - if self.value: result += _turn_coil_on - else: result += _turn_coil_off - return result
- -
[docs] def decode(self, data): - ''' Decodes a write coil request - - :param data: The packet data to decode - ''' - self.address, value = struct.unpack('>HH', data) - self.value = (value == ModbusStatus.On)
- -
[docs] def execute(self, context): - ''' Run a write coil request against a datastore - - :param context: The datastore to request from - :returns: The populated response or exception message - ''' - #if self.value not in [ModbusStatus.Off, ModbusStatus.On]: - # return self.doException(merror.IllegalValue) - if not context.validate(self.function_code, self.address, 1): - return self.doException(merror.IllegalAddress) - - context.setValues(self.function_code, self.address, [self.value]) - values = context.getValues(self.function_code, self.address, 1) - return WriteSingleCoilResponse(self.address, values[0])
- -
[docs] def get_response_pdu_size(self): - """ - Func_code (1 byte) + Output Address (2 byte) + Output Value (2 Bytes) - :return: - """ - return 1 + 2 + 2
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :return: A string representation of the instance - ''' - return "WriteCoilRequest(%d, %s) => " % (self.address, self.value)
- - -
[docs]class WriteSingleCoilResponse(ModbusResponse): - ''' - The normal response is an echo of the request, returned after the coil - state has been written. - ''' - function_code = 5 - _rtu_frame_size = 8 - -
[docs] def __init__(self, address=None, value=None, **kwargs): - ''' Initializes a new instance - - :param address: The variable address written to - :param value: The value written at address - ''' - ModbusResponse.__init__(self, **kwargs) - self.address = address - self.value = value
- -
[docs] def encode(self): - ''' Encodes write coil response - - :return: The byte encoded message - ''' - result = struct.pack('>H', self.address) - if self.value: result += _turn_coil_on - else: result += _turn_coil_off - return result
- -
[docs] def decode(self, data): - ''' Decodes a write coil response - - :param data: The packet data to decode - ''' - self.address, value = struct.unpack('>HH', data) - self.value = (value == ModbusStatus.On)
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :returns: A string representation of the instance - ''' - return "WriteCoilResponse(%d) => %d" % (self.address, self.value)
- - -
[docs]class WriteMultipleCoilsRequest(ModbusRequest): - ''' - "This function code is used to force each coil in a sequence of coils to - either ON or OFF in a remote device. The Request PDU specifies the coil - references to be forced. Coils are addressed starting at zero. Therefore - coil numbered 1 is addressed as 0. - - The requested ON/OFF states are specified by contents of the request - data field. A logical '1' in a bit position of the field requests the - corresponding output to be ON. A logical '0' requests it to be OFF." - ''' - function_code = 15 - _rtu_byte_count_pos = 6 - -
[docs] def __init__(self, address=None, values=None, **kwargs): - ''' Initializes a new instance - - :param address: The starting request address - :param values: The values to write - ''' - ModbusRequest.__init__(self, **kwargs) - self.address = address - if not values: values = [] - elif not hasattr(values, '__iter__'): values = [values] - self.values = values - self.byte_count = (len(self.values) + 7) // 8
- -
[docs] def encode(self): - ''' Encodes write coils request - - :returns: The byte encoded message - ''' - count = len(self.values) - self.byte_count = (count + 7) // 8 - packet = struct.pack('>HHB', self.address, count, self.byte_count) - packet += pack_bitstring(self.values) - return packet
- -
[docs] def decode(self, data): - ''' Decodes a write coils request - - :param data: The packet data to decode - ''' - self.address, count, self.byte_count = struct.unpack('>HHB', data[0:5]) - values = unpack_bitstring(data[5:]) - self.values = values[:count]
- -
[docs] def execute(self, context): - ''' Run a write coils request against a datastore - - :param context: The datastore to request from - :returns: The populated response or exception message - ''' - count = len(self.values) - if not (1 <= count <= 0x07b0): - return self.doException(merror.IllegalValue) - 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) - - context.setValues(self.function_code, self.address, self.values) - return WriteMultipleCoilsResponse(self.address, count)
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :returns: A string representation of the instance - ''' - params = (self.address, len(self.values)) - return "WriteNCoilRequest (%d) => %d " % params
- - -
[docs]class WriteMultipleCoilsResponse(ModbusResponse): - ''' - The normal response returns the function code, starting address, and - quantity of coils forced. - ''' - function_code = 15 - _rtu_frame_size = 8 - -
[docs] def __init__(self, address=None, count=None, **kwargs): - ''' Initializes a new instance - - :param address: The starting variable address written to - :param count: The number of values written - ''' - ModbusResponse.__init__(self, **kwargs) - self.address = address - self.count = count
- -
[docs] def encode(self): - ''' Encodes write coils response - - :returns: The byte encoded message - ''' - return struct.pack('>HH', self.address, self.count)
- -
[docs] def decode(self, data): - ''' Decodes a write coils response - - :param data: The packet data to decode - ''' - self.address, self.count = struct.unpack('>HH', data)
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :returns: A string representation of the instance - ''' - return "WriteNCoilResponse(%d, %d)" % (self.address, self.count)
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "WriteSingleCoilRequest", "WriteSingleCoilResponse", - "WriteMultipleCoilsRequest", "WriteMultipleCoilsResponse", -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/client/async.html b/doc/sphinx/html/_modules/pymodbus/client/async.html deleted file mode 100644 index 51c879075..000000000 --- a/doc/sphinx/html/_modules/pymodbus/client/async.html +++ /dev/null @@ -1,305 +0,0 @@ - - - - - - - - pymodbus.client.async — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.client.async

-"""
-Implementation of a Modbus Client Using Twisted
---------------------------------------------------
-
-Example run::
-
-    from twisted.internet import reactor, protocol
-    from pymodbus.client.async import ModbusClientProtocol
-
-    def printResult(result):
-        print "Result: %d" % result.bits[0]
-
-    def process(client):
-        result = client.write_coil(1, True)
-        result.addCallback(printResult)
-        reactor.callLater(1, reactor.stop)
-
-    defer = protocol.ClientCreator(reactor, ModbusClientProtocol
-            ).connectTCP("localhost", 502)
-    defer.addCallback(process)
-
-Another example::
-
-    from twisted.internet import reactor
-    from pymodbus.client.async import ModbusClientFactory
-
-    def process():
-        factory = reactor.connectTCP("localhost", 502, ModbusClientFactory())
-        reactor.stop()
-
-    if __name__ == "__main__":
-       reactor.callLater(1, process)
-       reactor.run()
-"""
-from twisted.internet import defer, protocol
-from pymodbus.factory import ClientDecoder
-from pymodbus.exceptions import ConnectionException
-from pymodbus.transaction import ModbusSocketFramer
-from pymodbus.transaction import FifoTransactionManager
-from pymodbus.transaction import DictTransactionManager
-from pymodbus.client.common import ModbusClientMixin
-from twisted.python.failure import Failure
-
-#---------------------------------------------------------------------------#
-# Logging
-#---------------------------------------------------------------------------#
-import logging
-_logger = logging.getLogger(__name__)
-
-
-#---------------------------------------------------------------------------#
-# Connected Client Protocols
-#---------------------------------------------------------------------------#
-
[docs]class ModbusClientProtocol(protocol.Protocol, ModbusClientMixin): - ''' - This represents the base modbus client protocol. All the application - layer code is deferred to a higher level wrapper. - ''' - -
[docs] def __init__(self, framer=None, **kwargs): - ''' Initializes the framer module - - :param framer: The framer to use for the protocol - ''' - self._connected = False - self.framer = framer or ModbusSocketFramer(ClientDecoder()) - if isinstance(self.framer, ModbusSocketFramer): - self.transaction = DictTransactionManager(self, **kwargs) - else: self.transaction = FifoTransactionManager(self, **kwargs)
- -
[docs] def connectionMade(self): - ''' Called upon a successful client connection. - ''' - _logger.debug("Client connected to modbus server") - self._connected = True
- -
[docs] def connectionLost(self, reason): - ''' Called upon a client disconnect - - :param reason: The reason for the disconnect - ''' - _logger.debug("Client disconnected from modbus server: %s" % reason) - self._connected = False - for tid in list(self.transaction): - self.transaction.getTransaction(tid).errback(Failure( - ConnectionException('Connection lost during request')))
- -
[docs] def dataReceived(self, data): - ''' Get response, check for valid message, decode result - - :param data: The data returned from the server - ''' - self.framer.processIncomingPacket(data, self._handleResponse)
- -
[docs] def execute(self, request): - ''' Starts the producer to send the next request to - consumer.write(Frame(request)) - ''' - request.transaction_id = self.transaction.getNextTID() - packet = self.framer.buildPacket(request) - self.transport.write(packet) - return self._buildResponse(request.transaction_id)
- -
[docs] def _handleResponse(self, reply): - ''' Handle the processed response and link to correct deferred - - :param reply: The reply to process - ''' - if reply is not None: - tid = reply.transaction_id - handler = self.transaction.getTransaction(tid) - if handler: - handler.callback(reply) - else: _logger.debug("Unrequested message: " + str(reply))
- -
[docs] def _buildResponse(self, tid): - ''' Helper method to return a deferred response - for the current request. - - :param tid: The transaction identifier for this response - :returns: A defer linked to the latest request - ''' - if not self._connected: - return defer.fail(Failure( - ConnectionException('Client is not connected'))) - - d = defer.Deferred() - self.transaction.addTransaction(d, tid) - return d
- - #----------------------------------------------------------------------# - # Extra Functions - #----------------------------------------------------------------------# - #if send_failed: - # if self.retry > 0: - # deferLater(clock, self.delay, send, message) - # self.retry -= 1 - - -#---------------------------------------------------------------------------# -# Not Connected Client Protocol -#---------------------------------------------------------------------------# -class ModbusUdpClientProtocol(protocol.DatagramProtocol, ModbusClientMixin): - ''' - This represents the base modbus client protocol. All the application - layer code is deferred to a higher level wrapper. - ''' - - def __init__(self, framer=None, **kwargs): - ''' Initializes the framer module - - :param framer: The framer to use for the protocol - ''' - self.framer = framer or ModbusSocketFramer(ClientDecoder()) - if isinstance(self.framer, ModbusSocketFramer): - self.transaction = DictTransactionManager(self, **kwargs) - else: self.transaction = FifoTransactionManager(self, **kwargs) - - def datagramReceived(self, data, params): - ''' Get response, check for valid message, decode result - - :param data: The data returned from the server - :param params: The host parameters sending the datagram - ''' - _logger.debug("Datagram from: %s:%d" % params) - self.framer.processIncomingPacket(data, self._handleResponse) - - def execute(self, request): - ''' Starts the producer to send the next request to - consumer.write(Frame(request)) - ''' - request.transaction_id = self.transaction.getNextTID() - packet = self.framer.buildPacket(request) - self.transport.write(packet) - return self._buildResponse(request.transaction_id) - - def _handleResponse(self, reply): - ''' Handle the processed response and link to correct deferred - - :param reply: The reply to process - ''' - if reply is not None: - tid = reply.transaction_id - handler = self.transaction.getTransaction(tid) - if handler: - handler.callback(reply) - else: _logger.debug("Unrequested message: " + str(reply)) - - def _buildResponse(self, tid): - ''' Helper method to return a deferred response - for the current request. - - :param tid: The transaction identifier for this response - :returns: A defer linked to the latest request - ''' - d = defer.Deferred() - self.transaction.addTransaction(d, tid) - return d - - -#---------------------------------------------------------------------------# -# Client Factories -#---------------------------------------------------------------------------# -
[docs]class ModbusClientFactory(protocol.ReconnectingClientFactory): - ''' Simple client protocol factory ''' - - protocol = ModbusClientProtocol
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "ModbusClientProtocol", "ModbusUdpClientProtocol", - "ModbusClientFactory", -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/client/common.html b/doc/sphinx/html/_modules/pymodbus/client/common.html deleted file mode 100644 index 5eec0cabb..000000000 --- a/doc/sphinx/html/_modules/pymodbus/client/common.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - - - - - pymodbus.client.common — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.client.common

-'''
-Modbus Client Common
-----------------------------------
-
-This is a common client mixin that can be used by
-both the synchronous and asynchronous clients to
-simplify the interface.
-'''
-from pymodbus.bit_read_message import *
-from pymodbus.bit_write_message import *
-from pymodbus.register_read_message import *
-from pymodbus.register_write_message import *
-from pymodbus.diag_message import *
-from pymodbus.file_message import *
-from pymodbus.other_message import *
-
-
-
[docs]class ModbusClientMixin(object): - ''' - This is a modbus client mixin that provides additional factory - methods for all the current modbus methods. This can be used - instead of the normal pattern of:: - - # instead of this - client = ModbusClient(...) - request = ReadCoilsRequest(1,10) - response = client.execute(request) - - # now like this - client = ModbusClient(...) - response = client.read_coils(1, 10) - ''' - -
[docs] def read_coils(self, address, count=1, **kwargs): - ''' - - :param address: The starting address to read from - :param count: The number of coils to read - :param unit: The slave unit this request is targeting - :returns: A deferred response handle - ''' - request = ReadCoilsRequest(address, count, **kwargs) - return self.execute(request)
- -
[docs] def read_discrete_inputs(self, address, count=1, **kwargs): - ''' - - :param address: The starting address to read from - :param count: The number of discretes to read - :param unit: The slave unit this request is targeting - :returns: A deferred response handle - ''' - request = ReadDiscreteInputsRequest(address, count, **kwargs) - return self.execute(request)
- -
[docs] def write_coil(self, address, value, **kwargs): - ''' - - :param address: The starting address to write to - :param value: The value to write to the specified address - :param unit: The slave unit this request is targeting - :returns: A deferred response handle - ''' - request = WriteSingleCoilRequest(address, value, **kwargs) - return self.execute(request)
- -
[docs] def write_coils(self, address, values, **kwargs): - ''' - - :param address: The starting address to write to - :param values: The values to write to the specified address - :param unit: The slave unit this request is targeting - :returns: A deferred response handle - ''' - request = WriteMultipleCoilsRequest(address, values, **kwargs) - return self.execute(request)
- -
[docs] def write_register(self, address, value, **kwargs): - ''' - - :param address: The starting address to write to - :param value: The value to write to the specified address - :param unit: The slave unit this request is targeting - :returns: A deferred response handle - ''' - request = WriteSingleRegisterRequest(address, value, **kwargs) - return self.execute(request)
- -
[docs] def write_registers(self, address, values, **kwargs): - ''' - - :param address: The starting address to write to - :param values: The values to write to the specified address - :param unit: The slave unit this request is targeting - :returns: A deferred response handle - ''' - request = WriteMultipleRegistersRequest(address, values, **kwargs) - return self.execute(request)
- -
[docs] def read_holding_registers(self, address, count=1, **kwargs): - ''' - - :param address: The starting address to read from - :param count: The number of registers to read - :param unit: The slave unit this request is targeting - :returns: A deferred response handle - ''' - request = ReadHoldingRegistersRequest(address, count, **kwargs) - return self.execute(request)
- -
[docs] def read_input_registers(self, address, count=1, **kwargs): - ''' - - :param address: The starting address to read from - :param count: The number of registers to read - :param unit: The slave unit this request is targeting - :returns: A deferred response handle - ''' - request = ReadInputRegistersRequest(address, count, **kwargs) - return self.execute(request)
- -
[docs] def readwrite_registers(self, *args, **kwargs): - ''' - - :param read_address: The address to start reading from - :param read_count: The number of registers to read from address - :param write_address: The address to start writing to - :param write_registers: The registers to write to the specified address - :param unit: The slave unit this request is targeting - :returns: A deferred response handle - ''' - request = ReadWriteMultipleRegistersRequest(*args, **kwargs) - return self.execute(request)
- -
[docs] def mask_write_register(self, *args, **kwargs): - ''' - - :param address: The address of the register to write - :param and_mask: The and bitmask to apply to the register address - :param or_mask: The or bitmask to apply to the register address - :param unit: The slave unit this request is targeting - :returns: A deferred response handle - ''' - request = MaskWriteRegisterRequest(*args, **kwargs) - return self.execute(request)
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ 'ModbusClientMixin' ] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/client/sync.html b/doc/sphinx/html/_modules/pymodbus/client/sync.html deleted file mode 100644 index 04e0ce562..000000000 --- a/doc/sphinx/html/_modules/pymodbus/client/sync.html +++ /dev/null @@ -1,506 +0,0 @@ - - - - - - - - pymodbus.client.sync — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.client.sync

-import socket
-import serial
-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
-from pymodbus.transaction import DictTransactionManager
-from pymodbus.transaction import ModbusSocketFramer, ModbusBinaryFramer
-from pymodbus.transaction import ModbusAsciiFramer, ModbusRtuFramer
-from pymodbus.client.common import ModbusClientMixin
-
-#---------------------------------------------------------------------------#
-# Logging
-#---------------------------------------------------------------------------#
-import logging
-_logger = logging.getLogger(__name__)
-
-
-#---------------------------------------------------------------------------#
-# The Synchronous Clients
-#---------------------------------------------------------------------------#
-
[docs]class BaseModbusClient(ModbusClientMixin): - ''' - Inteface for a modbus synchronous client. Defined here are all the - methods for performing the related request methods. Derived classes - simply need to implement the transport methods and set the correct - framer. - ''' - -
[docs] def __init__(self, framer, **kwargs): - ''' Initialize a client instance - - :param framer: The modbus framer implementation to use - ''' - self.framer = framer - if isinstance(self.framer, ModbusSocketFramer): - self.transaction = DictTransactionManager(self, **kwargs) - else: self.transaction = FifoTransactionManager(self, **kwargs)
- - #-----------------------------------------------------------------------# - # Client interface - #-----------------------------------------------------------------------# -
[docs] def connect(self): - ''' Connect to the modbus remote host - - :returns: True if connection succeeded, False otherwise - ''' - raise NotImplementedException("Method not implemented by derived class")
- -
[docs] def close(self): - ''' Closes the underlying socket connection - ''' - pass
- -
[docs] def _send(self, request): - ''' Sends data on the underlying socket - - :param request: The encoded request to send - :return: The number of bytes written - ''' - raise NotImplementedException("Method not implemented by derived class")
- -
[docs] def _recv(self, size): - ''' Reads data from the underlying descriptor - - :param size: The number of bytes to read - :return: The bytes read - ''' - raise NotImplementedException("Method not implemented by derived class")
- - #-----------------------------------------------------------------------# - # Modbus client methods - #-----------------------------------------------------------------------# -
[docs] def execute(self, request=None): - ''' - :param request: The request to process - :returns: The result of the request execution - ''' - if not self.connect(): - raise ConnectionException("Failed to connect[%s]" % (self.__str__())) - return self.transaction.execute(request)
- - #-----------------------------------------------------------------------# - # The magic methods - #-----------------------------------------------------------------------# -
[docs] def __enter__(self): - ''' Implement the client with enter block - - :returns: The current instance of the client - ''' - if not self.connect(): - raise ConnectionException("Failed to connect[%s]" % (self.__str__())) - return self
- -
[docs] def __exit__(self, klass, value, traceback): - ''' Implement the client with exit block ''' - self.close()
- -
[docs] def __str__(self): - ''' Builds a string representation of the connection - - :returns: The string representation - ''' - return "Null Transport"
- - -#---------------------------------------------------------------------------# -# Modbus TCP Client Transport Implementation -#---------------------------------------------------------------------------# -
[docs]class ModbusTcpClient(BaseModbusClient): - ''' Implementation of a modbus tcp client - ''' - -
[docs] def __init__(self, host='127.0.0.1', port=Defaults.Port, - framer=ModbusSocketFramer, **kwargs): - ''' Initialize a client instance - - :param host: The host to connect to (default 127.0.0.1) - :param port: The modbus port to connect to (default 502) - :param 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 - ''' - self.host = host - 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)
- -
[docs] def connect(self): - ''' Connect to the modbus tcp server - - :returns: True if connection succeeded, False otherwise - ''' - if self.socket: return True - try: - address = (self.host, self.port) - self.socket = socket.create_connection((self.host, self.port), - 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)) - self.close() - return self.socket != None
- -
[docs] def close(self): - ''' Closes the underlying socket connection - ''' - if self.socket: - self.socket.close() - self.socket = None
- -
[docs] def _send(self, request): - ''' Sends data on the underlying socket - - :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.send(request) - return 0
- -
[docs] def _recv(self, size): - ''' Reads data from the underlying descriptor - - :param size: The number of bytes to read - :return: The bytes read - ''' - if not self.socket: - raise ConnectionException(self.__str__()) - return self.socket.recv(size)
- -
[docs] def __str__(self): - ''' Builds a string representation of the connection - - :returns: The string representation - ''' - return "%s:%s" % (self.host, self.port)
- - -#---------------------------------------------------------------------------# -# Modbus UDP Client Transport Implementation -#---------------------------------------------------------------------------# -
[docs]class ModbusUdpClient(BaseModbusClient): - ''' Implementation of a modbus udp client - ''' - -
[docs] def __init__(self, host='127.0.0.1', port=Defaults.Port, - framer=ModbusSocketFramer, **kwargs): - ''' Initialize a client instance - - :param host: The host to connect to (default 127.0.0.1) - :param port: The modbus port to connect to (default 502) - :param framer: The modbus framer to use (default ModbusSocketFramer) - :param timeout: The timeout to use for this socket (default None) - ''' - self.host = host - self.port = port - self.socket = None - self.timeout = kwargs.get('timeout', None) - BaseModbusClient.__init__(self, framer(ClientDecoder()), **kwargs)
- - @classmethod -
[docs] def _get_address_family(cls, address): - ''' A helper method to get the correct address family - for a given address. - - :param address: The address to get the af for - :returns: AF_INET for ipv4 and AF_INET6 for ipv6 - ''' - try: - _ = socket.inet_pton(socket.AF_INET6, address) - except socket.error: # not a valid ipv6 address - return socket.AF_INET - return socket.AF_INET6
- -
[docs] def connect(self): - ''' Connect to the modbus tcp server - - :returns: True if connection succeeded, False otherwise - ''' - if self.socket: return True - try: - family = ModbusUdpClient._get_address_family(self.host) - self.socket = socket.socket(family, socket.SOCK_DGRAM) - self.socket.settimeout(self.timeout) - except socket.error as ex: - _logger.error('Unable to create udp socket %s' % ex) - self.close() - return self.socket != None
- -
[docs] def close(self): - ''' Closes the underlying socket connection - ''' - self.socket = None
- -
[docs] def _send(self, request): - ''' Sends data on the underlying socket - - :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.sendto(request, (self.host, self.port)) - return 0
- -
[docs] def _recv(self, size): - ''' Reads data from the underlying descriptor - - :param size: The number of bytes to read - :return: The bytes read - ''' - if not self.socket: - raise ConnectionException(self.__str__()) - return self.socket.recvfrom(size)[0]
- -
[docs] def __str__(self): - ''' Builds a string representation of the connection - - :returns: The string representation - ''' - return "%s:%s" % (self.host, self.port)
- - -#---------------------------------------------------------------------------# -# Modbus Serial Client Transport Implementation -#---------------------------------------------------------------------------# -
[docs]class ModbusSerialClient(BaseModbusClient): - ''' Implementation of a modbus serial client - ''' - -
[docs] def __init__(self, method='ascii', **kwargs): - ''' Initialize a serial client instance - - The methods to connect are:: - - - ascii - - rtu - - binary - - :param method: The method to use for connection - :param port: The serial port to attach to - :param stopbits: The number of stop bits to use - :param bytesize: The bytesize of the serial messages - :param parity: Which kind of parity to use - :param baudrate: The baud rate to use for the serial device - :param timeout: The timeout between serial requests (default 3s) - ''' - self.method = method - self.socket = None - BaseModbusClient.__init__(self, self.__implementation(method), **kwargs) - - self.port = kwargs.get('port', 0) - self.stopbits = kwargs.get('stopbits', Defaults.Stopbits) - self.bytesize = kwargs.get('bytesize', Defaults.Bytesize) - 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): - ''' Returns the requested framer - - :method: The serial framer to instantiate - :returns: The requested serial framer - ''' - method = method.lower() - if method == 'ascii': return ModbusAsciiFramer(ClientDecoder()) - elif method == 'rtu': return ModbusRtuFramer(ClientDecoder()) - elif method == 'binary': return ModbusBinaryFramer(ClientDecoder()) - elif method == 'socket': return ModbusSocketFramer(ClientDecoder()) - raise ParameterException("Invalid framer method requested") - -
[docs] def connect(self): - ''' Connect to the modbus serial server - - :returns: True if connection succeeded, False otherwise - ''' - if self.socket: return True - try: - 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 as msg: - _logger.error(msg) - self.close() - if self.method == "rtu": - self._last_frame_end = time.time() - return self.socket != None
- -
[docs] def close(self): - ''' Closes the underlying socket connection - ''' - if self.socket: - self.socket.close() - self.socket = None
- -
[docs] 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: - 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") - time.sleep(self._last_frame_end + self._silent_interval - ts) - - try: - in_waiting = "in_waiting" if hasattr(self.socket, "in_waiting") else "inWaiting" - if in_waiting == "in_waiting": - waitingbytes = getattr(self.socket, in_waiting) - else: - waitingbytes = getattr(self.socket, in_waiting)() - if waitingbytes: - result = self.socket.read(waitingbytes) - if _logger.isEnabledFor(logging.WARNING): - _logger.warning("cleanup recv buffer before send: " + " ".join([hex(byte2int(x)) for x in result])) - except NotImplementedError: - pass - - size = self.socket.write(request) - if self.method == "rtu": - self._last_frame_end = time.time() - return size - return 0
- -
[docs] def _recv(self, size): - ''' Reads data from the underlying descriptor - - :param size: The number of bytes to read - :return: The bytes read - ''' - if not self.socket: - raise ConnectionException(self.__str__()) - result = self.socket.read(size) - if self.method == "rtu": - self._last_frame_end = time.time() - return result
- -
[docs] def __str__(self): - ''' Builds a string representation of the connection - - :returns: The string representation - ''' - return "%s baud[%s]" % (self.method, self.baudrate)
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "ModbusTcpClient", "ModbusUdpClient", "ModbusSerialClient" -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/constants.html b/doc/sphinx/html/_modules/pymodbus/constants.html deleted file mode 100644 index adfc5a0b0..000000000 --- a/doc/sphinx/html/_modules/pymodbus/constants.html +++ /dev/null @@ -1,331 +0,0 @@ - - - - - - - - pymodbus.constants — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.constants

-'''
-Constants For Modbus Server/Client
-----------------------------------
-
-This is the single location for storing default
-values for the servers and clients.
-'''
-from pymodbus.interfaces import Singleton
-
-
-
[docs]class Defaults(Singleton): - ''' A collection of modbus default values - - .. attribute:: Port - - The default modbus tcp server port (502) - - .. attribute:: Retries - - The default number of times a client should retry the given - request before failing (3) - - .. attribute:: RetryOnEmpty - - A flag indicating if a transaction should be retried in the - case that an empty response is received. This is useful for - slow clients that may need more time to process a requst. - - .. attribute:: Timeout - - The default amount of time a client should wait for a request - to be processed (3 seconds) - - .. attribute:: Reconnects - - The default number of times a client should attempt to reconnect - before deciding the server is down (0) - - .. attribute:: TransactionId - - The starting transaction identifier number (0) - - .. attribute:: ProtocolId - - The modbus protocol id. Currently this is set to 0 in all - but proprietary implementations. - - .. attribute:: UnitId - - The modbus slave addrss. Currently this is set to 0x00 which - means this request should be broadcast to all the slave devices - (really means that all the devices should respons). - - .. attribute:: Baudrate - - The speed at which the data is transmitted over the serial line. - This defaults to 19200. - - .. attribute:: Parity - - The type of checksum to use to verify data integrity. This can be - on of the following:: - - - (E)ven - 1 0 1 0 | P(0) - - (O)dd - 1 0 1 0 | P(1) - - (N)one - 1 0 1 0 | no parity - - This defaults to (N)one. - - .. attribute:: Bytesize - - The number of bits in a byte of serial data. This can be one of - 5, 6, 7, or 8. This defaults to 8. - - .. attribute:: Stopbits - - The number of bits sent after each character in a message to - indicate the end of the byte. This defaults to 1. - - .. attribute:: ZeroMode - - Indicates if the slave datastore should use indexing at 0 or 1. - More about this can be read in section 4.4 of the modbus specification. - - .. attribute:: IgnoreMissingSlaves - - In case a request is made to a missing slave, this defines if an error - should be returned or simply ignored. This is useful for the case of a - serial server emulater where a request to a non-existant slave on a bus - will never respond. The client in this case will simply timeout. - ''' - Port = 502 - Retries = 3 - RetryOnEmpty = False - Timeout = 3 - Reconnects = 0 - TransactionId = 0 - ProtocolId = 0 - UnitId = 0x00 - Baudrate = 19200 - Parity = 'N' - Bytesize = 8 - Stopbits = 1 - ZeroMode = False - IgnoreMissingSlaves = False
- - -
[docs]class ModbusStatus(Singleton): - ''' - These represent various status codes in the modbus - protocol. - - .. attribute:: Waiting - - This indicates that a modbus device is currently - waiting for a given request to finish some running task. - - .. attribute:: Ready - - This indicates that a modbus device is currently - free to perform the next request task. - - .. attribute:: On - - This indicates that the given modbus entity is on - - .. attribute:: Off - - This indicates that the given modbus entity is off - - .. attribute:: SlaveOn - - This indicates that the given modbus slave is running - - .. attribute:: SlaveOff - - This indicates that the given modbus slave is not running - ''' - Waiting = 0xffff - Ready = 0x0000 - On = 0xff00 - Off = 0x0000 - SlaveOn = 0xff - SlaveOff = 0x00
- - -
[docs]class Endian(Singleton): - ''' An enumeration representing the various byte endianess. - - .. attribute:: Auto - - This indicates that the byte order is chosen by the - current native environment. - - .. attribute:: Big - - This indicates that the bytes are in little endian format - - .. attribute:: Little - - This indicates that the bytes are in big endian format - - .. note:: I am simply borrowing the format strings from the - python struct module for my convenience. - ''' - Auto = '@' - Big = '>' - Little = '<'
- - -
[docs]class ModbusPlusOperation(Singleton): - ''' Represents the type of modbus plus request - - .. attribute:: GetStatistics - - Operation requesting that the current modbus plus statistics - be returned in the response. - - .. attribute:: ClearStatistics - - Operation requesting that the current modbus plus statistics - be cleared and not returned in the response. - ''' - GetStatistics = 0x0003 - ClearStatistics = 0x0004
- - -
[docs]class DeviceInformation(Singleton): - ''' Represents what type of device information to read - - .. attribute:: Basic - - This is the basic (required) device information to be returned. - This includes VendorName, ProductCode, and MajorMinorRevision - code. - - .. attribute:: Regular - - In addition to basic data objects, the device provides additional - and optinoal identification and description data objects. All of - the objects of this category are defined in the standard but their - implementation is optional. - - .. attribute:: Extended - - In addition to regular data objects, the device provides additional - and optional identification and description private data about the - physical device itself. All of these data are device dependent. - - .. attribute:: Specific - - Request to return a single data object. - ''' - Basic = 0x01 - Regular = 0x02 - Extended = 0x03 - Specific = 0x04
- - -
[docs]class MoreData(Singleton): - ''' Represents the more follows condition - - .. attribute:: Nothing - - This indiates that no more objects are going to be returned. - - .. attribute:: KeepReading - - This indicates that there are more objects to be returned. - ''' - Nothing = 0x00 - KeepReading = 0xFF
- -#---------------------------------------------------------------------------# -# Exported Identifiers -#---------------------------------------------------------------------------# -__all__ = [ - "Defaults", "ModbusStatus", "Endian", - "ModbusPlusOperation", - "DeviceInformation", "MoreData", -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/datastore/context.html b/doc/sphinx/html/_modules/pymodbus/datastore/context.html deleted file mode 100644 index 306a20e72..000000000 --- a/doc/sphinx/html/_modules/pymodbus/datastore/context.html +++ /dev/null @@ -1,246 +0,0 @@ - - - - - - - - pymodbus.datastore.context — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.datastore.context

-from pymodbus.exceptions import ParameterException, NoSuchSlaveException
-from pymodbus.interfaces import IModbusSlaveContext
-from pymodbus.datastore.store import ModbusSequentialDataBlock
-from pymodbus.constants import Defaults
-from pymodbus.compat import iteritems, itervalues
-
-#---------------------------------------------------------------------------#
-# Logging
-#---------------------------------------------------------------------------#
-import logging;
-_logger = logging.getLogger(__name__)
-
-
-#---------------------------------------------------------------------------#
-# Slave Contexts
-#---------------------------------------------------------------------------#
-
[docs]class ModbusSlaveContext(IModbusSlaveContext): - ''' - This creates a modbus data model with each data access - stored in its own personal block - ''' - -
[docs] def __init__(self, *args, **kwargs): - ''' Initializes the datastores, defaults to fully populated - sequential data blocks if none are passed in. - - :param kwargs: Each element is a ModbusDataBlock - - 'di' - Discrete Inputs initializer - 'co' - Coils initializer - 'hr' - Holding Register initializer - 'ir' - Input Registers iniatializer - ''' - self.store = {} - self.store['d'] = kwargs.get('di', ModbusSequentialDataBlock.create()) - self.store['c'] = kwargs.get('co', ModbusSequentialDataBlock.create()) - self.store['i'] = kwargs.get('ir', ModbusSequentialDataBlock.create()) - self.store['h'] = kwargs.get('hr', ModbusSequentialDataBlock.create()) - self.zero_mode = kwargs.get('zero_mode', Defaults.ZeroMode)
- -
[docs] def __str__(self): - ''' Returns a string representation of the context - - :returns: A string representation of the context - ''' - return "Modbus Slave Context"
- -
[docs] def reset(self): - ''' Resets all the datastores to their default values ''' - for datastore in itervalues(self.store): - datastore.reset()
- -
[docs] def validate(self, fx, address, count=1): - ''' Validates the request to make sure it is in range - - :param fx: The function we are working with - :param address: The starting address - :param count: The number of values to test - :returns: True if the request in within range, False otherwise - ''' - if not self.zero_mode: address = address + 1 - _logger.debug("validate[%d] %d:%d" % (fx, address, count)) - return self.store[self.decode(fx)].validate(address, count)
- -
[docs] def getValues(self, fx, address, count=1): - ''' Validates the request to make sure it is in range - - :param fx: The function we are working with - :param address: The starting address - :param count: The number of values to retrieve - :returns: The requested values from a:a+c - ''' - if not self.zero_mode: address = address + 1 - _logger.debug("getValues[%d] %d:%d" % (fx, address, count)) - return self.store[self.decode(fx)].getValues(address, count)
- -
[docs] def setValues(self, fx, address, values): - ''' Sets the datastore with the supplied values - - :param fx: The function we are working with - :param address: The starting address - :param values: The new values to be set - ''' - if not self.zero_mode: address = address + 1 - _logger.debug("setValues[%d] %d:%d" % (fx, address, len(values))) - self.store[self.decode(fx)].setValues(address, values)
- - -
[docs]class ModbusServerContext(object): - ''' This represents a master collection of slave contexts. - If single is set to true, it will be treated as a single - context so every unit-id returns the same context. If single - is set to false, it will be interpreted as a collection of - slave contexts. - ''' - -
[docs] def __init__(self, slaves=None, single=True): - ''' Initializes a new instance of a modbus server context. - - :param slaves: A dictionary of client contexts - :param single: Set to true to treat this as a single context - ''' - self.single = single - self.__slaves = slaves or {} - if self.single: - self.__slaves = {Defaults.UnitId: self.__slaves}
- -
[docs] def __iter__(self): - ''' Iterater over the current collection of slave - contexts. - - :returns: An iterator over the slave contexts - ''' - return iteritems(self.__slaves)
- -
[docs] def __contains__(self, slave): - ''' Check if the given slave is in this list - - :param slave: slave The slave to check for existance - :returns: True if the slave exists, False otherwise - ''' - return slave in self.__slaves
- -
[docs] def __setitem__(self, slave, context): - ''' Used to set a new slave context - - :param slave: The slave context to set - :param context: The new context to set for this slave - ''' - if self.single: slave = Defaults.UnitId - if 0xf7 >= slave >= 0x00: - self.__slaves[slave] = context - else: - raise NoSuchSlaveException('slave index :{} out of range'.format(slave))
- -
[docs] def __delitem__(self, slave): - ''' Wrapper used to access the slave context - - :param slave: The slave context to remove - ''' - if not self.single and (0xf7 >= slave >= 0x00): - del self.__slaves[slave] - else: - raise NoSuchSlaveException('slave index: {} out of range'.format(slave))
- -
[docs] def __getitem__(self, slave): - ''' Used to get access to a slave context - - :param slave: The slave context to get - :returns: The requested slave context - ''' - if self.single: slave = Defaults.UnitId - if slave in self.__slaves: - return self.__slaves.get(slave) - else: - raise NoSuchSlaveException("slave - {} does not exist, or is out of range".format(slave))
-
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/datastore/remote.html b/doc/sphinx/html/_modules/pymodbus/datastore/remote.html deleted file mode 100644 index 05a888254..000000000 --- a/doc/sphinx/html/_modules/pymodbus/datastore/remote.html +++ /dev/null @@ -1,190 +0,0 @@ - - - - - - - - pymodbus.datastore.remote — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.datastore.remote

-from pymodbus.exceptions import NotImplementedException
-from pymodbus.interfaces import IModbusSlaveContext
-
-#---------------------------------------------------------------------------#
-# Logging
-#---------------------------------------------------------------------------#
-import logging
-_logger = logging.getLogger(__name__)
-
-
-#---------------------------------------------------------------------------#
-# Context
-#---------------------------------------------------------------------------#
-
[docs]class RemoteSlaveContext(IModbusSlaveContext): - ''' TODO - This creates a modbus data model that connects to - a remote device (depending on the client used) - ''' - -
[docs] def __init__(self, client): - ''' Initializes the datastores - - :param client: The client to retrieve values with - ''' - self._client = client - self.__build_mapping()
- -
[docs] def reset(self): - ''' Resets all the datastores to their default values ''' - raise NotImplementedException()
- -
[docs] def validate(self, fx, address, count=1): - ''' Validates the request to make sure it is in range - - :param fx: The function we are working with - :param address: The starting address - :param count: The number of values to test - :returns: True if the request in within range, False otherwise - ''' - _logger.debug("validate[%d] %d:%d" % (fx, address, count)) - result = self.__get_callbacks[self.decode(fx)](address, count) - return result.function_code < 0x80
- -
[docs] def getValues(self, fx, address, count=1): - ''' Validates the request to make sure it is in range - - :param fx: The function we are working with - :param address: The starting address - :param count: The number of values to retrieve - :returns: The requested values from a:a+c - ''' - # TODO deal with deferreds - _logger.debug("get values[%d] %d:%d" % (fx, address, count)) - result = self.__get_callbacks[self.decode(fx)](address, count) - return self.__extract_result(self.decode(fx), result)
- -
[docs] def setValues(self, fx, address, values): - ''' Sets the datastore with the supplied values - - :param fx: The function we are working with - :param address: The starting address - :param values: The new values to be set - ''' - # TODO deal with deferreds - _logger.debug("set values[%d] %d:%d" % (fx, address, len(values))) - self.__set_callbacks[self.decode(fx)](address, values)
- -
[docs] def __str__(self): - ''' Returns a string representation of the context - - :returns: A string representation of the context - ''' - return "Remote Slave Context(%s)" % self._client
- - def __build_mapping(self): - ''' - A quick helper method to build the function - code mapper. - ''' - self.__get_callbacks = { - 'd': lambda a, c: self._client.read_discrete_inputs(a, c), - 'c': lambda a, c: self._client.read_coils(a, c), - 'h': lambda a, c: self._client.read_holding_registers(a, c), - 'i': lambda a, c: self._client.read_input_registers(a, c), - } - self.__set_callbacks = { - 'd': lambda a, v: self._client.write_coils(a, v), - 'c': lambda a, v: self._client.write_coils(a, v), - 'h': lambda a, v: self._client.write_registers(a, v), - 'i': lambda a, v: self._client.write_registers(a, v), - } - - def __extract_result(self, fx, result): - ''' A helper method to extract the values out of - a response. TODO make this consistent (values?) - ''' - if result.function_code < 0x80: - if fx in ['d', 'c']: return result.bits - if fx in ['h', 'i']: return result.registers - else: return result
-
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/datastore/store.html b/doc/sphinx/html/_modules/pymodbus/datastore/store.html deleted file mode 100644 index 54b6b4f02..000000000 --- a/doc/sphinx/html/_modules/pymodbus/datastore/store.html +++ /dev/null @@ -1,343 +0,0 @@ - - - - - - - - pymodbus.datastore.store — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.datastore.store

-"""
-Modbus Server Datastore
--------------------------
-
-For each server, you will create a ModbusServerContext and pass
-in the default address space for each data access.  The class
-will create and manage the data.
-
-Further modification of said data accesses should be performed
-with [get,set][access]Values(address, count)
-
-Datastore Implementation
--------------------------
-
-There are two ways that the server datastore can be implemented.
-The first is a complete range from 'address' start to 'count'
-number of indecies.  This can be thought of as a straight array::
-
-    data = range(1, 1 + count)
-    [1,2,3,...,count]
-
-The other way that the datastore can be implemented (and how
-many devices implement it) is a associate-array::
-
-    data = {1:'1', 3:'3', ..., count:'count'}
-    [1,3,...,count]
-
-The difference between the two is that the latter will allow
-arbitrary gaps in its datastore while the former will not.
-This is seen quite commonly in some modbus implementations.
-What follows is a clear example from the field:
-
-Say a company makes two devices to monitor power usage on a rack.
-One works with three-phase and the other with a single phase. The
-company will dictate a modbus data mapping such that registers::
-
-    n:      phase 1 power
-    n+1:    phase 2 power
-    n+2:    phase 3 power
-
-Using this, layout, the first device will implement n, n+1, and n+2,
-however, the second device may set the latter two values to 0 or
-will simply not implmented the registers thus causing a single read
-or a range read to fail.
-
-I have both methods implemented, and leave it up to the user to change
-based on their preference.
-"""
-from pymodbus.exceptions import NotImplementedException, ParameterException
-from pymodbus.compat import iteritems, iterkeys, itervalues, get_next
-
-#---------------------------------------------------------------------------#
-# Logging
-#---------------------------------------------------------------------------#
-import logging
-_logger = logging.getLogger(__name__)
-
-
-#---------------------------------------------------------------------------#
-# Datablock Storage
-#---------------------------------------------------------------------------#
-
[docs]class BaseModbusDataBlock(object): - ''' - Base class for a modbus datastore - - Derived classes must create the following fields: - @address The starting address point - @defult_value The default value of the datastore - @values The actual datastore values - - Derived classes must implemented the following methods: - validate(self, address, count=1) - getValues(self, address, count=1) - setValues(self, address, values) - ''' - -
[docs] def default(self, count, value=False): - ''' Used to initialize a store to one value - - :param count: The number of fields to set - :param value: The default value to set to the fields - ''' - self.default_value = value - self.values = [self.default_value] * count - self.address = 0x00
- -
[docs] def reset(self): - ''' Resets the datastore to the initialized default value ''' - self.values = [self.default_value] * len(self.values)
- -
[docs] def validate(self, address, count=1): - ''' Checks to see if the request is in range - - :param address: The starting address - :param count: The number of values to test for - :returns: True if the request in within range, False otherwise - ''' - raise NotImplementedException("Datastore Address Check")
- -
[docs] def getValues(self, address, count=1): - ''' Returns the requested values from the datastore - - :param address: The starting address - :param count: The number of values to retrieve - :returns: The requested values from a:a+c - ''' - raise NotImplementedException("Datastore Value Retrieve")
- -
[docs] def setValues(self, address, values): - ''' Returns the requested values from the datastore - - :param address: The starting address - :param values: The values to store - ''' - raise NotImplementedException("Datastore Value Retrieve")
- -
[docs] def __str__(self): - ''' Build a representation of the datastore - - :returns: A string representation of the datastore - ''' - return "DataStore(%d, %d)" % (len(self.values), self.default_value)
- -
[docs] def __iter__(self): - ''' Iterater over the data block data - - :returns: An iterator of the data block data - ''' - if isinstance(self.values, dict): - return iteritems(self.values) - return enumerate(self.values, self.address)
- - -
[docs]class ModbusSequentialDataBlock(BaseModbusDataBlock): - ''' Creates a sequential modbus datastore ''' - -
[docs] def __init__(self, address, values): - ''' Initializes the datastore - - :param address: The starting address of the datastore - :param values: Either a list or a dictionary of values - ''' - self.address = address - if hasattr(values, '__iter__'): - self.values = list(values) - else: self.values = [values] - self.default_value = self.values[0].__class__()
- - @classmethod -
[docs] def create(klass): - ''' Factory method to create a datastore with the - full address space initialized to 0x00 - - :returns: An initialized datastore - ''' - return klass(0x00, [0x00] * 65536)
- -
[docs] def validate(self, address, count=1): - ''' Checks to see if the request is in range - - :param address: The starting address - :param count: The number of values to test for - :returns: True if the request in within range, False otherwise - ''' - result = (self.address <= address) - result &= ((self.address + len(self.values)) >= (address + count)) - return result
- -
[docs] def getValues(self, address, count=1): - ''' Returns the requested values of the datastore - - :param address: The starting address - :param count: The number of values to retrieve - :returns: The requested values from a:a+c - ''' - start = address - self.address - return self.values[start:start + count]
- -
[docs] def setValues(self, address, values): - ''' Sets the requested values of the datastore - - :param address: The starting address - :param values: The new values to be set - ''' - if not isinstance(values, list): - values = [values] - start = address - self.address - self.values[start:start + len(values)] = values
- - -
[docs]class ModbusSparseDataBlock(BaseModbusDataBlock): - ''' Creates a sparse modbus datastore ''' - -
[docs] def __init__(self, values): - ''' Initializes the datastore - - Using the input values we create the default - datastore value and the starting address - - :param values: Either a list or a dictionary of values - ''' - if isinstance(values, dict): - self.values = values - elif hasattr(values, '__iter__'): - self.values = dict(enumerate(values)) - else: raise ParameterException( - "Values for datastore must be a list or dictionary") - self.default_value = get_next(itervalues(self.values)).__class__() - self.address = get_next(iterkeys(self.values))
- - @classmethod -
[docs] def create(klass): - ''' Factory method to create a datastore with the - full address space initialized to 0x00 - - :returns: An initialized datastore - ''' - return klass([0x00] * 65536)
- -
[docs] def validate(self, address, count=1): - ''' Checks to see if the request is in range - - :param address: The starting address - :param count: The number of values to test for - :returns: True if the request in within range, False otherwise - ''' - if count == 0: return False - handle = set(range(address, address + count)) - return handle.issubset(set(iterkeys(self.values)))
- -
[docs] def getValues(self, address, count=1): - ''' Returns the requested values of the datastore - - :param address: The starting address - :param count: The number of values to retrieve - :returns: The requested values from a:a+c - ''' - return [self.values[i] for i in range(address, address + count)]
- -
[docs] def setValues(self, address, values): - ''' Sets the requested values of the datastore - - :param address: The starting address - :param values: The new values to be set - ''' - if isinstance(values, dict): - for idx, val in iteritems(values): - self.values[idx] = val - else: - if not isinstance(values, list): - values = [values] - for idx, val in enumerate(values): - self.values[address + idx] = val
-
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/device.html b/doc/sphinx/html/_modules/pymodbus/device.html deleted file mode 100644 index ce0d93f53..000000000 --- a/doc/sphinx/html/_modules/pymodbus/device.html +++ /dev/null @@ -1,712 +0,0 @@ - - - - - - - - pymodbus.device — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.device

-"""
-Modbus Device Controller
--------------------------
-
-These are the device management handlers.  They should be
-maintained in the server context and the various methods
-should be inserted in the correct locations.
-"""
-from pymodbus.constants import DeviceInformation
-from pymodbus.interfaces import Singleton
-from pymodbus.utilities import dict_property
-from pymodbus.compat import iteritems, itervalues, izip, int2byte
-
-from collections import OrderedDict
-
-#---------------------------------------------------------------------------#
-# Network Access Control
-#---------------------------------------------------------------------------#
-
[docs]class ModbusAccessControl(Singleton): - ''' - This is a simple implementation of a Network Management System table. - Its purpose is to control access to the server (if it is used). - We assume that if an entry is in the table, it is allowed accesses to - resources. However, if the host does not appear in the table (all - unknown hosts) its connection will simply be closed. - - Since it is a singleton, only one version can possible exist and all - instances pull from here. - ''' - __nmstable = [ - "127.0.0.1", - ] - -
[docs] def __iter__(self): - ''' Iterater over the network access table - - :returns: An iterator of the network access table - ''' - return self.__nmstable.__iter__()
- -
[docs] def __contains__(self, host): - ''' Check if a host is allowed to access resources - - :param host: The host to check - ''' - return host in self.__nmstable
- -
[docs] def add(self, host): - ''' Add allowed host(s) from the NMS table - - :param host: The host to add - ''' - if not isinstance(host, list): - host = [host] - for entry in host: - if entry not in self.__nmstable: - self.__nmstable.append(entry)
- -
[docs] def remove(self, host): - ''' Remove allowed host(s) from the NMS table - - :param host: The host to remove - ''' - if not isinstance(host, list): - host = [host] - for entry in host: - if entry in self.__nmstable: - self.__nmstable.remove(entry)
- -
[docs] def check(self, host): - ''' Check if a host is allowed to access resources - - :param host: The host to check - ''' - return host in self.__nmstable
- - -#---------------------------------------------------------------------------# -# Modbus Plus Statistics -#---------------------------------------------------------------------------# -
[docs]class ModbusPlusStatistics(object): - ''' - This is used to maintain the current modbus plus statistics count. As of - right now this is simply a stub to complete the modbus implementation. - For more information, see the modbus implementation guide page 87. - ''' - - __data = OrderedDict({ - 'node_type_id' : [0x00] * 2, # 00 - 'software_version_number' : [0x00] * 2, # 01 - 'network_address' : [0x00] * 2, # 02 - 'mac_state_variable' : [0x00] * 2, # 03 - 'peer_status_code' : [0x00] * 2, # 04 - 'token_pass_counter' : [0x00] * 2, # 05 - 'token_rotation_time' : [0x00] * 2, # 06 - - 'program_master_token_failed' : [0x00], # 07 hi - 'data_master_token_failed' : [0x00], # 07 lo - 'program_master_token_owner' : [0x00], # 08 hi - 'data_master_token_owner' : [0x00], # 08 lo - 'program_slave_token_owner' : [0x00], # 09 hi - 'data_slave_token_owner' : [0x00], # 09 lo - 'data_slave_command_transfer' : [0x00], # 10 hi - '__unused_10_lowbit' : [0x00], # 10 lo - - 'program_slave_command_transfer' : [0x00], # 11 hi - 'program_master_rsp_transfer' : [0x00], # 11 lo - 'program_slave_auto_logout' : [0x00], # 12 hi - 'program_master_connect_status' : [0x00], # 12 lo - 'receive_buffer_dma_overrun' : [0x00], # 13 hi - 'pretransmit_deferral_error' : [0x00], # 13 lo - 'frame_size_error' : [0x00], # 14 hi - 'repeated_command_received' : [0x00], # 14 lo - 'receiver_alignment_error' : [0x00], # 15 hi - 'receiver_collision_abort_error' : [0x00], # 15 lo - 'bad_packet_length_error' : [0x00], # 16 hi - 'receiver_crc_error' : [0x00], # 16 lo - 'transmit_buffer_dma_underrun' : [0x00], # 17 hi - 'bad_link_address_error' : [0x00], # 17 lo - - 'bad_mac_function_code_error' : [0x00], # 18 hi - 'internal_packet_length_error' : [0x00], # 18 lo - 'communication_failed_error' : [0x00], # 19 hi - 'communication_retries' : [0x00], # 19 lo - 'no_response_error' : [0x00], # 20 hi - 'good_receive_packet' : [0x00], # 20 lo - 'unexpected_path_error' : [0x00], # 21 hi - 'exception_response_error' : [0x00], # 21 lo - 'forgotten_transaction_error' : [0x00], # 22 hi - 'unexpected_response_error' : [0x00], # 22 lo - - 'active_station_bit_map' : [0x00] * 8, # 23-26 - 'token_station_bit_map' : [0x00] * 8, # 27-30 - 'global_data_bit_map' : [0x00] * 8, # 31-34 - 'receive_buffer_use_bit_map' : [0x00] * 8, # 35-37 - 'data_master_output_path' : [0x00] * 8, # 38-41 - 'data_slave_input_path' : [0x00] * 8, # 42-45 - 'program_master_outptu_path' : [0x00] * 8, # 46-49 - 'program_slave_input_path' : [0x00] * 8, # 50-53 - }) - -
[docs] def __init__(self): - ''' - Initialize the modbus plus statistics with the default - information. - ''' - self.reset()
- -
[docs] def __iter__(self): - ''' Iterater over the statistics - - :returns: An iterator of the modbus plus statistics - ''' - return iteritems(self.__data)
- -
[docs] def reset(self): - ''' This clears all of the modbus plus statistics - ''' - for key in self.__data: - self.__data[key] = [0x00] * len(self.__data[key])
- -
[docs] def summary(self): - ''' Returns a summary of the modbus plus statistics - - :returns: 54 16-bit words representing the status - ''' - return itervalues(self.__data)
- -
[docs] def encode(self): - ''' Returns a summary of the modbus plus statistics - - :returns: 54 16-bit words representing the status - ''' - total, values = [], sum(self.__data.values(), []) - for c in range(0, len(values), 2): - total.append((values[c] << 8) | values[c+1]) - return total
- - -#---------------------------------------------------------------------------# -# Device Information Control -#---------------------------------------------------------------------------# -
[docs]class ModbusDeviceIdentification(object): - ''' - This is used to supply the device identification - for the readDeviceIdentification function - - For more information read section 6.21 of the modbus - application protocol. - ''' - __data = { - 0x00: '', # VendorName - 0x01: '', # ProductCode - 0x02: '', # MajorMinorRevision - 0x03: '', # VendorUrl - 0x04: '', # ProductName - 0x05: '', # ModelName - 0x06: '', # UserApplicationName - 0x07: '', # reserved - 0x08: '', # reserved - # 0x80 -> 0xFF are private - } - - __names = [ - 'VendorName', - 'ProductCode', - 'MajorMinorRevision', - 'VendorUrl', - 'ProductName', - 'ModelName', - 'UserApplicationName', - ] - -
[docs] def __init__(self, info=None): - ''' - Initialize the datastore with the elements you need. - (note acceptable range is [0x00-0x06,0x80-0xFF] inclusive) - - :param information: A dictionary of {int:string} of values - ''' - if isinstance(info, dict): - for key in info: - if (0x06 >= key >= 0x00) or (0x80 > key > 0x08): - self.__data[key] = info[key]
- -
[docs] def __iter__(self): - ''' Iterater over the device information - - :returns: An iterator of the device information - ''' - return iteritems(self.__data)
- -
[docs] def summary(self): - ''' Return a summary of the main items - - :returns: An dictionary of the main items - ''' - return dict(zip(self.__names, itervalues(self.__data)))
- -
[docs] def update(self, value): - ''' Update the values of this identity - using another identify as the value - - :param value: The value to copy values from - ''' - self.__data.update(value)
- -
[docs] def __setitem__(self, key, value): - ''' Wrapper used to access the device information - - :param key: The register to set - :param value: The new value for referenced register - ''' - if key not in [0x07, 0x08]: - self.__data[key] = value
- -
[docs] def __getitem__(self, key): - ''' Wrapper used to access the device information - - :param key: The register to read - ''' - return self.__data.setdefault(key, '')
- -
[docs] def __str__(self): - ''' Build a representation of the device - - :returns: A string representation of the device - ''' - return "DeviceIdentity"
- - #-------------------------------------------------------------------------# - # Properties - #-------------------------------------------------------------------------# - VendorName = dict_property(lambda s: s.__data, 0) - ProductCode = dict_property(lambda s: s.__data, 1) - MajorMinorRevision = dict_property(lambda s: s.__data, 2) - VendorUrl = dict_property(lambda s: s.__data, 3) - ProductName = dict_property(lambda s: s.__data, 4) - ModelName = dict_property(lambda s: s.__data, 5) - UserApplicationName = dict_property(lambda s: s.__data, 6)
- - -
[docs]class DeviceInformationFactory(Singleton): - ''' This is a helper factory that really just hides - some of the complexity of processing the device information - requests (function code 0x2b 0x0e). - ''' - - __lookup = { - DeviceInformation.Basic: lambda c,r,i: c.__gets(r, list(range(0x00, 0x03))), - DeviceInformation.Regular: lambda c,r,i: c.__gets(r, list(range(0x00, 0x08))), - DeviceInformation.Extended: lambda c,r,i: c.__gets(r, list(range(0x80, i))), - DeviceInformation.Specific: lambda c,r,i: c.__get(r, i), - } - - @classmethod -
[docs] def get(cls, control, read_code=DeviceInformation.Basic, object_id=0x00): - ''' Get the requested device data from the system - - :param control: The control block to pull data from - :param read_code: The read code to process - :param object_id: The specific object_id to read - :returns: The requested data (id, length, value) - ''' - identity = control.Identity - return cls.__lookup[read_code](cls, identity, object_id)
- - @classmethod - def __get(cls, identity, object_id): - ''' Read a single object_id from the device information - - :param identity: The identity block to pull data from - :param object_id: The specific object id to read - :returns: The requested data (id, length, value) - ''' - return { object_id:identity[object_id] } - - @classmethod - def __gets(cls, identity, object_ids): - ''' Read multiple object_ids from the device information - - :param identity: The identity block to pull data from - :param object_ids: The specific object ids to read - :returns: The requested data (id, length, value) - ''' - return dict((oid, identity[oid]) for oid in object_ids)
- - -#---------------------------------------------------------------------------# -# Counters Handler -#---------------------------------------------------------------------------# -class ModbusCountersHandler(object): - ''' - This is a helper class to simplify the properties for the counters:: - - 0x0B 1 Return Bus Message Count - - Quantity of messages that the remote - device has detected on the communications system since its - last restart, clear counters operation, or power-up. Messages - with bad CRC are not taken into account. - - 0x0C 2 Return Bus Communication Error Count - - Quantity of CRC errors encountered by the remote device since its - last restart, clear counters operation, or power-up. In case of - an error detected on the character level, (overrun, parity error), - or in case of a message length < 3 bytes, the receiving device is - not able to calculate the CRC. In such cases, this counter is - also incremented. - - 0x0D 3 Return Slave Exception Error Count - - Quantity of MODBUS exception error detected by the remote device - since its last restart, clear counters operation, or power-up. It - comprises also the error detected in broadcast messages even if an - exception message is not returned in this case. - Exception errors are described and listed in "MODBUS Application - Protocol Specification" document. - - 0xOE 4 Return Slave Message Count - - Quantity of messages addressed to the remote device, including - broadcast messages, that the remote device has processed since its - last restart, clear counters operation, or power-up. - - 0x0F 5 Return Slave No Response Count - - Quantity of messages received by the remote device for which it - returned no response (neither a normal response nor an exception - response), since its last restart, clear counters operation, or - power-up. Then, this counter counts the number of broadcast - messages it has received. - - 0x10 6 Return Slave NAK Count - - Quantity of messages addressed to the remote device for which it - returned a Negative Acknowledge (NAK) exception response, since - its last restart, clear counters operation, or power-up. Exception - responses are described and listed in "MODBUS Application Protocol - Specification" document. - - 0x11 7 Return Slave Busy Count - - Quantity of messages addressed to the remote device for which it - returned a Slave Device Busy exception response, since its last - restart, clear counters operation, or power-up. Exception - responses are described and listed in "MODBUS Application - Protocol Specification" document. - - 0x12 8 Return Bus Character Overrun Count - - Quantity of messages addressed to the remote device that it could - not handle due to a character overrun condition, since its last - restart, clear counters operation, or power-up. A character - overrun is caused by data characters arriving at the port faster - than they can. - - .. note:: I threw the event counter in here for convinience - ''' - __data = dict([(i, 0x0000) for i in range(9)]) - __names = [ - 'BusMessage', - 'BusCommunicationError', - 'SlaveExceptionError', - 'SlaveMessage', - 'SlaveNoResponse', - 'SlaveNAK', - 'SlaveBusy', - 'BusCharacterOverrun' - 'Event ' - ] - - def __iter__(self): - ''' Iterater over the device counters - - :returns: An iterator of the device counters - ''' - return izip(self.__names, itervalues(self.__data)) - - def update(self, values): - ''' Update the values of this identity - using another identify as the value - - :param values: The value to copy values from - ''' - for k, v in iteritems(values): - v += self.__getattribute__(k) - self.__setattr__(k, v) - - def reset(self): - ''' This clears all of the system counters - ''' - self.__data = dict([(i, 0x0000) for i in range(9)]) - - def summary(self): - ''' Returns a summary of the counters current status - - :returns: A byte with each bit representing each counter - ''' - count, result = 0x01, 0x00 - for i in itervalues(self.__data): - if i != 0x00: result |= count - count <<= 1 - return result - - #-------------------------------------------------------------------------# - # Properties - #-------------------------------------------------------------------------# - BusMessage = dict_property(lambda s: s.__data, 0) - BusCommunicationError = dict_property(lambda s: s.__data, 1) - BusExceptionError = dict_property(lambda s: s.__data, 2) - SlaveMessage = dict_property(lambda s: s.__data, 3) - SlaveNoResponse = dict_property(lambda s: s.__data, 4) - SlaveNAK = dict_property(lambda s: s.__data, 5) - SlaveBusy = dict_property(lambda s: s.__data, 6) - BusCharacterOverrun = dict_property(lambda s: s.__data, 7) - Event = dict_property(lambda s: s.__data, 8) - - -#---------------------------------------------------------------------------# -# Main server controll block -#---------------------------------------------------------------------------# -
[docs]class ModbusControlBlock(Singleton): - ''' - This is a global singleotn that controls all system information - - All activity should be logged here and all diagnostic requests - should come from here. - ''' - - __mode = 'ASCII' - __diagnostic = [False] * 16 - __instance = None - __listen_only = False - __delimiter = '\r' - __counters = ModbusCountersHandler() - __identity = ModbusDeviceIdentification() - __plus = ModbusPlusStatistics() - __events = [] - - #-------------------------------------------------------------------------# - # Magic - #-------------------------------------------------------------------------# -
[docs] def __str__(self): - ''' Build a representation of the control block - - :returns: A string representation of the control block - ''' - return "ModbusControl"
- -
[docs] def __iter__(self): - ''' Iterater over the device counters - - :returns: An iterator of the device counters - ''' - return self.__counters.__iter__()
- - #-------------------------------------------------------------------------# - # Events - #-------------------------------------------------------------------------# -
[docs] def addEvent(self, event): - ''' Adds a new event to the event log - - :param event: A new event to add to the log - ''' - self.__events.insert(0, event) - self.__events = self.__events[0:64] # chomp to 64 entries - self.Counter.Event += 1
- -
[docs] def getEvents(self): - ''' Returns an encoded collection of the event log. - - :returns: The encoded events packet - ''' - events = [event.encode() for event in self.__events] - return b''.join(events)
- -
[docs] def clearEvents(self): - ''' Clears the current list of events - ''' - self.__events = []
- - #-------------------------------------------------------------------------# - # Other Properties - #-------------------------------------------------------------------------# - Identity = property(lambda s: s.__identity) - Counter = property(lambda s: s.__counters) - Events = property(lambda s: s.__events) - Plus = property(lambda s: s.__plus) - -
[docs] def reset(self): - ''' This clears all of the system counters and the - diagnostic register - ''' - self.__events = [] - self.__counters.reset() - self.__diagnostic = [False] * 16
- - #-------------------------------------------------------------------------# - # Listen Properties - #-------------------------------------------------------------------------# -
[docs] def _setListenOnly(self, value): - ''' This toggles the listen only status - - :param value: The value to set the listen status to - ''' - self.__listen_only = bool(value)
- - ListenOnly = property(lambda s: s.__listen_only, _setListenOnly) - - #-------------------------------------------------------------------------# - # Mode Properties - #-------------------------------------------------------------------------# -
[docs] def _setMode(self, mode): - ''' This toggles the current serial mode - - :param mode: The data transfer method in (RTU, ASCII) - ''' - if mode in ['ASCII', 'RTU']: - self.__mode = mode
- - Mode = property(lambda s: s.__mode, _setMode) - - #-------------------------------------------------------------------------# - # Delimiter Properties - #-------------------------------------------------------------------------# -
[docs] def _setDelimiter(self, char): - ''' This changes the serial delimiter character - - :param char: The new serial delimiter character - ''' - if isinstance(char, str): - self.__delimiter = char.encode() - if isinstance(char, bytes): - self.__delimiter = char - elif isinstance(char, int): - self.__delimiter = int2byte(char)
- - Delimiter = property(lambda s: s.__delimiter, _setDelimiter) - - #-------------------------------------------------------------------------# - # Diagnostic Properties - #-------------------------------------------------------------------------# -
[docs] def setDiagnostic(self, mapping): - ''' This sets the value in the diagnostic register - - :param mapping: Dictionary of key:value pairs to set - ''' - for entry in iteritems(mapping): - if entry[0] >= 0 and entry[0] < len(self.__diagnostic): - self.__diagnostic[entry[0]] = (entry[1] != 0)
- -
[docs] def getDiagnostic(self, bit): - ''' This gets the value in the diagnostic register - - :param bit: The bit to get - :returns: The current value of the requested bit - ''' - try: - if bit and bit >= 0 and bit < len(self.__diagnostic): - return self.__diagnostic[bit] - except Exception: - return None
- -
[docs] def getDiagnosticRegister(self): - ''' This gets the entire diagnostic register - - :returns: The diagnostic register collection - ''' - return self.__diagnostic
- -#---------------------------------------------------------------------------# -# Exported Identifiers -#---------------------------------------------------------------------------# -__all__ = [ - "ModbusAccessControl", - "ModbusPlusStatistics", - "ModbusDeviceIdentification", - "DeviceInformationFactory", - "ModbusControlBlock" -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/diag_message.html b/doc/sphinx/html/_modules/pymodbus/diag_message.html deleted file mode 100644 index b706258af..000000000 --- a/doc/sphinx/html/_modules/pymodbus/diag_message.html +++ /dev/null @@ -1,845 +0,0 @@ - - - - - - - - pymodbus.diag_message — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.diag_message

-'''
-Diagnostic Record Read/Write
-------------------------------
-
-These need to be tied into a the current server context
-or linked to the appropriate data
-'''
-import struct
-
-from pymodbus.constants import ModbusStatus, ModbusPlusOperation
-from pymodbus.pdu import ModbusRequest
-from pymodbus.pdu import ModbusResponse
-from pymodbus.device import ModbusControlBlock
-from pymodbus.exceptions import NotImplementedException
-from pymodbus.utilities import pack_bitstring
-
-_MCB = ModbusControlBlock()
-
-
-#---------------------------------------------------------------------------#
-# Diagnostic Function Codes Base Classes
-# diagnostic 08, 00-18,20
-#---------------------------------------------------------------------------#
-# TODO Make sure all the data is decoded from the response
-#---------------------------------------------------------------------------#
-
[docs]class DiagnosticStatusRequest(ModbusRequest): - ''' - This is a base class for all of the diagnostic request functions - ''' - function_code = 0x08 - _rtu_frame_size = 8 - -
[docs] def __init__(self, **kwargs): - ''' - Base initializer for a diagnostic request - ''' - ModbusRequest.__init__(self, **kwargs) - self.message = None
- -
[docs] def encode(self): - ''' - Base encoder for a diagnostic response - we encode the data set in self.message - - :returns: The encoded packet - ''' - packet = struct.pack('>H', self.sub_function_code) - if self.message is not None: - if isinstance(self.message, str): - packet += self.message.encode() - elif isinstance(self.message, bytes): - packet += self.message - elif isinstance(self.message, list): - for piece in self.message: - packet += struct.pack('>H', piece) - elif isinstance(self.message, int): - packet += struct.pack('>H', self.message) - return packet
- -
[docs] def decode(self, data): - ''' Base decoder for a diagnostic request - - :param data: The data to decode into the function code - ''' - self.sub_function_code, self.message = struct.unpack('>HH', data)
- -
[docs] def get_response_pdu_size(self): - """ - Func_code (1 byte) + Sub function code (2 byte) + Data (2 * N bytes) - :return: - """ - if not isinstance(self.message,list): - self.message = [self.message] - return 1 + 2 + 2 * len(self.message)
- - - -
[docs]class DiagnosticStatusResponse(ModbusResponse): - ''' - This is a base class for all of the diagnostic response functions - - It works by performing all of the encoding and decoding of variable - data and lets the higher classes define what extra data to append - and how to execute a request - ''' - function_code = 0x08 - _rtu_frame_size = 8 - -
[docs] def __init__(self, **kwargs): - ''' - Base initializer for a diagnostic response - ''' - ModbusResponse.__init__(self, **kwargs) - self.message = None
- -
[docs] def encode(self): - ''' - Base encoder for a diagnostic response - we encode the data set in self.message - - :returns: The encoded packet - ''' - packet = struct.pack('>H', self.sub_function_code) - if self.message is not None: - if isinstance(self.message, str): - packet += self.message.encode() - elif isinstance(self.message, bytes): - packet += self.message - elif isinstance(self.message, list): - for piece in self.message: - packet += struct.pack('>H', piece) - elif isinstance(self.message, int): - packet += struct.pack('>H', self.message) - return packet
- -
[docs] def decode(self, data): - ''' Base decoder for a diagnostic response - - :param data: The data to decode into the function code - ''' - self.sub_function_code, self.message = struct.unpack('>HH', data)
- - -
[docs]class DiagnosticStatusSimpleRequest(DiagnosticStatusRequest): - ''' - A large majority of the diagnostic functions are simple - status request functions. They work by sending 0x0000 - as data and their function code and they are returned - 2 bytes of data. - - If a function inherits this, they only need to implement - the execute method - ''' - -
[docs] def __init__(self, data=0x0000, **kwargs): - ''' - General initializer for a simple diagnostic request - - The data defaults to 0x0000 if not provided as over half - of the functions require it. - - :param data: The data to send along with the request - ''' - DiagnosticStatusRequest.__init__(self, **kwargs) - self.message = data
- -
[docs] def execute(self, *args): - ''' Base function to raise if not implemented ''' - raise NotImplementedException("Diagnostic Message Has No Execute Method")
- - -
[docs]class DiagnosticStatusSimpleResponse(DiagnosticStatusResponse): - ''' - A large majority of the diagnostic functions are simple - status request functions. They work by sending 0x0000 - as data and their function code and they are returned - 2 bytes of data. - ''' - -
[docs] def __init__(self, data=0x0000, **kwargs): - ''' General initializer for a simple diagnostic response - - :param data: The resulting data to return to the client - ''' - DiagnosticStatusResponse.__init__(self, **kwargs) - self.message = data
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 00 -#---------------------------------------------------------------------------# -
[docs]class ReturnQueryDataRequest(DiagnosticStatusRequest): - ''' - The data passed in the request data field is to be returned (looped back) - in the response. The entire response message should be identical to the - request. - ''' - sub_function_code = 0x0000 - -
[docs] def __init__(self, message=0x0000, **kwargs): - ''' Initializes a new instance of the request - - :param message: The message to send to loopback - ''' - DiagnosticStatusRequest.__init__(self, **kwargs) - if isinstance(message, list): - self.message = message - else: - self.message = [message]
- -
[docs] def execute(self, *args): - ''' Executes the loopback request (builds the response) - - :returns: The populated loopback response message - ''' - return ReturnQueryDataResponse(self.message)
- - -
[docs]class ReturnQueryDataResponse(DiagnosticStatusResponse): - ''' - The data passed in the request data field is to be returned (looped back) - in the response. The entire response message should be identical to the - request. - ''' - sub_function_code = 0x0000 - -
[docs] def __init__(self, message=0x0000, **kwargs): - ''' Initializes a new instance of the response - - :param message: The message to loopback - ''' - DiagnosticStatusResponse.__init__(self, **kwargs) - if isinstance(message, list): - self.message = message - else: self.message = [message]
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 01 -#---------------------------------------------------------------------------# -
[docs]class RestartCommunicationsOptionRequest(DiagnosticStatusRequest): - ''' - The remote device serial line port must be initialized and restarted, and - all of its communications event counters are cleared. If the port is - currently in Listen Only Mode, no response is returned. This function is - the only one that brings the port out of Listen Only Mode. If the port is - not currently in Listen Only Mode, a normal response is returned. This - occurs before the restart is executed. - ''' - sub_function_code = 0x0001 - -
[docs] def __init__(self, toggle=False, **kwargs): - ''' Initializes a new request - - :param toggle: Set to True to toggle, False otherwise - ''' - DiagnosticStatusRequest.__init__(self, **kwargs) - if toggle: - self.message = [ModbusStatus.On] - else: self.message = [ModbusStatus.Off]
- -
[docs] def execute(self, *args): - ''' Clear event log and restart - - :returns: The initialized response message - ''' - #if _MCB.ListenOnly: - return RestartCommunicationsOptionResponse(self.message)
- -
[docs]class RestartCommunicationsOptionResponse(DiagnosticStatusResponse): - ''' - The remote device serial line port must be initialized and restarted, and - all of its communications event counters are cleared. If the port is - currently in Listen Only Mode, no response is returned. This function is - the only one that brings the port out of Listen Only Mode. If the port is - not currently in Listen Only Mode, a normal response is returned. This - occurs before the restart is executed. - ''' - sub_function_code = 0x0001 - -
[docs] def __init__(self, toggle=False, **kwargs): - ''' Initializes a new response - - :param toggle: Set to True if we toggled, False otherwise - ''' - DiagnosticStatusResponse.__init__(self, **kwargs) - if toggle: - self.message = [ModbusStatus.On] - else: self.message = [ModbusStatus.Off]
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 02 -#---------------------------------------------------------------------------# -
[docs]class ReturnDiagnosticRegisterRequest(DiagnosticStatusSimpleRequest): - ''' - The contents of the remote device's 16-bit diagnostic register are - returned in the response - ''' - sub_function_code = 0x0002 - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - #if _MCB.isListenOnly(): - register = pack_bitstring(_MCB.getDiagnosticRegister()) - return ReturnDiagnosticRegisterResponse(register)
- - -
[docs]class ReturnDiagnosticRegisterResponse(DiagnosticStatusSimpleResponse): - ''' - The contents of the remote device's 16-bit diagnostic register are - returned in the response - ''' - sub_function_code = 0x0002
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 03 -#---------------------------------------------------------------------------# -
[docs]class ChangeAsciiInputDelimiterRequest(DiagnosticStatusSimpleRequest): - ''' - The character 'CHAR' passed in the request data field becomes the end of - message delimiter for future messages (replacing the default LF - character). This function is useful in cases of a Line Feed is not - required at the end of ASCII messages. - ''' - sub_function_code = 0x0003 - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - char = (self.message & 0xff00) >> 8 - _MCB.Delimiter = char - return ChangeAsciiInputDelimiterResponse(self.message)
- - -
[docs]class ChangeAsciiInputDelimiterResponse(DiagnosticStatusSimpleResponse): - ''' - The character 'CHAR' passed in the request data field becomes the end of - message delimiter for future messages (replacing the default LF - character). This function is useful in cases of a Line Feed is not - required at the end of ASCII messages. - ''' - sub_function_code = 0x0003
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 04 -#---------------------------------------------------------------------------# -
[docs]class ForceListenOnlyModeRequest(DiagnosticStatusSimpleRequest): - ''' - Forces the addressed remote device to its Listen Only Mode for MODBUS - communications. This isolates it from the other devices on the network, - allowing them to continue communicating without interruption from the - addressed remote device. No response is returned. - ''' - sub_function_code = 0x0004 - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - _MCB.ListenOnly = True - return ForceListenOnlyModeResponse()
- - -
[docs]class ForceListenOnlyModeResponse(DiagnosticStatusResponse): - ''' - Forces the addressed remote device to its Listen Only Mode for MODBUS - communications. This isolates it from the other devices on the network, - allowing them to continue communicating without interruption from the - addressed remote device. No response is returned. - - This does not send a response - ''' - sub_function_code = 0x0004 - should_respond = False - -
[docs] def __init__(self, **kwargs): - ''' Initializer to block a return response - ''' - DiagnosticStatusResponse.__init__(self, **kwargs) - self.message = []
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 10 -#---------------------------------------------------------------------------# -
[docs]class ClearCountersRequest(DiagnosticStatusSimpleRequest): - ''' - The goal is to clear ll counters and the diagnostic register. - Also, counters are cleared upon power-up - ''' - sub_function_code = 0x000A - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - _MCB.reset() - return ClearCountersResponse(self.message)
- - -
[docs]class ClearCountersResponse(DiagnosticStatusSimpleResponse): - ''' - The goal is to clear ll counters and the diagnostic register. - Also, counters are cleared upon power-up - ''' - sub_function_code = 0x000A
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 11 -#---------------------------------------------------------------------------# -
[docs]class ReturnBusMessageCountRequest(DiagnosticStatusSimpleRequest): - ''' - The response data field returns the quantity of messages that the - remote device has detected on the communications systems since its last - restart, clear counters operation, or power-up - ''' - sub_function_code = 0x000B - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - count = _MCB.Counter.BusMessage - return ReturnBusMessageCountResponse(count)
- - -
[docs]class ReturnBusMessageCountResponse(DiagnosticStatusSimpleResponse): - ''' - The response data field returns the quantity of messages that the - remote device has detected on the communications systems since its last - restart, clear counters operation, or power-up - ''' - sub_function_code = 0x000B
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 12 -#---------------------------------------------------------------------------# -
[docs]class ReturnBusCommunicationErrorCountRequest(DiagnosticStatusSimpleRequest): - ''' - The response data field returns the quantity of CRC errors encountered - by the remote device since its last restart, clear counter operation, or - power-up - ''' - sub_function_code = 0x000C - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - count = _MCB.Counter.BusCommunicationError - return ReturnBusCommunicationErrorCountResponse(count)
- - -
[docs]class ReturnBusCommunicationErrorCountResponse(DiagnosticStatusSimpleResponse): - ''' - The response data field returns the quantity of CRC errors encountered - by the remote device since its last restart, clear counter operation, or - power-up - ''' - sub_function_code = 0x000C
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 13 -#---------------------------------------------------------------------------# -
[docs]class ReturnBusExceptionErrorCountRequest(DiagnosticStatusSimpleRequest): - ''' - The response data field returns the quantity of modbus exception - responses returned by the remote device since its last restart, - clear counters operation, or power-up - ''' - sub_function_code = 0x000D - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - count = _MCB.Counter.BusExceptionError - return ReturnBusExceptionErrorCountResponse(count)
- - -
[docs]class ReturnBusExceptionErrorCountResponse(DiagnosticStatusSimpleResponse): - ''' - The response data field returns the quantity of modbus exception - responses returned by the remote device since its last restart, - clear counters operation, or power-up - ''' - sub_function_code = 0x000D
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 14 -#---------------------------------------------------------------------------# -
[docs]class ReturnSlaveMessageCountRequest(DiagnosticStatusSimpleRequest): - ''' - The response data field returns the quantity of messages addressed to the - remote device, or broadcast, that the remote device has processed since - its last restart, clear counters operation, or power-up - ''' - sub_function_code = 0x000E - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - count = _MCB.Counter.SlaveMessage - return ReturnSlaveMessageCountResponse(count)
- - -
[docs]class ReturnSlaveMessageCountResponse(DiagnosticStatusSimpleResponse): - ''' - The response data field returns the quantity of messages addressed to the - remote device, or broadcast, that the remote device has processed since - its last restart, clear counters operation, or power-up - ''' - sub_function_code = 0x000E
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 15 -#---------------------------------------------------------------------------# -
[docs]class ReturnSlaveNoResponseCountRequest(DiagnosticStatusSimpleRequest): - ''' - The response data field returns the quantity of messages addressed to the - remote device, or broadcast, that the remote device has processed since - its last restart, clear counters operation, or power-up - ''' - sub_function_code = 0x000F - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - count = _MCB.Counter.SlaveNoResponse - return ReturnSlaveNoReponseCountResponse(count)
- - -
[docs]class ReturnSlaveNoReponseCountResponse(DiagnosticStatusSimpleResponse): - ''' - The response data field returns the quantity of messages addressed to the - remote device, or broadcast, that the remote device has processed since - its last restart, clear counters operation, or power-up - ''' - sub_function_code = 0x000F
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 16 -#---------------------------------------------------------------------------# -
[docs]class ReturnSlaveNAKCountRequest(DiagnosticStatusSimpleRequest): - ''' - The response data field returns the quantity of messages addressed to the - remote device for which it returned a Negative Acknowledge (NAK) exception - response, since its last restart, clear counters operation, or power-up. - Exception responses are described and listed in section 7 . - ''' - sub_function_code = 0x0010 - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - count = _MCB.Counter.SlaveNAK - return ReturnSlaveNAKCountResponse(count)
- - -
[docs]class ReturnSlaveNAKCountResponse(DiagnosticStatusSimpleResponse): - ''' - The response data field returns the quantity of messages addressed to the - remote device for which it returned a Negative Acknowledge (NAK) exception - response, since its last restart, clear counters operation, or power-up. - Exception responses are described and listed in section 7. - ''' - sub_function_code = 0x0010
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 17 -#---------------------------------------------------------------------------# -
[docs]class ReturnSlaveBusyCountRequest(DiagnosticStatusSimpleRequest): - ''' - The response data field returns the quantity of messages addressed to the - remote device for which it returned a Slave Device Busy exception response, - since its last restart, clear counters operation, or power-up. - ''' - sub_function_code = 0x0011 - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - count = _MCB.Counter.SlaveBusy - return ReturnSlaveBusyCountResponse(count)
- - -
[docs]class ReturnSlaveBusyCountResponse(DiagnosticStatusSimpleResponse): - ''' - The response data field returns the quantity of messages addressed to the - remote device for which it returned a Slave Device Busy exception response, - since its last restart, clear counters operation, or power-up. - ''' - sub_function_code = 0x0011
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 18 -#---------------------------------------------------------------------------# -
[docs]class ReturnSlaveBusCharacterOverrunCountRequest(DiagnosticStatusSimpleRequest): - ''' - The response data field returns the quantity of messages addressed to the - remote device that it could not handle due to a character overrun condition, - since its last restart, clear counters operation, or power-up. A character - overrun is caused by data characters arriving at the port faster than they - can be stored, or by the loss of a character due to a hardware malfunction. - ''' - sub_function_code = 0x0012 - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - count = _MCB.Counter.BusCharacterOverrun - return ReturnSlaveBusCharacterOverrunCountResponse(count)
- - -
[docs]class ReturnSlaveBusCharacterOverrunCountResponse(DiagnosticStatusSimpleResponse): - ''' - The response data field returns the quantity of messages addressed to the - remote device that it could not handle due to a character overrun condition, - since its last restart, clear counters operation, or power-up. A character - overrun is caused by data characters arriving at the port faster than they - can be stored, or by the loss of a character due to a hardware malfunction. - ''' - sub_function_code = 0x0012
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 19 -#---------------------------------------------------------------------------# -
[docs]class ReturnIopOverrunCountRequest(DiagnosticStatusSimpleRequest): - ''' - An IOP overrun is caused by data characters arriving at the port - faster than they can be stored, or by the loss of a character due - to a hardware malfunction. This function is specific to the 884. - ''' - sub_function_code = 0x0013 - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - count = _MCB.Counter.BusCharacterOverrun - return ReturnIopOverrunCountResponse(count)
- - -
[docs]class ReturnIopOverrunCountResponse(DiagnosticStatusSimpleResponse): - ''' - The response data field returns the quantity of messages - addressed to the slave that it could not handle due to an 884 - IOP overrun condition, since its last restart, clear counters - operation, or power-up. - ''' - sub_function_code = 0x0013
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 20 -#---------------------------------------------------------------------------# -
[docs]class ClearOverrunCountRequest(DiagnosticStatusSimpleRequest): - ''' - Clears the overrun error counter and reset the error flag - - An error flag should be cleared, but nothing else in the - specification mentions is, so it is ignored. - ''' - sub_function_code = 0x0014 - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - _MCB.Counter.BusCharacterOverrun = 0x0000 - return ClearOverrunCountResponse(self.message)
- - -
[docs]class ClearOverrunCountResponse(DiagnosticStatusSimpleResponse): - ''' - Clears the overrun error counter and reset the error flag - ''' - sub_function_code = 0x0014
- - -#---------------------------------------------------------------------------# -# Diagnostic Sub Code 21 -#---------------------------------------------------------------------------# -
[docs]class GetClearModbusPlusRequest(DiagnosticStatusSimpleRequest): - ''' - In addition to the Function code (08) and Subfunction code - (00 15 hex) in the query, a two-byte Operation field is used - to specify either a 'Get Statistics' or a 'Clear Statistics' - operation. The two operations are exclusive - the 'Get' - operation cannot clear the statistics, and the 'Clear' - operation does not return statistics prior to clearing - them. Statistics are also cleared on power-up of the slave - device. - ''' - sub_function_code = 0x0015 - -
[docs] def execute(self, *args): - ''' Execute the diagnostic request on the given device - - :returns: The initialized response message - ''' - message = None # the clear operation does not return info - if self.message == ModbusPlusOperation.ClearStatistics: - _MCB.Plus.reset() - else: message = _MCB.Plus.encode() - return GetClearModbusPlusResponse(message)
- - -
[docs]class GetClearModbusPlusResponse(DiagnosticStatusSimpleResponse): - ''' - Returns a series of 54 16-bit words (108 bytes) in the data field - of the response (this function differs from the usual two-byte - length of the data field). The data contains the statistics for - the Modbus Plus peer processor in the slave device. - ''' - sub_function_code = 0x0015
- - -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "DiagnosticStatusRequest", "DiagnosticStatusResponse", - "ReturnQueryDataRequest", "ReturnQueryDataResponse", - "RestartCommunicationsOptionRequest", "RestartCommunicationsOptionResponse", - "ReturnDiagnosticRegisterRequest", "ReturnDiagnosticRegisterResponse", - "ChangeAsciiInputDelimiterRequest", "ChangeAsciiInputDelimiterResponse", - "ForceListenOnlyModeRequest", "ForceListenOnlyModeResponse", - "ClearCountersRequest", "ClearCountersResponse", - "ReturnBusMessageCountRequest", "ReturnBusMessageCountResponse", - "ReturnBusCommunicationErrorCountRequest", "ReturnBusCommunicationErrorCountResponse", - "ReturnBusExceptionErrorCountRequest", "ReturnBusExceptionErrorCountResponse", - "ReturnSlaveMessageCountRequest", "ReturnSlaveMessageCountResponse", - "ReturnSlaveNoResponseCountRequest", "ReturnSlaveNoReponseCountResponse", - "ReturnSlaveNAKCountRequest", "ReturnSlaveNAKCountResponse", - "ReturnSlaveBusyCountRequest", "ReturnSlaveBusyCountResponse", - "ReturnSlaveBusCharacterOverrunCountRequest", "ReturnSlaveBusCharacterOverrunCountResponse", - "ReturnIopOverrunCountRequest", "ReturnIopOverrunCountResponse", - "ClearOverrunCountRequest", "ClearOverrunCountResponse", - "GetClearModbusPlusRequest", "GetClearModbusPlusResponse", -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/events.html b/doc/sphinx/html/_modules/pymodbus/events.html deleted file mode 100644 index 1b3a1f593..000000000 --- a/doc/sphinx/html/_modules/pymodbus/events.html +++ /dev/null @@ -1,287 +0,0 @@ - - - - - - - - pymodbus.events — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.events

-'''
-Modbus Remote Events
-------------------------------------------------------------
-
-An event byte returned by the Get Communications Event Log function
-can be any one of four types. The type is defined by bit 7
-(the high-order bit) in each byte. It may be further defined by bit 6.
-'''
-from pymodbus.exceptions import NotImplementedException
-from pymodbus.exceptions import ParameterException
-from pymodbus.utilities import pack_bitstring, unpack_bitstring
-
-
-
[docs]class ModbusEvent(object): - -
[docs] def encode(self): - ''' Encodes the status bits to an event message - - :returns: The encoded event message - ''' - raise NotImplementedException()
- -
[docs] def decode(self, event): - ''' Decodes the event message to its status bits - - :param event: The event to decode - ''' - raise NotImplementedException()
- - -
[docs]class RemoteReceiveEvent(ModbusEvent): - ''' Remote device MODBUS Receive Event - - The remote device stores this type of event byte when a query message - is received. It is stored before the remote device processes the message. - This event is defined by bit 7 set to logic '1'. The other bits will be - set to a logic '1' if the corresponding condition is TRUE. The bit layout - is:: - - Bit Contents - ---------------------------------- - 0 Not Used - 2 Not Used - 3 Not Used - 4 Character Overrun - 5 Currently in Listen Only Mode - 6 Broadcast Receive - 7 1 - ''' - -
[docs] def __init__(self, **kwargs): - ''' Initialize a new event instance - ''' - self.overrun = kwargs.get('overrun', False) - self.listen = kwargs.get('listen', False) - self.broadcast = kwargs.get('broadcast', False)
- -
[docs] def encode(self): - ''' Encodes the status bits to an event message - - :returns: The encoded event message - ''' - bits = [False] * 3 - bits += [self.overrun, self.listen, self.broadcast, True] - packet = pack_bitstring(bits) - return packet
- -
[docs] def decode(self, event): - ''' Decodes the event message to its status bits - - :param event: The event to decode - ''' - bits = unpack_bitstring(event) - self.overrun = bits[4] - self.listen = bits[5] - self.broadcast = bits[6]
- - -
[docs]class RemoteSendEvent(ModbusEvent): - ''' Remote device MODBUS Send Event - - The remote device stores this type of event byte when it finishes - processing a request message. It is stored if the remote device - returned a normal or exception response, or no response. - - This event is defined by bit 7 set to a logic '0', with bit 6 set to a '1'. - The other bits will be set to a logic '1' if the corresponding - condition is TRUE. The bit layout is:: - - Bit Contents - ----------------------------------------------------------- - 0 Read Exception Sent (Exception Codes 1-3) - 1 Slave Abort Exception Sent (Exception Code 4) - 2 Slave Busy Exception Sent (Exception Codes 5-6) - 3 Slave Program NAK Exception Sent (Exception Code 7) - 4 Write Timeout Error Occurred - 5 Currently in Listen Only Mode - 6 1 - 7 0 - ''' - -
[docs] def __init__(self, **kwargs): - ''' Initialize a new event instance - ''' - self.read = kwargs.get('read', False) - self.slave_abort = kwargs.get('slave_abort', False) - self.slave_busy = kwargs.get('slave_busy', False) - self.slave_nak = kwargs.get('slave_nak', False) - self.write_timeout = kwargs.get('write_timeout', False) - self.listen = kwargs.get('listen', False)
- -
[docs] def encode(self): - ''' Encodes the status bits to an event message - - :returns: The encoded event message - ''' - bits = [self.read, self.slave_abort, self.slave_busy, - self.slave_nak, self.write_timeout, self.listen] - bits += [True, False] - packet = pack_bitstring(bits) - return packet
- -
[docs] def decode(self, event): - ''' Decodes the event message to its status bits - - :param event: The event to decode - ''' - # todo fix the start byte count - bits = unpack_bitstring(event) - self.read = bits[0] - self.slave_abort = bits[1] - self.slave_busy = bits[2] - self.slave_nak = bits[3] - self.write_timeout = bits[4] - self.listen = bits[5]
- - -
[docs]class EnteredListenModeEvent(ModbusEvent): - ''' Remote device Entered Listen Only Mode - - The remote device stores this type of event byte when it enters - the Listen Only Mode. The event is defined by a content of 04 hex. - ''' - - value = 0x04 - __encoded = b'\x04' - -
[docs] def encode(self): - ''' Encodes the status bits to an event message - - :returns: The encoded event message - ''' - return self.__encoded
- -
[docs] def decode(self, event): - ''' Decodes the event message to its status bits - - :param event: The event to decode - ''' - if event != self.__encoded: - raise ParameterException('Invalid decoded value')
- - -
[docs]class CommunicationRestartEvent(ModbusEvent): - ''' Remote device Initiated Communication Restart - - The remote device stores this type of event byte when its communications - port is restarted. The remote device can be restarted by the Diagnostics - function (code 08), with sub-function Restart Communications Option - (code 00 01). - - That function also places the remote device into a 'Continue on Error' - or 'Stop on Error' mode. If the remote device is placed into 'Continue on - Error' mode, the event byte is added to the existing event log. If the - remote device is placed into 'Stop on Error' mode, the byte is added to - the log and the rest of the log is cleared to zeros. - - The event is defined by a content of zero. - ''' - - value = 0x00 - __encoded = b'\x00' - -
[docs] def encode(self): - ''' Encodes the status bits to an event message - - :returns: The encoded event message - ''' - return self.__encoded
- -
[docs] def decode(self, event): - ''' Decodes the event message to its status bits - - :param event: The event to decode - ''' - if event != self.__encoded: - raise ParameterException('Invalid decoded value')
-
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/exceptions.html b/doc/sphinx/html/_modules/pymodbus/exceptions.html deleted file mode 100644 index eafc77a48..000000000 --- a/doc/sphinx/html/_modules/pymodbus/exceptions.html +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - - pymodbus.exceptions — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.exceptions

-'''
-Pymodbus Exceptions
---------------------
-
-Custom exceptions to be used in the Modbus code.
-'''
-
-
-
[docs]class ModbusException(Exception): - ''' Base modbus exception ''' - -
[docs] def __init__(self, string): - ''' Initialize the exception - :param string: The message to append to the error - ''' - self.string = string
- - def __str__(self): - return 'Modbus Error: %s' % self.string
- - -
[docs]class ModbusIOException(ModbusException): - ''' Error resulting from data i/o ''' - -
[docs] def __init__(self, string=""): - ''' Initialize the exception - :param string: The message to append to the error - ''' - message = "[Input/Output] %s" % string - ModbusException.__init__(self, message)
- - -
[docs]class ParameterException(ModbusException): - ''' Error resulting from invalid parameter ''' - -
[docs] def __init__(self, string=""): - ''' Initialize the exception - - :param string: The message to append to the error - ''' - message = "[Invalid Parameter] %s" % string - ModbusException.__init__(self, message)
- - -class NoSuchSlaveException(ModbusException): - ''' Error resulting from making a request to a slave - that does not exist ''' - - def __init__(self, string=""): - ''' Initialize the exception - - :param string: The message to append to the error - ''' - message = "[No Such Slave] %s" % string - ModbusException.__init__(self, message) - - -
[docs]class NotImplementedException(ModbusException): - ''' Error resulting from not implemented function ''' - -
[docs] def __init__(self, string=""): - ''' Initialize the exception - :param string: The message to append to the error - ''' - message = "[Not Implemented] %s" % string - ModbusException.__init__(self, message)
- - -class ConnectionException(ModbusException): - ''' Error resulting from a bad connection ''' - - def __init__(self, string=""): - ''' Initialize the exception - - :param string: The message to append to the error - ''' - message = "[Connection] %s" % string - ModbusException.__init__(self, message) - -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "ModbusException", "ModbusIOException", - "ParameterException", "NotImplementedException", - "ConnectionException", "NoSuchSlaveException", -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/factory.html b/doc/sphinx/html/_modules/pymodbus/factory.html deleted file mode 100644 index cfffdf5d4..000000000 --- a/doc/sphinx/html/_modules/pymodbus/factory.html +++ /dev/null @@ -1,347 +0,0 @@ - - - - - - - - pymodbus.factory — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.factory

-"""
-Modbus Request/Response Decoder Factories
--------------------------------------------
-
-The following factories make it easy to decode request/response messages.
-To add a new request/response pair to be decodeable by the library, simply
-add them to the respective function lookup table (order doesn't matter, but
-it does help keep things organized).
-
-Regardless of how many functions are added to the lookup, O(1) behavior is
-kept as a result of a pre-computed lookup dictionary.
-"""
-
-from pymodbus.pdu import IllegalFunctionRequest
-from pymodbus.pdu import ExceptionResponse
-from pymodbus.pdu import ModbusExceptions as ecode
-from pymodbus.interfaces import IModbusDecoder
-from pymodbus.exceptions import ModbusException
-from pymodbus.bit_read_message import *
-from pymodbus.bit_write_message import *
-from pymodbus.diag_message import *
-from pymodbus.file_message import *
-from pymodbus.other_message import *
-from pymodbus.mei_message import *
-from pymodbus.register_read_message import *
-from pymodbus.register_write_message import *
-from pymodbus.compat import byte2int
-
-#---------------------------------------------------------------------------#
-# Logging
-#---------------------------------------------------------------------------#
-import logging
-_logger = logging.getLogger(__name__)
-
-
-#---------------------------------------------------------------------------#
-# Server Decoder
-#---------------------------------------------------------------------------#
-
[docs]class ServerDecoder(IModbusDecoder): - ''' Request Message Factory (Server) - - To add more implemented functions, simply add them to the list - ''' - __function_table = [ - ReadHoldingRegistersRequest, - ReadDiscreteInputsRequest, - ReadInputRegistersRequest, - ReadCoilsRequest, - WriteMultipleCoilsRequest, - WriteMultipleRegistersRequest, - WriteSingleRegisterRequest, - WriteSingleCoilRequest, - ReadWriteMultipleRegistersRequest, - - DiagnosticStatusRequest, - - ReadExceptionStatusRequest, - GetCommEventCounterRequest, - GetCommEventLogRequest, - ReportSlaveIdRequest, - - ReadFileRecordRequest, - WriteFileRecordRequest, - MaskWriteRegisterRequest, - ReadFifoQueueRequest, - - ReadDeviceInformationRequest, - ] - __sub_function_table = [ - ReturnQueryDataRequest, - RestartCommunicationsOptionRequest, - ReturnDiagnosticRegisterRequest, - ChangeAsciiInputDelimiterRequest, - ForceListenOnlyModeRequest, - ClearCountersRequest, - ReturnBusMessageCountRequest, - ReturnBusCommunicationErrorCountRequest, - ReturnBusExceptionErrorCountRequest, - ReturnSlaveMessageCountRequest, - ReturnSlaveNoResponseCountRequest, - ReturnSlaveNAKCountRequest, - ReturnSlaveBusyCountRequest, - ReturnSlaveBusCharacterOverrunCountRequest, - ReturnIopOverrunCountRequest, - ClearOverrunCountRequest, - GetClearModbusPlusRequest, - - ReadDeviceInformationRequest, - ] - -
[docs] def __init__(self): - ''' Initializes the client lookup tables - ''' - functions = set(f.function_code for f in self.__function_table) - self.__lookup = dict([(f.function_code, f) for f in self.__function_table]) - self.__sub_lookup = dict((f, {}) for f in functions) - for f in self.__sub_function_table: - self.__sub_lookup[f.function_code][f.sub_function_code] = f
- -
[docs] def decode(self, message): - ''' Wrapper to decode a request packet - - :param message: The raw modbus request packet - :return: The decoded modbus message or None if error - ''' - try: - return self._helper(message) - except ModbusException as er: - _logger.warning("Unable to decode request %s" % er) - return None
- -
[docs] def lookupPduClass(self, function_code): - ''' Use `function_code` to determine the class of the PDU. - - :param function_code: The function code specified in a frame. - :returns: The class of the PDU that has a matching `function_code`. - ''' - return self.__lookup.get(function_code, ExceptionResponse)
- -
[docs] def _helper(self, data): - ''' - This factory is used to generate the correct request object - from a valid request packet. This decodes from a list of the - currently implemented request types. - - :param data: The request packet to decode - :returns: The decoded request or illegal function request object - ''' - function_code = byte2int(data[0]) - _logger.debug("Factory Request[%d]" % function_code) - request = self.__lookup.get(function_code, lambda: None)() - if not request: - request = IllegalFunctionRequest(function_code) - request.decode(data[1:]) - - if hasattr(request, 'sub_function_code'): - lookup = self.__sub_lookup.get(request.function_code, {}) - subtype = lookup.get(request.sub_function_code, None) - if subtype: request.__class__ = subtype - - return request
- - -#---------------------------------------------------------------------------# -# Client Decoder -#---------------------------------------------------------------------------# -
[docs]class ClientDecoder(IModbusDecoder): - ''' Response Message Factory (Client) - - To add more implemented functions, simply add them to the list - ''' - __function_table = [ - ReadHoldingRegistersResponse, - ReadDiscreteInputsResponse, - ReadInputRegistersResponse, - ReadCoilsResponse, - WriteMultipleCoilsResponse, - WriteMultipleRegistersResponse, - WriteSingleRegisterResponse, - WriteSingleCoilResponse, - ReadWriteMultipleRegistersResponse, - - DiagnosticStatusResponse, - - ReadExceptionStatusResponse, - GetCommEventCounterResponse, - GetCommEventLogResponse, - ReportSlaveIdResponse, - - ReadFileRecordResponse, - WriteFileRecordResponse, - MaskWriteRegisterResponse, - ReadFifoQueueResponse, - - ReadDeviceInformationResponse, - ] - __sub_function_table = [ - ReturnQueryDataResponse, - RestartCommunicationsOptionResponse, - ReturnDiagnosticRegisterResponse, - ChangeAsciiInputDelimiterResponse, - ForceListenOnlyModeResponse, - ClearCountersResponse, - ReturnBusMessageCountResponse, - ReturnBusCommunicationErrorCountResponse, - ReturnBusExceptionErrorCountResponse, - ReturnSlaveMessageCountResponse, - ReturnSlaveNoReponseCountResponse, - ReturnSlaveNAKCountResponse, - ReturnSlaveBusyCountResponse, - ReturnSlaveBusCharacterOverrunCountResponse, - ReturnIopOverrunCountResponse, - ClearOverrunCountResponse, - GetClearModbusPlusResponse, - - ReadDeviceInformationResponse, - ] - -
[docs] def __init__(self): - ''' Initializes the client lookup tables - ''' - functions = set(f.function_code for f in self.__function_table) - self.__lookup = dict([(f.function_code, f) for f in self.__function_table]) - self.__sub_lookup = dict((f, {}) for f in functions) - for f in self.__sub_function_table: - self.__sub_lookup[f.function_code][f.sub_function_code] = f
- -
[docs] def lookupPduClass(self, function_code): - ''' Use `function_code` to determine the class of the PDU. - - :param function_code: The function code specified in a frame. - :returns: The class of the PDU that has a matching `function_code`. - ''' - return self.__lookup.get(function_code, ExceptionResponse)
- -
[docs] def decode(self, message): - ''' Wrapper to decode a response packet - - :param message: The raw packet to decode - :return: The decoded modbus message or None if error - ''' - try: - return self._helper(message) - except ModbusException as er: - _logger.error("Unable to decode response %s" % er) - return None
- -
[docs] def _helper(self, data): - ''' - This factory is used to generate the correct response object - from a valid response packet. This decodes from a list of the - currently implemented request types. - - :param data: The response packet to decode - :returns: The decoded request or an exception response object - ''' - function_code = byte2int(data[0]) - _logger.debug("Factory Response[%d]" % function_code) - response = self.__lookup.get(function_code, lambda: None)() - if function_code > 0x80: - code = function_code & 0x7f # strip error portion - response = ExceptionResponse(code, ecode.IllegalFunction) - if not response: - raise ModbusException("Unknown response %d" % function_code) - response.decode(data[1:]) - - if hasattr(response, 'sub_function_code'): - lookup = self.__sub_lookup.get(response.function_code, {}) - subtype = lookup.get(response.sub_function_code, None) - if subtype: response.__class__ = subtype - - return response
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = ['ServerDecoder', 'ClientDecoder'] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/file_message.html b/doc/sphinx/html/_modules/pymodbus/file_message.html deleted file mode 100644 index fcc06fca1..000000000 --- a/doc/sphinx/html/_modules/pymodbus/file_message.html +++ /dev/null @@ -1,576 +0,0 @@ - - - - - - - - pymodbus.file_message — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.file_message

-'''
-File Record Read/Write Messages
--------------------------------
-
-Currently none of these messages are implemented
-'''
-import struct
-from pymodbus.pdu import ModbusRequest
-from pymodbus.pdu import ModbusResponse
-from pymodbus.pdu import ModbusExceptions as merror
-from pymodbus.compat import byte2int
-
-
-#---------------------------------------------------------------------------#
-# File Record Types
-#---------------------------------------------------------------------------#
-
[docs]class FileRecord(object): - ''' Represents a file record and its relevant data. - ''' - -
[docs] def __init__(self, **kwargs): - ''' Initializes a new instance - - :params reference_type: Defaults to 0x06 (must be) - :params file_number: Indicates which file number we are reading - :params record_number: Indicates which record in the file - :params record_data: The actual data of the record - :params record_length: The length in registers of the record - :params response_length: The length in bytes of the record - ''' - self.reference_type = kwargs.get('reference_type', 0x06) - self.file_number = kwargs.get('file_number', 0x00) - self.record_number = kwargs.get('record_number', 0x00) - self.record_data = kwargs.get('record_data', '') - - self.record_length = kwargs.get('record_length', len(self.record_data) // 2) - self.response_length = kwargs.get('response_length', len(self.record_data) + 1)
- -
[docs] def __eq__(self, relf): - ''' Compares the left object to the right - ''' - return self.reference_type == relf.reference_type \ - and self.file_number == relf.file_number \ - and self.record_number == relf.record_number \ - and self.record_length == relf.record_length \ - and self.record_data == relf.record_data
- -
[docs] def __ne__(self, relf): - ''' Compares the left object to the right - ''' - return not self.__eq__(relf)
- -
[docs] def __repr__(self): - ''' Gives a representation of the file record - ''' - params = (self.file_number, self.record_number, self.record_length) - return 'FileRecord(file=%d, record=%d, length=%d)' % params
- - -#---------------------------------------------------------------------------# -# File Requests/Responses -#---------------------------------------------------------------------------# -
[docs]class ReadFileRecordRequest(ModbusRequest): - ''' - This function code is used to perform a file record read. All request - data lengths are provided in terms of number of bytes and all record - lengths are provided in terms of registers. - - A file is an organization of records. Each file contains 10000 records, - addressed 0000 to 9999 decimal or 0x0000 to 0x270f. For example, record - 12 is addressed as 12. The function can read multiple groups of - references. The groups can be separating (non-contiguous), but the - references within each group must be sequential. Each group is defined - in a seperate 'sub-request' field that contains seven bytes:: - - The reference type: 1 byte (must be 0x06) - The file number: 2 bytes - The starting record number within the file: 2 bytes - The length of the record to be read: 2 bytes - - The quantity of registers to be read, combined with all other fields - in the expected response, must not exceed the allowable length of the - MODBUS PDU: 235 bytes. - ''' - function_code = 0x14 - _rtu_byte_count_pos = 2 - -
[docs] def __init__(self, records=None, **kwargs): - ''' Initializes a new instance - - :param records: The file record requests to be read - ''' - ModbusRequest.__init__(self, **kwargs) - self.records = records or []
- -
[docs] def encode(self): - ''' Encodes the request packet - - :returns: The byte encoded packet - ''' - packet = struct.pack('B', len(self.records) * 7) - for record in self.records: - packet += struct.pack('>BHHH', 0x06, record.file_number, - record.record_number, record.record_length) - return packet
- -
[docs] def decode(self, data): - ''' Decodes the incoming request - - :param data: The data to decode into the address - ''' - self.records = [] - byte_count = byte2int(data[0]) - for count in range(1, byte_count, 7): - decoded = struct.unpack('>BHHH', data[count:count+7]) - record = FileRecord(file_number=decoded[1], - record_number=decoded[2], record_length=decoded[3]) - if decoded[0] == 0x06: self.records.append(record)
- -
[docs] def execute(self, context): - ''' Run a read exeception status request against the store - - :param context: The datastore to request from - :returns: The populated response - ''' - # TODO do some new context operation here - # if file number, record number, or address + length - # is too big, return an error. - files = [] - return ReadFileRecordResponse(files)
- - -
[docs]class ReadFileRecordResponse(ModbusResponse): - ''' - The normal response is a series of 'sub-responses,' one for each - 'sub-request.' The byte count field is the total combined count of - bytes in all 'sub-responses.' In addition, each 'sub-response' - contains a field that shows its own byte count. - ''' - function_code = 0x14 - _rtu_byte_count_pos = 2 - -
[docs] def __init__(self, records=None, **kwargs): - ''' Initializes a new instance - - :param records: The requested file records - ''' - ModbusResponse.__init__(self, **kwargs) - self.records = records or []
- -
[docs] def encode(self): - ''' Encodes the response - - :returns: The byte encoded message - ''' - total = sum(record.response_length + 1 for record in self.records) - packet = struct.pack('B', total) - for record in self.records: - packet += struct.pack('>BB', 0x06, record.record_length) - packet += record.record_data - return packet
- -
[docs] def decode(self, data): - ''' Decodes a the response - - :param data: The packet data to decode - ''' - count, self.records = 1, [] - byte_count = byte2int(data[0]) - while count < byte_count: - response_length, reference_type = struct.unpack('>BB', data[count:count+2]) - count += response_length + 1 # the count is not included - record = FileRecord(response_length=response_length, - record_data=data[count - response_length + 1:count]) - if reference_type == 0x06: self.records.append(record)
- - -
[docs]class WriteFileRecordRequest(ModbusRequest): - ''' - This function code is used to perform a file record write. All - request data lengths are provided in terms of number of bytes - and all record lengths are provided in terms of the number of 16 - bit words. - ''' - function_code = 0x15 - _rtu_byte_count_pos = 2 - -
[docs] def __init__(self, records=None, **kwargs): - ''' Initializes a new instance - - :param records: The file record requests to be read - ''' - ModbusRequest.__init__(self, **kwargs) - self.records = records or []
- -
[docs] def encode(self): - ''' Encodes the request packet - - :returns: The byte encoded packet - ''' - total_length = sum((record.record_length * 2) + 7 for record in self.records) - packet = struct.pack('B', total_length) - for record in self.records: - packet += struct.pack('>BHHH', 0x06, record.file_number, - record.record_number, record.record_length) - packet += record.record_data - return packet
- -
[docs] def decode(self, data): - ''' Decodes the incoming request - - :param data: The data to decode into the address - ''' - count, self.records = 1, [] - byte_count = byte2int(data[0]) - while count < byte_count: - decoded = struct.unpack('>BHHH', data[count:count+7]) - response_length = decoded[3] * 2 - count += response_length + 7 - record = FileRecord(record_length=decoded[3], - file_number=decoded[1], record_number=decoded[2], - record_data=data[count - response_length:count]) - if decoded[0] == 0x06: self.records.append(record)
- -
[docs] def execute(self, context): - ''' Run the write file record request against the context - - :param context: The datastore to request from - :returns: The populated response - ''' - # TODO do some new context operation here - # if file number, record number, or address + length - # is too big, return an error. - return WriteFileRecordResponse(self.records)
- - -
[docs]class WriteFileRecordResponse(ModbusResponse): - ''' - The normal response is an echo of the request. - ''' - function_code = 0x15 - _rtu_byte_count_pos = 2 - -
[docs] def __init__(self, records=None, **kwargs): - ''' Initializes a new instance - - :param records: The file record requests to be read - ''' - ModbusResponse.__init__(self, **kwargs) - self.records = records or []
- -
[docs] def encode(self): - ''' Encodes the response - - :returns: The byte encoded message - ''' - total_length = sum((record.record_length * 2) + 7 for record in self.records) - packet = struct.pack('B', total_length) - for record in self.records: - packet += struct.pack('>BHHH', 0x06, record.file_number, - record.record_number, record.record_length) - packet += record.record_data - return packet
- -
[docs] def decode(self, data): - ''' Decodes the incoming request - - :param data: The data to decode into the address - ''' - count, self.records = 1, [] - byte_count = byte2int(data[0]) - while count < byte_count: - decoded = struct.unpack('>BHHH', data[count:count+7]) - response_length = decoded[3] * 2 - count += response_length + 7 - record = FileRecord(record_length=decoded[3], - file_number=decoded[1], record_number=decoded[2], - record_data=data[count - response_length:count]) - if decoded[0] == 0x06: self.records.append(record)
- - -class MaskWriteRegisterRequest(ModbusRequest): - ''' - This function code is used to modify the contents of a specified holding - register using a combination of an AND mask, an OR mask, and the - register's current contents. The function can be used to set or clear - individual bits in the register. - ''' - function_code = 0x16 - _rtu_frame_size = 10 - - - def __init__(self, address=0x0000, and_mask=0xffff, or_mask=0x0000, **kwargs): - ''' Initializes a new instance - - :param address: The mask pointer address (0x0000 to 0xffff) - :param and_mask: The and bitmask to apply to the register address - :param or_mask: The or bitmask to apply to the register address - ''' - ModbusRequest.__init__(self, **kwargs) - self.address = address - self.and_mask = and_mask - self.or_mask = or_mask - - def encode(self): - ''' Encodes the request packet - - :returns: The byte encoded packet - ''' - return struct.pack('>HHH', self.address, self.and_mask, self.or_mask) - - def decode(self, data): - ''' Decodes the incoming request - - :param data: The data to decode into the address - ''' - self.address, self.and_mask, self.or_mask = struct.unpack('>HHH', data) - - def execute(self, context): - ''' Run a mask write register request against the store - - :param context: The datastore to request from - :returns: The populated response - ''' - if not (0x0000 <= self.and_mask <= 0xffff): - return self.doException(merror.IllegalValue) - if not (0x0000 <= self.or_mask <= 0xffff): - return self.doException(merror.IllegalValue) - if not context.validate(self.function_code, self.address, 1): - return self.doException(merror.IllegalAddress) - values = context.getValues(self.function_code, self.address, 1)[0] - values = ((values & self.and_mask) | self.or_mask) - context.setValues(self.function_code, self.address, [values]) - return MaskWriteRegisterResponse(self.address, self.and_mask, self.or_mask) - - -class MaskWriteRegisterResponse(ModbusResponse): - ''' - The normal response is an echo of the request. The response is returned - after the register has been written. - ''' - function_code = 0x16 - _rtu_frame_size = 10 - - def __init__(self, address=0x0000, and_mask=0xffff, or_mask=0x0000, **kwargs): - ''' Initializes a new instance - - :param address: The mask pointer address (0x0000 to 0xffff) - :param and_mask: The and bitmask applied to the register address - :param or_mask: The or bitmask applied to the register address - ''' - ModbusResponse.__init__(self, **kwargs) - self.address = address - self.and_mask = and_mask - self.or_mask = or_mask - - def encode(self): - ''' Encodes the response - - :returns: The byte encoded message - ''' - return struct.pack('>HHH', self.address, self.and_mask, self.or_mask) - - def decode(self, data): - ''' Decodes a the response - - :param data: The packet data to decode - ''' - self.address, self.and_mask, self.or_mask = struct.unpack('>HHH', data) - - -
[docs]class ReadFifoQueueRequest(ModbusRequest): - ''' - This function code allows to read the contents of a First-In-First-Out - (FIFO) queue of register in a remote device. The function returns a - count of the registers in the queue, followed by the queued data. - Up to 32 registers can be read: the count, plus up to 31 queued data - registers. - - The queue count register is returned first, followed by the queued data - registers. The function reads the queue contents, but does not clear - them. - ''' - function_code = 0x18 - _rtu_frame_size = 6 - -
[docs] def __init__(self, address=0x0000, **kwargs): - ''' Initializes a new instance - - :param address: The fifo pointer address (0x0000 to 0xffff) - ''' - ModbusRequest.__init__(self, **kwargs) - self.address = address - self.values = [] # this should be added to the context
- -
[docs] def encode(self): - ''' Encodes the request packet - - :returns: The byte encoded packet - ''' - return struct.pack('>H', self.address)
- -
[docs] def decode(self, data): - ''' Decodes the incoming request - - :param data: The data to decode into the address - ''' - self.address = struct.unpack('>H', data)[0]
- -
[docs] def execute(self, context): - ''' Run a read exeception status request against the store - - :param context: The datastore to request from - :returns: The populated response - ''' - if not (0x0000 <= self.address <= 0xffff): - return self.doException(merror.IllegalValue) - if len(self.values) > 31: - return self.doException(merror.IllegalValue) - # TODO pull the values from some context - return ReadFifoQueueResponse(self.values)
- - -
[docs]class ReadFifoQueueResponse(ModbusResponse): - ''' - In a normal response, the byte count shows the quantity of bytes to - follow, including the queue count bytes and value register bytes - (but not including the error check field). The queue count is the - quantity of data registers in the queue (not including the count register). - - If the queue count exceeds 31, an exception response is returned with an - error code of 03 (Illegal Data Value). - ''' - function_code = 0x18 - - @classmethod -
[docs] def calculateRtuFrameSize(cls, buffer): - ''' Calculates the size of the message - - :param buffer: A buffer containing the data that have been received. - :returns: The number of bytes in the response. - ''' - hi_byte = byte2int(buffer[2]) - lo_byte = byte2int(buffer[3]) - return (hi_byte << 16) + lo_byte + 6
- -
[docs] def __init__(self, values=None, **kwargs): - ''' Initializes a new instance - - :param values: The list of values of the fifo to return - ''' - ModbusResponse.__init__(self, **kwargs) - self.values = values or []
- -
[docs] def encode(self): - ''' Encodes the response - - :returns: The byte encoded message - ''' - length = len(self.values) * 2 - packet = struct.pack('>HH', 2 + length, length) - for value in self.values: - packet += struct.pack('>H', value) - return packet
- -
[docs] def decode(self, data): - ''' Decodes a the response - - :param data: The packet data to decode - ''' - self.values = [] - _, count = struct.unpack('>HH', data[0:4]) - for index in range(0, count - 4): - idx = 4 + index * 2 - self.values.append(struct.unpack('>H', data[idx:idx + 2])[0])
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "FileRecord", - "ReadFileRecordRequest", "ReadFileRecordResponse", - "WriteFileRecordRequest", "WriteFileRecordResponse", - "MaskWriteRegisterRequest", "MaskWriteRegisterResponse", - "ReadFifoQueueRequest", "ReadFifoQueueResponse", -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/interfaces.html b/doc/sphinx/html/_modules/pymodbus/interfaces.html deleted file mode 100644 index 46190819f..000000000 --- a/doc/sphinx/html/_modules/pymodbus/interfaces.html +++ /dev/null @@ -1,327 +0,0 @@ - - - - - - - - pymodbus.interfaces — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.interfaces

-'''
-Pymodbus Interfaces
----------------------
-
-A collection of base classes that are used throughout
-the pymodbus library.
-'''
-from pymodbus.exceptions import NotImplementedException
-
-
-#---------------------------------------------------------------------------#
-# Generic
-#---------------------------------------------------------------------------#
-
[docs]class Singleton(object): - ''' - Singleton base class - http://mail.python.org/pipermail/python-list/2007-July/450681.html - ''' -
[docs] def __new__(cls, *args, **kwargs): - ''' Create a new instance - ''' - if '_inst' not in vars(cls): - cls._inst = object.__new__(cls) - return cls._inst
- - -#---------------------------------------------------------------------------# -# Project Specific -#---------------------------------------------------------------------------# -
[docs]class IModbusDecoder(object): - ''' Modbus Decoder Base Class - - This interface must be implemented by a modbus message - decoder factory. These factories are responsible for - abstracting away converting a raw packet into a request / response - message object. - ''' - -
[docs] def decode(self, message): - ''' Wrapper to decode a given packet - - :param message: The raw modbus request packet - :return: The decoded modbus message or None if error - ''' - raise NotImplementedException( - "Method not implemented by derived class")
- -
[docs] def lookupPduClass(self, function_code): - ''' Use `function_code` to determine the class of the PDU. - - :param function_code: The function code specified in a frame. - :returns: The class of the PDU that has a matching `function_code`. - ''' - raise NotImplementedException( - "Method not implemented by derived class")
- - -
[docs]class IModbusFramer(object): - ''' - A framer strategy interface. The idea is that we abstract away all the - detail about how to detect if a current message frame exists, decoding - it, sending it, etc so that we can plug in a new Framer object (tcp, - rtu, ascii). - ''' - -
[docs] def checkFrame(self): - ''' Check and decode the next frame - - :returns: True if we successful, False otherwise - ''' - raise NotImplementedException( - "Method not implemented by derived class")
- -
[docs] def advanceFrame(self): - ''' Skip over the current framed message - This allows us to skip over the current message after we have processed - it or determined that it contains an error. It also has to reset the - current frame header handle - ''' - raise NotImplementedException( - "Method not implemented by derived class")
- -
[docs] def addToFrame(self, message): - ''' Add the next message to the frame buffer - - This should be used before the decoding while loop to add the received - data to the buffer handle. - - :param message: The most recent packet - ''' - raise NotImplementedException( - "Method not implemented by derived class")
- -
[docs] def isFrameReady(self): - ''' Check if we should continue decode logic - - This is meant to be used in a while loop in the decoding phase to let - the decoder know that there is still data in the buffer. - - :returns: True if ready, False otherwise - ''' - raise NotImplementedException( - "Method not implemented by derived class")
- -
[docs] def getFrame(self): - ''' Get the next frame from the buffer - - :returns: The frame data or '' - ''' - raise NotImplementedException( - "Method not implemented by derived class")
- -
[docs] def populateResult(self, result): - ''' Populates the modbus result with current frame header - - We basically copy the data back over from the current header - to the result header. This may not be needed for serial messages. - - :param result: The response packet - ''' - raise NotImplementedException( - "Method not implemented by derived class")
- -
[docs] def processIncomingPacket(self, data, callback): - ''' The new packet processing pattern - - This takes in a new request packet, adds it to the current - packet stream, and performs framing on it. That is, checks - for complete messages, and once found, will process all that - exist. This handles the case when we read N + 1 or 1 / N - messages at a time instead of 1. - - The processed and decoded messages are pushed to the callback - function to process and send. - - :param data: The new packet data - :param callback: The function to send results to - ''' - raise NotImplementedException( - "Method not implemented by derived class")
- -
[docs] def buildPacket(self, message): - ''' Creates a ready to send modbus packet - - The raw packet is built off of a fully populated modbus - request / response message. - - :param message: The request/response to send - :returns: The built packet - ''' - raise NotImplementedException( - "Method not implemented by derived class")
- - -
[docs]class IModbusSlaveContext(object): - ''' - Interface for a modbus slave data context - - Derived classes must implemented the following methods: - reset(self) - validate(self, fx, address, count=1) - getValues(self, fx, address, count=1) - setValues(self, fx, address, values) - ''' - __fx_mapper = {2: 'd', 4: 'i'} - __fx_mapper.update([(i, 'h') for i in [3, 6, 16, 22, 23]]) - __fx_mapper.update([(i, 'c') for i in [1, 5, 15]]) - -
[docs] def decode(self, fx): - ''' Converts the function code to the datastore to - - :param fx: The function we are working with - :returns: one of [d(iscretes),i(inputs),h(oliding),c(oils) - ''' - return self.__fx_mapper[fx]
- -
[docs] def reset(self): - ''' Resets all the datastores to their default values - ''' - raise NotImplementedException("Context Reset")
- -
[docs] def validate(self, fx, address, count=1): - ''' Validates the request to make sure it is in range - - :param fx: The function we are working with - :param address: The starting address - :param count: The number of values to test - :returns: True if the request in within range, False otherwise - ''' - raise NotImplementedException("validate context values")
- -
[docs] def getValues(self, fx, address, count=1): - ''' Validates the request to make sure it is in range - - :param fx: The function we are working with - :param address: The starting address - :param count: The number of values to retrieve - :returns: The requested values from a:a+c - ''' - raise NotImplementedException("get context values")
- -
[docs] def setValues(self, fx, address, values): - ''' Sets the datastore with the supplied values - - :param fx: The function we are working with - :param address: The starting address - :param values: The new values to be set - ''' - raise NotImplementedException("set context values")
- - -
[docs]class IPayloadBuilder(object): - ''' - This is an interface to a class that can build a payload - for a modbus register write command. It should abstract - the codec for encoding data to the required format - (bcd, binary, char, etc). - ''' - -
[docs] def build(self): - ''' Return the payload buffer as a list - - This list is two bytes per element and can - thus be treated as a list of registers. - - :returns: The payload buffer as a list - ''' - raise NotImplementedException("set context values")
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - 'Singleton', - 'IModbusDecoder', 'IModbusFramer', 'IModbusSlaveContext', - 'IPayloadBuilder', -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/mei_message.html b/doc/sphinx/html/_modules/pymodbus/mei_message.html deleted file mode 100644 index 0e3336359..000000000 --- a/doc/sphinx/html/_modules/pymodbus/mei_message.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - - - - - pymodbus.mei_message — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.mei_message

-'''
-Encapsulated Interface (MEI) Transport Messages
------------------------------------------------
-
-'''
-import struct
-from pymodbus.constants import DeviceInformation, MoreData
-from pymodbus.pdu import ModbusRequest
-from pymodbus.pdu import ModbusResponse
-from pymodbus.device import ModbusControlBlock
-from pymodbus.device import DeviceInformationFactory
-from pymodbus.pdu import ModbusExceptions as merror
-from pymodbus.compat import iteritems, byte2int
-
-_MCB = ModbusControlBlock()
-
-
-#---------------------------------------------------------------------------#
-# Read Device Information
-#---------------------------------------------------------------------------#
-
[docs]class ReadDeviceInformationRequest(ModbusRequest): - ''' - This function code allows reading the identification and additional - information relative to the physical and functional description of a - remote device, only. - - The Read Device Identification interface is modeled as an address space - composed of a set of addressable data elements. The data elements are - called objects and an object Id identifies them. - ''' - function_code = 0x2b - sub_function_code = 0x0e - _rtu_frame_size = 7 - -
[docs] def __init__(self, read_code=None, object_id=0x00, **kwargs): - ''' Initializes a new instance - - :param read_code: The device information read code - :param object_id: The object to read from - ''' - ModbusRequest.__init__(self, **kwargs) - self.read_code = read_code or DeviceInformation.Basic - self.object_id = object_id
- -
[docs] def encode(self): - ''' Encodes the request packet - - :returns: The byte encoded packet - ''' - packet = struct.pack('>BBB', self.sub_function_code, - self.read_code, self.object_id) - return packet
- -
[docs] def decode(self, data): - ''' Decodes data part of the message. - - :param data: The incoming data - ''' - params = struct.unpack('>BBB', data) - self.sub_function_code, self.read_code, self.object_id = params
- -
[docs] def execute(self, context): - ''' Run a read exeception status request against the store - - :param context: The datastore to request from - :returns: The populated response - ''' - if not (0x00 <= self.object_id <= 0xff): - return self.doException(merror.IllegalValue) - if not (0x00 <= self.read_code <= 0x04): - return self.doException(merror.IllegalValue) - - information = DeviceInformationFactory.get(_MCB, - self.read_code, self.object_id) - return ReadDeviceInformationResponse(self.read_code, information)
- -
[docs] def __str__(self): - ''' Builds a representation of the request - - :returns: The string representation of the request - ''' - params = (self.read_code, self.object_id) - return "ReadDeviceInformationRequest(%d,%d)" % params
- - -
[docs]class ReadDeviceInformationResponse(ModbusResponse): - ''' - ''' - function_code = 0x2b - sub_function_code = 0x0e - - @classmethod -
[docs] def calculateRtuFrameSize(cls, buffer): - ''' Calculates the size of the message - - :param buffer: A buffer containing the data that have been received. - :returns: The number of bytes in the response. - ''' - size = 8 # skip the header information - count = byte2int(buffer[7]) - - while count > 0: - _, object_length = struct.unpack('>BB', buffer[size:size+2]) - size += object_length + 2 - count -= 1 - return size + 2
- -
[docs] def __init__(self, read_code=None, information=None, **kwargs): - ''' Initializes a new instance - - :param read_code: The device information read code - :param information: The requested information request - ''' - ModbusResponse.__init__(self, **kwargs) - self.read_code = read_code or DeviceInformation.Basic - self.information = information or {} - self.number_of_objects = len(self.information) - self.conformity = 0x83 # I support everything right now - - # TODO calculate - self.next_object_id = 0x00 # self.information[-1](0) - self.more_follows = MoreData.Nothing
- -
[docs] def encode(self): - ''' Encodes the response - - :returns: The byte encoded message - ''' - packet = struct.pack('>BBBBBB', self.sub_function_code, - self.read_code, self.conformity, self.more_follows, - self.next_object_id, self.number_of_objects) - - for (object_id, data) in iteritems(self.information): - packet += struct.pack('>BB', object_id, len(data)) - packet += data.encode() - return packet
- -
[docs] def decode(self, data): - ''' Decodes a the response - - :param data: The packet data to decode - ''' - params = struct.unpack('>BBBBBB', data[0:6]) - self.sub_function_code, self.read_code = params[0:2] - self.conformity, self.more_follows = params[2:4] - self.next_object_id, self.number_of_objects = params[4:6] - self.information, count = {}, 6 # skip the header information - - while count < len(data): - object_id, object_length = struct.unpack('>BB', data[count:count+2]) - count += object_length + 2 - self.information[object_id] = data[count-object_length:count]
- -
[docs] def __str__(self): - ''' Builds a representation of the response - - :returns: The string representation of the response - ''' - return "ReadDeviceInformationResponse(%d)" % self.read_code
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "ReadDeviceInformationRequest", "ReadDeviceInformationResponse", -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/other_message.html b/doc/sphinx/html/_modules/pymodbus/other_message.html deleted file mode 100644 index cf1081c62..000000000 --- a/doc/sphinx/html/_modules/pymodbus/other_message.html +++ /dev/null @@ -1,533 +0,0 @@ - - - - - - - - pymodbus.other_message — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.other_message

-'''
-Diagnostic record read/write
-
-Currently not all implemented
-'''
-import struct
-from pymodbus.constants import ModbusStatus
-from pymodbus.pdu import ModbusRequest
-from pymodbus.pdu import ModbusResponse
-from pymodbus.device import ModbusControlBlock
-from pymodbus.compat import byte2int, int2byte
-
-_MCB = ModbusControlBlock()
-
-
-#---------------------------------------------------------------------------#
-# TODO Make these only work on serial
-#---------------------------------------------------------------------------#
-
[docs]class ReadExceptionStatusRequest(ModbusRequest): - ''' - This function code is used to read the contents of eight Exception Status - outputs in a remote device. The function provides a simple method for - accessing this information, because the Exception Output references are - known (no output reference is needed in the function). - ''' - function_code = 0x07 - _rtu_frame_size = 4 - -
[docs] def __init__(self, **kwargs): - ''' Initializes a new instance - ''' - ModbusRequest.__init__(self, **kwargs)
- -
[docs] def encode(self): - ''' Encodes the message - ''' - return b''
- -
[docs] def decode(self, data): - ''' Decodes data part of the message. - - :param data: The incoming data - ''' - pass
- -
[docs] def execute(self): - ''' Run a read exeception status request against the store - - :returns: The populated response - ''' - status = _MCB.Counter.summary() - return ReadExceptionStatusResponse(status)
- -
[docs] def __str__(self): - ''' Builds a representation of the request - - :returns: The string representation of the request - ''' - return "ReadExceptionStatusRequest(%d)" % (self.function_code)
- - -
[docs]class ReadExceptionStatusResponse(ModbusResponse): - ''' - The normal response contains the status of the eight Exception Status - outputs. The outputs are packed into one data byte, with one bit - per output. The status of the lowest output reference is contained - in the least significant bit of the byte. The contents of the eight - Exception Status outputs are device specific. - ''' - function_code = 0x07 - _rtu_frame_size = 5 - -
[docs] def __init__(self, status=0x00, **kwargs): - ''' Initializes a new instance - - :param status: The status response to report - ''' - ModbusResponse.__init__(self, **kwargs) - self.status = status
- -
[docs] def encode(self): - ''' Encodes the response - - :returns: The byte encoded message - ''' - return struct.pack('>B', self.status)
- -
[docs] def decode(self, data): - ''' Decodes a the response - - :param data: The packet data to decode - ''' - self.status = byte2int(data[0])
- -
[docs] def __str__(self): - ''' Builds a representation of the response - - :returns: The string representation of the response - ''' - arguments = (self.function_code, self.status) - return "ReadExceptionStatusResponse(%d, %s)" % arguments
- -# Encapsulate interface transport 43, 14 -# CANopen general reference 43, 13 - - -#---------------------------------------------------------------------------# -# TODO Make these only work on serial -#---------------------------------------------------------------------------# -
[docs]class GetCommEventCounterRequest(ModbusRequest): - ''' - This function code is used to get a status word and an event count from - the remote device's communication event counter. - - By fetching the current count before and after a series of messages, a - client can determine whether the messages were handled normally by the - remote device. - - The device's event counter is incremented once for each successful - message completion. It is not incremented for exception responses, - poll commands, or fetch event counter commands. - - The event counter can be reset by means of the Diagnostics function - (code 08), with a subfunction of Restart Communications Option - (code 00 01) or Clear Counters and Diagnostic Register (code 00 0A). - ''' - function_code = 0x0b - _rtu_frame_size = 4 - -
[docs] def __init__(self, **kwargs): - ''' Initializes a new instance - ''' - ModbusRequest.__init__(self, **kwargs)
- -
[docs] def encode(self): - ''' Encodes the message - ''' - return b''
- -
[docs] def decode(self, data): - ''' Decodes data part of the message. - - :param data: The incoming data - ''' - pass
- -
[docs] def execute(self): - ''' Run a read exeception status request against the store - - :returns: The populated response - ''' - status = _MCB.Counter.Event - return GetCommEventCounterResponse(status)
- -
[docs] def __str__(self): - ''' Builds a representation of the request - - :returns: The string representation of the request - ''' - return "GetCommEventCounterRequest(%d)" % (self.function_code)
- - -
[docs]class GetCommEventCounterResponse(ModbusResponse): - ''' - The normal response contains a two-byte status word, and a two-byte - event count. The status word will be all ones (FF FF hex) if a - previously-issued program command is still being processed by the - remote device (a busy condition exists). Otherwise, the status word - will be all zeros. - ''' - function_code = 0x0b - _rtu_frame_size = 8 - -
[docs] def __init__(self, count=0x0000, **kwargs): - ''' Initializes a new instance - - :param count: The current event counter value - ''' - ModbusResponse.__init__(self, **kwargs) - self.count = count - self.status = True # this means we are ready, not waiting
- -
[docs] def encode(self): - ''' Encodes the response - - :returns: The byte encoded message - ''' - if self.status: ready = ModbusStatus.Ready - else: ready = ModbusStatus.Waiting - return struct.pack('>HH', ready, self.count)
- -
[docs] def decode(self, data): - ''' Decodes a the response - - :param data: The packet data to decode - ''' - ready, self.count = struct.unpack('>HH', data) - self.status = (ready == ModbusStatus.Ready)
- -
[docs] def __str__(self): - ''' Builds a representation of the response - - :returns: The string representation of the response - ''' - arguments = (self.function_code, self.count, self.status) - return "GetCommEventCounterResponse(%d, %d, %d)" % arguments
- - -#---------------------------------------------------------------------------# -# TODO Make these only work on serial -#---------------------------------------------------------------------------# -class GetCommEventLogRequest(ModbusRequest): - ''' - This function code is used to get a status word, event count, message - count, and a field of event bytes from the remote device. - - The status word and event counts are identical to that returned by - the Get Communications Event Counter function (11, 0B hex). - - The message counter contains the quantity of messages processed by the - remote device since its last restart, clear counters operation, or - power-up. This count is identical to that returned by the Diagnostic - function (code 08), sub-function Return Bus Message Count (code 11, - 0B hex). - - The event bytes field contains 0-64 bytes, with each byte corresponding - to the status of one MODBUS send or receive operation for the remote - device. The remote device enters the events into the field in - chronological order. Byte 0 is the most recent event. Each new byte - flushes the oldest byte from the field. - ''' - function_code = 0x0c - _rtu_frame_size = 4 - - def __init__(self, **kwargs): - ''' Initializes a new instance - ''' - ModbusRequest.__init__(self, **kwargs) - - def encode(self): - ''' Encodes the message - ''' - return b'' - - def decode(self, data): - ''' Decodes data part of the message. - - :param data: The incoming data - ''' - pass - - def execute(self): - ''' Run a read exeception status request against the store - - :returns: The populated response - ''' - results = { - 'status' : True, - 'message_count' : _MCB.Counter.BusMessage, - 'event_count' : _MCB.Counter.Event, - 'events' : _MCB.getEvents(), - } - return GetCommEventLogResponse(**results) - - def __str__(self): - ''' Builds a representation of the request - - :returns: The string representation of the request - ''' - return "GetCommEventLogRequest(%d)" % self.function_code - - -class GetCommEventLogResponse(ModbusResponse): - ''' - The normal response contains a two-byte status word field, - a two-byte event count field, a two-byte message count field, - and a field containing 0-64 bytes of events. A byte count - field defines the total length of the data in these four field - ''' - function_code = 0x0c - _rtu_byte_count_pos = 3 - - def __init__(self, **kwargs): - ''' Initializes a new instance - - :param status: The status response to report - :param message_count: The current message count - :param event_count: The current event count - :param events: The collection of events to send - ''' - ModbusResponse.__init__(self, **kwargs) - self.status = kwargs.get('status', True) - self.message_count = kwargs.get('message_count', 0) - self.event_count = kwargs.get('event_count', 0) - self.events = kwargs.get('events', []) - - def encode(self): - ''' Encodes the response - - :returns: The byte encoded message - ''' - if self.status: ready = ModbusStatus.Ready - else: ready = ModbusStatus.Waiting - packet = struct.pack('>B', 6 + len(self.events)) - packet += struct.pack('>H', ready) - packet += struct.pack('>HH', self.event_count, self.message_count) - packet += b''.join(struct.pack('>B', e) for e in self.events) - return packet - - def decode(self, data): - ''' Decodes a the response - - :param data: The packet data to decode - ''' - length = byte2int(data[0]) - status = struct.unpack('>H', data[1:3])[0] - self.status = (status == ModbusStatus.Ready) - self.event_count = struct.unpack('>H', data[3:5])[0] - self.message_count = struct.unpack('>H', data[5:7])[0] - - self.events = [] - for e in range(7, length + 1): - self.events.append(byte2int(data[e])) - - def __str__(self): - ''' Builds a representation of the response - - :returns: The string representation of the response - ''' - arguments = (self.function_code, self.status, self.message_count, self.event_count) - return "GetCommEventLogResponse(%d, %d, %d, %d)" % arguments - - -#---------------------------------------------------------------------------# -# TODO Make these only work on serial -#---------------------------------------------------------------------------# -
[docs]class ReportSlaveIdRequest(ModbusRequest): - ''' - This function code is used to read the description of the type, the - current status, and other information specific to a remote device. - ''' - function_code = 0x11 - _rtu_frame_size = 4 - -
[docs] def __init__(self, **kwargs): - ''' Initializes a new instance - ''' - ModbusRequest.__init__(self, **kwargs)
- -
[docs] def encode(self): - ''' Encodes the message - ''' - return b''
- -
[docs] def decode(self, data): - ''' Decodes data part of the message. - - :param data: The incoming data - ''' - pass
- -
[docs] def execute(self): - ''' Run a read exeception status request against the store - - :returns: The populated response - ''' - identifier = b'\x70\x79\x6d\x6f\x64\x62\x75\x73' - return ReportSlaveIdResponse(identifier)
- -
[docs] def __str__(self): - ''' Builds a representation of the request - - :returns: The string representation of the request - ''' - return "ResportSlaveIdRequest(%d)" % self.function_code
- - -
[docs]class ReportSlaveIdResponse(ModbusResponse): - ''' - The format of a normal response is shown in the following example. - The data contents are specific to each type of device. - ''' - function_code = 0x11 - _rtu_byte_count_pos = 2 - -
[docs] def __init__(self, identifier=b'\x00', status=True, **kwargs): - ''' Initializes a new instance - - :param identifier: The identifier of the slave - :param status: The status response to report - ''' - ModbusResponse.__init__(self, **kwargs) - self.identifier = identifier - self.status = status
- -
[docs] def encode(self): - ''' Encodes the response - - :returns: The byte encoded message - ''' - if self.status: status = ModbusStatus.SlaveOn - else: status = ModbusStatus.SlaveOff - length = len(self.identifier) + 2 - packet = int2byte(length) - packet += self.identifier # we assume it is already encoded - packet += int2byte(status) - return packet
- -
[docs] def decode(self, data): - ''' Decodes a the response - - Since the identifier is device dependent, we just return the - raw value that a user can decode to whatever it should be. - - :param data: The packet data to decode - ''' - length = byte2int(data[0]) - self.identifier = data[1:length + 1] - status = byte2int(data[-1]) - self.status = status == ModbusStatus.SlaveOn
- -
[docs] def __str__(self): - ''' Builds a representation of the response - - :returns: The string representation of the response - ''' - arguments = (self.function_code, self.identifier, self.status) - return "ResportSlaveIdResponse(%d, %d, %d)" % arguments
- -#---------------------------------------------------------------------------# -# TODO Make these only work on serial -#---------------------------------------------------------------------------# -# report device identification 43, 14 - -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "ReadExceptionStatusRequest", "ReadExceptionStatusResponse", - "GetCommEventCounterRequest", "GetCommEventCounterResponse", - "GetCommEventLogRequest", "GetCommEventLogResponse", - "ReportSlaveIdRequest", "ReportSlaveIdResponse", -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/payload.html b/doc/sphinx/html/_modules/pymodbus/payload.html deleted file mode 100644 index 67fb0efeb..000000000 --- a/doc/sphinx/html/_modules/pymodbus/payload.html +++ /dev/null @@ -1,432 +0,0 @@ - - - - - - - - pymodbus.payload — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.payload

-'''
-Modbus Payload Builders
-------------------------
-
-A collection of utilities for building and decoding
-modbus messages payloads.
-'''
-from struct import pack, unpack
-from pymodbus.interfaces import IPayloadBuilder
-from pymodbus.constants import Endian
-from pymodbus.utilities import pack_bitstring
-from pymodbus.utilities import unpack_bitstring
-from pymodbus.exceptions import ParameterException
-
-
-
[docs]class BinaryPayloadBuilder(IPayloadBuilder): - ''' - A utility that helps build payload messages to be - written with the various modbus messages. It really is just - a simple wrapper around the struct module, however it saves - time looking up the format strings. What follows is a simple - example:: - - builder = BinaryPayloadBuilder(endian=Endian.Little) - builder.add_8bit_uint(1) - builder.add_16bit_uint(2) - payload = builder.build() - ''' - -
[docs] 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 endian: The endianess of the payload - ''' - self._payload = payload or [] - self._endian = endian
- -
[docs] def to_string(self): - ''' Return the payload buffer as a string - - :returns: The payload buffer as a string - ''' - return b''.join(self._payload)
- -
[docs] def __str__(self): - ''' Return the payload buffer as a string - - :returns: The payload buffer as a string - ''' - return self.to_string().decode('utf-8')
- -
[docs] def reset(self): - ''' Reset the payload buffer - ''' - self._payload = []
- -
[docs] def to_registers(self): - ''' Convert the payload buffer into a register - layout that can be used as a context block. - - :returns: The register layout to use as a block - ''' - fstring = self._endian + 'H' - payload = self.build() - return [unpack(fstring, value)[0] for value in payload]
- -
[docs] def build(self): - ''' Return the payload buffer as a list - - This list is two bytes per element and can - thus be treated as a list of registers. - - :returns: The payload buffer as a list - ''' - string = self.to_string() - length = len(string) - string = string + (b'\x00' * (length % 2)) - return [string[i:i+2] for i in range(0, length, 2)]
- -
[docs] def add_bits(self, values): - ''' Adds a collection of bits to be encoded - - If these are less than a multiple of eight, - they will be left padded with 0 bits to make - it so. - - :param value: The value to add to the buffer - ''' - value = pack_bitstring(values) - self._payload.append(value)
- -
[docs] def add_8bit_uint(self, value): - ''' Adds a 8 bit unsigned int to the buffer - - :param value: The value to add to the buffer - ''' - fstring = self._endian + 'B' - self._payload.append(pack(fstring, value))
- -
[docs] def add_16bit_uint(self, value): - ''' Adds a 16 bit unsigned int to the buffer - - :param value: The value to add to the buffer - ''' - fstring = self._endian + 'H' - self._payload.append(pack(fstring, value))
- -
[docs] def add_32bit_uint(self, value): - ''' Adds a 32 bit unsigned int to the buffer - - :param value: The value to add to the buffer - ''' - fstring = self._endian + 'I' - self._payload.append(pack(fstring, value))
- -
[docs] def add_64bit_uint(self, value): - ''' Adds a 64 bit unsigned int to the buffer - - :param value: The value to add to the buffer - ''' - fstring = self._endian + 'Q' - self._payload.append(pack(fstring, value))
- -
[docs] def add_8bit_int(self, value): - ''' Adds a 8 bit signed int to the buffer - - :param value: The value to add to the buffer - ''' - fstring = self._endian + 'b' - self._payload.append(pack(fstring, value))
- -
[docs] def add_16bit_int(self, value): - ''' Adds a 16 bit signed int to the buffer - - :param value: The value to add to the buffer - ''' - fstring = self._endian + 'h' - self._payload.append(pack(fstring, value))
- -
[docs] def add_32bit_int(self, value): - ''' Adds a 32 bit signed int to the buffer - - :param value: The value to add to the buffer - ''' - fstring = self._endian + 'i' - self._payload.append(pack(fstring, value))
- -
[docs] def add_64bit_int(self, value): - ''' Adds a 64 bit signed int to the buffer - - :param value: The value to add to the buffer - ''' - fstring = self._endian + 'q' - self._payload.append(pack(fstring, value))
- -
[docs] def add_32bit_float(self, value): - ''' Adds a 32 bit float to the buffer - - :param value: The value to add to the buffer - ''' - fstring = self._endian + 'f' - self._payload.append(pack(fstring, value))
- -
[docs] def add_64bit_float(self, value): - ''' Adds a 64 bit float(double) to the buffer - - :param value: The value to add to the buffer - ''' - fstring = self._endian + 'd' - self._payload.append(pack(fstring, value))
- -
[docs] def add_string(self, value): - ''' Adds a string to the buffer - - :param value: The value to add to the buffer - ''' - fstring = self._endian + str(len(value)) + 's' - self._payload.append(pack(fstring, value))
- - -
[docs]class BinaryPayloadDecoder(object): - ''' - A utility that helps decode payload messages from a modbus - reponse message. It really is just a simple wrapper around - the struct module, however it saves time looking up the format - strings. What follows is a simple example:: - - decoder = BinaryPayloadDecoder(payload) - first = decoder.decode_8bit_uint() - second = decoder.decode_16bit_uint() - ''' - -
[docs] def __init__(self, payload, endian=Endian.Little): - ''' Initialize a new payload decoder - - :param payload: The payload to decode with - :param endian: The endianess of the payload - ''' - self._payload = payload - self._pointer = 0x00 - self._endian = endian
- - @classmethod -
[docs] def fromRegisters(klass, registers, endian=Endian.Little): - ''' Initialize a payload decoder with the result of - reading a collection of registers from a modbus device. - - The registers are treated as a list of 2 byte values. - We have to do this because of how the data has already - been decoded by the rest of the library. - - :param registers: The register results to initialize with - :param endian: The endianess of the payload - :returns: An initialized PayloadDecoder - ''' - if isinstance(registers, list): # repack into flat binary - payload = b''.join(pack(endian + 'H', x) for x in registers) - return klass(payload, endian) - raise ParameterException('Invalid collection of registers supplied')
- - @classmethod -
[docs] def fromCoils(klass, coils, endian=Endian.Little): - ''' Initialize a payload decoder with the result of - reading a collection of coils from a modbus device. - - The coils are treated as a list of bit(boolean) values. - - :param coils: The coil results to initialize with - :param endian: The endianess of the payload - :returns: An initialized PayloadDecoder - ''' - if isinstance(coils, list): - payload = pack_bitstring(coils) - return klass(payload, endian) - raise ParameterException('Invalid collection of coils supplied')
- -
[docs] def reset(self): - ''' Reset the decoder pointer back to the start - ''' - self._pointer = 0x00
- -
[docs] def decode_8bit_uint(self): - ''' Decodes a 8 bit unsigned int from the buffer - ''' - self._pointer += 1 - fstring = self._endian + 'B' - handle = self._payload[self._pointer - 1:self._pointer] - return unpack(fstring, handle)[0]
- -
[docs] def decode_bits(self): - ''' Decodes a byte worth of bits from the buffer - ''' - self._pointer += 1 - fstring = self._endian + 'B' - handle = self._payload[self._pointer - 1:self._pointer] - return unpack_bitstring(handle)
- -
[docs] def decode_16bit_uint(self): - ''' Decodes a 16 bit unsigned int from the buffer - ''' - self._pointer += 2 - fstring = self._endian + 'H' - handle = self._payload[self._pointer - 2:self._pointer] - return unpack(fstring, handle)[0]
- -
[docs] def decode_32bit_uint(self): - ''' Decodes a 32 bit unsigned int from the buffer - ''' - self._pointer += 4 - fstring = self._endian + 'I' - handle = self._payload[self._pointer - 4:self._pointer] - return unpack(fstring, handle)[0]
- -
[docs] def decode_64bit_uint(self): - ''' Decodes a 64 bit unsigned int from the buffer - ''' - self._pointer += 8 - fstring = self._endian + 'Q' - handle = self._payload[self._pointer - 8:self._pointer] - return unpack(fstring, handle)[0]
- -
[docs] def decode_8bit_int(self): - ''' Decodes a 8 bit signed int from the buffer - ''' - self._pointer += 1 - fstring = self._endian + 'b' - handle = self._payload[self._pointer - 1:self._pointer] - return unpack(fstring, handle)[0]
- -
[docs] def decode_16bit_int(self): - ''' Decodes a 16 bit signed int from the buffer - ''' - self._pointer += 2 - fstring = self._endian + 'h' - handle = self._payload[self._pointer - 2:self._pointer] - return unpack(fstring, handle)[0]
- -
[docs] def decode_32bit_int(self): - ''' Decodes a 32 bit signed int from the buffer - ''' - self._pointer += 4 - fstring = self._endian + 'i' - handle = self._payload[self._pointer - 4:self._pointer] - return unpack(fstring, handle)[0]
- -
[docs] def decode_64bit_int(self): - ''' Decodes a 64 bit signed int from the buffer - ''' - self._pointer += 8 - fstring = self._endian + 'q' - handle = self._payload[self._pointer - 8:self._pointer] - return unpack(fstring, handle)[0]
- -
[docs] def decode_32bit_float(self): - ''' Decodes a 32 bit float from the buffer - ''' - self._pointer += 4 - fstring = self._endian + 'f' - handle = self._payload[self._pointer - 4:self._pointer] - return unpack(fstring, handle)[0]
- -
[docs] def decode_64bit_float(self): - ''' Decodes a 64 bit float(double) from the buffer - ''' - self._pointer += 8 - fstring = self._endian + 'd' - handle = self._payload[self._pointer - 8:self._pointer] - return unpack(fstring, handle)[0]
- -
[docs] def decode_string(self, size=1): - ''' Decodes a string from the buffer - - :param size: The size of the string to decode - ''' - self._pointer += size - return self._payload[self._pointer - size:self._pointer]
- -#---------------------------------------------------------------------------# -# Exported Identifiers -#---------------------------------------------------------------------------# -__all__ = ["BinaryPayloadBuilder", "BinaryPayloadDecoder"] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/pdu.html b/doc/sphinx/html/_modules/pymodbus/pdu.html deleted file mode 100644 index afcda7a14..000000000 --- a/doc/sphinx/html/_modules/pymodbus/pdu.html +++ /dev/null @@ -1,330 +0,0 @@ - - - - - - - - pymodbus.pdu — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.pdu

-'''
-Contains base classes for modbus request/response/error packets
-'''
-from pymodbus.interfaces import Singleton
-from pymodbus.exceptions import NotImplementedException
-from pymodbus.constants import Defaults
-from pymodbus.utilities import rtuFrameSize
-from pymodbus.compat import iteritems, int2byte, byte2int
-
-#---------------------------------------------------------------------------#
-# Logging
-#---------------------------------------------------------------------------#
-import logging
-_logger = logging.getLogger(__name__)
-
-
-#---------------------------------------------------------------------------#
-# Base PDU's
-#---------------------------------------------------------------------------#
-
[docs]class ModbusPDU(object): - ''' - Base class for all Modbus mesages - - .. attribute:: transaction_id - - This value is used to uniquely identify a request - response pair. It can be implemented as a simple counter - - .. attribute:: protocol_id - - This is a constant set at 0 to indicate Modbus. It is - put here for ease of expansion. - - .. attribute:: unit_id - - This is used to route the request to the correct child. In - the TCP modbus, it is used for routing (or not used at all. However, - for the serial versions, it is used to specify which child to perform - the requests against. The value 0x00 represents the broadcast address - (also 0xff). - - .. attribute:: check - - This is used for LRC/CRC in the serial modbus protocols - - .. attribute:: skip_encode - - This is used when the message payload has already been encoded. - Generally this will occur when the PayloadBuilder is being used - to create a complicated message. By setting this to True, the - request will pass the currently encoded message through instead - of encoding it again. - ''' - -
[docs] def __init__(self, **kwargs): - ''' Initializes the base data for a modbus request ''' - self.transaction_id = kwargs.get('transaction', Defaults.TransactionId) - self.protocol_id = kwargs.get('protocol', Defaults.ProtocolId) - self.unit_id = kwargs.get('unit', Defaults.UnitId) - self.skip_encode = kwargs.get('skip_encode', False) - self.check = 0x0000
- -
[docs] def encode(self): - ''' Encodes the message - - :raises: A not implemented exception - ''' - raise NotImplementedException()
- -
[docs] def decode(self, data): - ''' Decodes data part of the message. - - :param data: is a string object - :raises: A not implemented exception - ''' - raise NotImplementedException()
- - @classmethod -
[docs] def calculateRtuFrameSize(cls, buffer): - ''' Calculates the size of a PDU. - - :param buffer: A buffer containing the data that have been received. - :returns: The number of bytes in the PDU. - ''' - if hasattr(cls, '_rtu_frame_size'): - return cls._rtu_frame_size - elif hasattr(cls, '_rtu_byte_count_pos'): - return rtuFrameSize(buffer, cls._rtu_byte_count_pos) - else: raise NotImplementedException( - "Cannot determine RTU frame size for %s" % cls.__name__)
- - -
[docs]class ModbusRequest(ModbusPDU): - ''' Base class for a modbus request PDU ''' - -
[docs] def __init__(self, **kwargs): - ''' Proxy to the lower level initializer ''' - ModbusPDU.__init__(self, **kwargs)
- -
[docs] def doException(self, exception): - ''' Builds an error response based on the function - - :param exception: The exception to return - :raises: An exception response - ''' - _logger.error("Exception Response F(%d) E(%d)" % - (self.function_code, exception)) - return ExceptionResponse(self.function_code, exception)
- - -
[docs]class ModbusResponse(ModbusPDU): - ''' Base class for a modbus response PDU - - .. attribute:: should_respond - - A flag that indicates if this response returns a result back - to the client issuing the request - - .. attribute:: _rtu_frame_size - - Indicates the size of the modbus rtu response used for - calculating how much to read. - ''' - - should_respond = True - -
[docs] def __init__(self, **kwargs): - ''' Proxy to the lower level initializer ''' - ModbusPDU.__init__(self, **kwargs)
- - -#---------------------------------------------------------------------------# -# Exception PDU's -#---------------------------------------------------------------------------# -
[docs]class ModbusExceptions(Singleton): - ''' - An enumeration of the valid modbus exceptions - ''' - IllegalFunction = 0x01 - IllegalAddress = 0x02 - IllegalValue = 0x03 - SlaveFailure = 0x04 - Acknowledge = 0x05 - SlaveBusy = 0x06 - MemoryParityError = 0x08 - GatewayPathUnavailable = 0x0A - GatewayNoResponse = 0x0B - - @classmethod -
[docs] def decode(cls, code): - ''' Given an error code, translate it to a - string error name. - - :param code: The code number to translate - ''' - values = dict((v, k) for k, v in iteritems(cls.__dict__) - if not k.startswith('__') and not callable(v)) - return values.get(code, None)
- - -
[docs]class ExceptionResponse(ModbusResponse): - ''' Base class for a modbus exception PDU ''' - ExceptionOffset = 0x80 - _rtu_frame_size = 5 - -
[docs] def __init__(self, function_code, exception_code=None, **kwargs): - ''' Initializes the modbus exception response - - :param function_code: The function to build an exception response for - :param exception_code: The specific modbus exception to return - ''' - ModbusResponse.__init__(self, **kwargs) - self.original_code = function_code - self.function_code = function_code | self.ExceptionOffset - self.exception_code = exception_code
- -
[docs] def encode(self): - ''' Encodes a modbus exception response - - :returns: The encoded exception packet - ''' - return int2byte(self.exception_code)
- -
[docs] def decode(self, data): - ''' Decodes a modbus exception response - - :param data: The packet data to decode - ''' - self.exception_code = byte2int(data[0])
- -
[docs] def __str__(self): - ''' Builds a representation of an exception response - - :returns: The string representation of an exception response - ''' - message = ModbusExceptions.decode(self.exception_code) - parameters = (self.function_code, self.original_code, message) - return "Exception Response(%d, %d, %s)" % parameters
- - -
[docs]class IllegalFunctionRequest(ModbusRequest): - ''' - Defines the Modbus slave exception type 'Illegal Function' - This exception code is returned if the slave:: - - - does not implement the function code **or** - - is not in a state that allows it to process the function - ''' - ErrorCode = 1 - -
[docs] def __init__(self, function_code, **kwargs): - ''' Initializes a IllegalFunctionRequest - - :param function_code: The function we are erroring on - ''' - ModbusRequest.__init__(self, **kwargs) - self.function_code = function_code
- -
[docs] def decode(self, data): - ''' This is here so this failure will run correctly - - :param data: Not used - ''' - pass
- -
[docs] def execute(self, context): - ''' Builds an illegal function request error response - - :param context: The current context for the message - :returns: The error response packet - ''' - return ExceptionResponse(self.function_code, self.ErrorCode)
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - 'ModbusRequest', 'ModbusResponse', 'ModbusExceptions', - 'ExceptionResponse', 'IllegalFunctionRequest', -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/register_read_message.html b/doc/sphinx/html/_modules/pymodbus/register_read_message.html deleted file mode 100644 index 5ecb331d7..000000000 --- a/doc/sphinx/html/_modules/pymodbus/register_read_message.html +++ /dev/null @@ -1,449 +0,0 @@ - - - - - - - - pymodbus.register_read_message — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.register_read_message

-'''
-Register Reading Request/Response
----------------------------------
-'''
-import struct
-from pymodbus.pdu import ModbusRequest
-from pymodbus.pdu import ModbusResponse
-from pymodbus.pdu import ModbusExceptions as merror
-from pymodbus.compat import int2byte, byte2int
-
-
-
[docs]class ReadRegistersRequestBase(ModbusRequest): - ''' - Base class for reading a modbus register - ''' - _rtu_frame_size = 8 - -
[docs] def __init__(self, address, count, **kwargs): - ''' Initializes a new instance - - :param address: The address to start the read from - :param count: The number of registers to read - ''' - ModbusRequest.__init__(self, **kwargs) - self.address = address - self.count = count
- -
[docs] def encode(self): - ''' Encodes the request packet - - :return: The encoded packet - ''' - return struct.pack('>HH', self.address, self.count)
- -
[docs] def decode(self, data): - ''' Decode a register request packet - - :param data: The request to decode - ''' - self.address, self.count = struct.unpack('>HH', data)
- -
[docs] 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.count
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :returns: A string representation of the instance - ''' - return "ReadRegisterRequest (%d,%d)" % (self.address, self.count)
- - -
[docs]class ReadRegistersResponseBase(ModbusResponse): - ''' - Base class for responsing to a modbus register read - ''' - - _rtu_byte_count_pos = 2 - -
[docs] def __init__(self, values, **kwargs): - ''' Initializes a new instance - - :param values: The values to write to - ''' - ModbusResponse.__init__(self, **kwargs) - self.registers = values or []
- -
[docs] def encode(self): - ''' Encodes the response packet - - :returns: The encoded packet - ''' - result = int2byte(len(self.registers) * 2) - for register in self.registers: - result += struct.pack('>H', register) - return result
- -
[docs] def decode(self, data): - ''' Decode a register response packet - - :param data: The request to decode - ''' - byte_count = byte2int(data[0]) - self.registers = [] - for i in range(1, byte_count + 1, 2): - self.registers.append(struct.unpack('>H', data[i:i + 2])[0])
- -
[docs] def getRegister(self, index): - ''' Get the requested register - - :param index: The indexed register to retrieve - :returns: The request register - ''' - return self.registers[index]
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :returns: A string representation of the instance - ''' - return "ReadRegisterResponse (%d)" % len(self.registers)
- - -
[docs]class ReadHoldingRegistersRequest(ReadRegistersRequestBase): - ''' - This function code is used to read the contents of a contiguous block - of holding registers in a remote device. The Request PDU specifies the - starting register address and the number of registers. In the PDU - Registers are addressed starting at zero. Therefore registers numbered - 1-16 are addressed as 0-15. - ''' - function_code = 3 - -
[docs] def __init__(self, address=None, count=None, **kwargs): - ''' Initializes a new instance of the request - - :param address: The starting address to read from - :param count: The number of registers to read from address - ''' - ReadRegistersRequestBase.__init__(self, address, count, **kwargs)
- -
[docs] def execute(self, context): - ''' Run a read holding request against a datastore - - :param context: The datastore to request from - :returns: An initialized response, exception message otherwise - ''' - if not (1 <= self.count <= 0x7d): - return self.doException(merror.IllegalValue) - if not context.validate(self.function_code, self.address, self.count): - return self.doException(merror.IllegalAddress) - values = context.getValues(self.function_code, self.address, self.count) - return ReadHoldingRegistersResponse(values)
- - -
[docs]class ReadHoldingRegistersResponse(ReadRegistersResponseBase): - ''' - This function code is used to read the contents of a contiguous block - of holding registers in a remote device. The Request PDU specifies the - starting register address and the number of registers. In the PDU - Registers are addressed starting at zero. Therefore registers numbered - 1-16 are addressed as 0-15. - ''' - function_code = 3 - -
[docs] def __init__(self, values=None, **kwargs): - ''' Initializes a new response instance - - :param values: The resulting register values - ''' - ReadRegistersResponseBase.__init__(self, values, **kwargs)
- - -
[docs]class ReadInputRegistersRequest(ReadRegistersRequestBase): - ''' - This function code is used to read from 1 to approx. 125 contiguous - input registers in a remote device. The Request PDU specifies the - starting register address and the number of registers. In the PDU - Registers are addressed starting at zero. Therefore input registers - numbered 1-16 are addressed as 0-15. - ''' - function_code = 4 - -
[docs] def __init__(self, address=None, count=None, **kwargs): - ''' Initializes a new instance of the request - - :param address: The starting address to read from - :param count: The number of registers to read from address - ''' - ReadRegistersRequestBase.__init__(self, address, count, **kwargs)
- -
[docs] def execute(self, context): - ''' Run a read input request against a datastore - - :param context: The datastore to request from - :returns: An initialized response, exception message otherwise - ''' - if not (1 <= self.count <= 0x7d): - return self.doException(merror.IllegalValue) - if not context.validate(self.function_code, self.address, self.count): - return self.doException(merror.IllegalAddress) - values = context.getValues(self.function_code, self.address, self.count) - return ReadInputRegistersResponse(values)
- - -
[docs]class ReadInputRegistersResponse(ReadRegistersResponseBase): - ''' - This function code is used to read from 1 to approx. 125 contiguous - input registers in a remote device. The Request PDU specifies the - starting register address and the number of registers. In the PDU - Registers are addressed starting at zero. Therefore input registers - numbered 1-16 are addressed as 0-15. - ''' - function_code = 4 - -
[docs] def __init__(self, values=None, **kwargs): - ''' Initializes a new response instance - - :param values: The resulting register values - ''' - ReadRegistersResponseBase.__init__(self, values, **kwargs)
- - -
[docs]class ReadWriteMultipleRegistersRequest(ModbusRequest): - ''' - This function code performs a combination of one read operation and one - write operation in a single MODBUS transaction. The write - operation is performed before the read. - - Holding registers are addressed starting at zero. Therefore holding - registers 1-16 are addressed in the PDU as 0-15. - - The request specifies the starting address and number of holding - registers to be read as well as the starting address, number of holding - registers, and the data to be written. The byte count specifies the - number of bytes to follow in the write data field." - ''' - function_code = 23 - _rtu_byte_count_pos = 10 - -
[docs] def __init__(self, **kwargs): - ''' Initializes a new request message - - :param read_address: The address to start reading from - :param read_count: The number of registers to read from address - :param write_address: The address to start writing to - :param write_registers: The registers to write to the specified address - ''' - ModbusRequest.__init__(self, **kwargs) - self.read_address = kwargs.get('read_address', 0x00) - self.read_count = kwargs.get('read_count', 0) - self.write_address = kwargs.get('write_address', 0x00) - self.write_registers = kwargs.get('write_registers', None) - if not hasattr(self.write_registers, '__iter__'): - self.write_registers = [self.write_registers] - self.write_count = len(self.write_registers) - self.write_byte_count = self.write_count * 2
- -
[docs] def encode(self): - ''' Encodes the request packet - - :returns: The encoded packet - ''' - result = struct.pack('>HHHHB', - self.read_address, self.read_count, \ - self.write_address, self.write_count, self.write_byte_count) - for register in self.write_registers: - result += struct.pack('>H', register) - return result
- -
[docs] def decode(self, data): - ''' Decode the register request packet - - :param data: The request to decode - ''' - self.read_address, self.read_count, \ - self.write_address, self.write_count, \ - self.write_byte_count = struct.unpack('>HHHHB', data[:9]) - self.write_registers = [] - for i in range(9, self.write_byte_count + 9, 2): - register = struct.unpack('>H', data[i:i + 2])[0] - self.write_registers.append(register)
- -
[docs] def execute(self, context): - ''' Run a write single register request against a datastore - - :param context: The datastore to request from - :returns: An initialized response, exception message otherwise - ''' - if not (1 <= self.read_count <= 0x07d): - return self.doException(merror.IllegalValue) - if not (1 <= self.write_count <= 0x079): - return self.doException(merror.IllegalValue) - if (self.write_byte_count != self.write_count * 2): - return self.doException(merror.IllegalValue) - if not context.validate(self.function_code, self.write_address, - self.write_count): - return self.doException(merror.IllegalAddress) - if not context.validate(self.function_code, self.read_address, - self.read_count): - return self.doException(merror.IllegalAddress) - context.setValues(self.function_code, self.write_address, - self.write_registers) - registers = context.getValues(self.function_code, self.read_address, - self.read_count) - return ReadWriteMultipleRegistersResponse(registers)
- -
[docs] 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
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :returns: A string representation of the instance - ''' - params = (self.read_address, self.read_count, self.write_address, - self.write_count) - return "ReadWriteNRegisterRequest R(%d,%d) W(%d,%d)" % params
- - -
[docs]class ReadWriteMultipleRegistersResponse(ModbusResponse): - ''' - The normal response contains the data from the group of registers that - were read. The byte count field specifies the quantity of bytes to - follow in the read data field. - ''' - function_code = 23 - _rtu_byte_count_pos = 2 - -
[docs] def __init__(self, values=None, **kwargs): - ''' Initializes a new instance - - :param values: The register values to write - ''' - ModbusResponse.__init__(self, **kwargs) - self.registers = values or []
- -
[docs] def encode(self): - ''' Encodes the response packet - - :returns: The encoded packet - ''' - result = int2byte(len(self.registers) * 2) - for register in self.registers: - result += struct.pack('>H', register) - return result
- -
[docs] def decode(self, data): - ''' Decode the register response packet - - :param data: The response to decode - ''' - bytecount = byte2int(data[0]) - for i in range(1, bytecount, 2): - self.registers.append(struct.unpack('>H', data[i:i + 2])[0])
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :returns: A string representation of the instance - ''' - return "ReadWriteNRegisterResponse (%d)" % len(self.registers)
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "ReadHoldingRegistersRequest", "ReadHoldingRegistersResponse", - "ReadInputRegistersRequest", "ReadInputRegistersResponse", - "ReadWriteMultipleRegistersRequest", "ReadWriteMultipleRegistersResponse", -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/register_write_message.html b/doc/sphinx/html/_modules/pymodbus/register_write_message.html deleted file mode 100644 index f2990db88..000000000 --- a/doc/sphinx/html/_modules/pymodbus/register_write_message.html +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - - - pymodbus.register_write_message — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.register_write_message

-'''
-Register Writing Request/Response Messages
--------------------------------------------
-'''
-import struct
-from pymodbus.pdu import ModbusRequest
-from pymodbus.pdu import ModbusResponse
-from pymodbus.pdu import ModbusExceptions as merror
-
-
-
[docs]class WriteSingleRegisterRequest(ModbusRequest): - ''' - This function code is used to write a single holding register in a - remote device. - - The Request PDU specifies the address of the register to - be written. Registers are addressed starting at zero. Therefore register - numbered 1 is addressed as 0. - ''' - function_code = 6 - _rtu_frame_size = 8 - -
[docs] def __init__(self, address=None, value=None, **kwargs): - ''' Initializes a new instance - - :param address: The address to start writing add - :param value: The values to write - ''' - ModbusRequest.__init__(self, **kwargs) - self.address = address - self.value = value
- -
[docs] def encode(self): - ''' Encode a write single register packet packet request - - :returns: The encoded packet - ''' - if self.skip_encode: - return self.value - return struct.pack('>HH', self.address, self.value)
- -
[docs] def decode(self, data): - ''' Decode a write single register packet packet request - - :param data: The request to decode - ''' - self.address, self.value = struct.unpack('>HH', data)
- -
[docs] def execute(self, context): - ''' Run a write single register request against a datastore - - :param context: The datastore to request from - :returns: An initialized response, exception message otherwise - ''' - if not (0 <= self.value <= 0xffff): - return self.doException(merror.IllegalValue) - if not context.validate(self.function_code, self.address, 1): - return self.doException(merror.IllegalAddress) - - context.setValues(self.function_code, self.address, [self.value]) - values = context.getValues(self.function_code, self.address, 1) - return WriteSingleRegisterResponse(self.address, values[0])
- -
[docs] def get_response_pdu_size(self): - """ - Func_code (1 byte) + Register Address(2 byte) + Register Value (2 bytes) - :return: - """ - return 1 + 2 + 2
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :returns: A string representation of the instance - ''' - return "WriteRegisterRequest %d => %d" % (self.address, self.value)
- - -
[docs]class WriteSingleRegisterResponse(ModbusResponse): - ''' - The normal response is an echo of the request, returned after the - register contents have been written. - ''' - function_code = 6 - _rtu_frame_size = 8 - -
[docs] def __init__(self, address=None, value=None, **kwargs): - ''' Initializes a new instance - - :param address: The address to start writing add - :param value: The values to write - ''' - ModbusResponse.__init__(self, **kwargs) - self.address = address - self.value = value
- -
[docs] def encode(self): - ''' Encode a write single register packet packet request - - :returns: The encoded packet - ''' - return struct.pack('>HH', self.address, self.value)
- -
[docs] def decode(self, data): - ''' Decode a write single register packet packet request - - :param data: The request to decode - ''' - self.address, self.value = struct.unpack('>HH', data)
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :returns: A string representation of the instance - ''' - params = (self.address, self.value) - return "WriteRegisterResponse %d => %d" % params
- - -#---------------------------------------------------------------------------# -# Write Multiple Registers -#---------------------------------------------------------------------------# -
[docs]class WriteMultipleRegistersRequest(ModbusRequest): - ''' - This function code is used to write a block of contiguous registers (1 - to approx. 120 registers) in a remote device. - - The requested written values are specified in the request data field. - Data is packed as two bytes per register. - ''' - function_code = 16 - _rtu_byte_count_pos = 6 - _pdu_length = 5 #func + adress1 + adress2 + outputQuant1 + outputQuant2 - -
[docs] def __init__(self, address=None, values=None, **kwargs): - ''' Initializes a new instance - - :param address: The address to start writing to - :param values: The values to write - ''' - ModbusRequest.__init__(self, **kwargs) - self.address = address - if values is None: - values = [] - elif not hasattr(values, '__iter__'): - values = [values] - self.values = values - self.count = len(self.values) - self.byte_count = self.count * 2
- -
[docs] def encode(self): - ''' Encode a write single register packet packet request - - :returns: The encoded packet - ''' - packet = struct.pack('>HHB', self.address, self.count, self.byte_count) - if self.skip_encode: - return packet + b''.join(self.values) - - for value in self.values: - packet += struct.pack('>H', value) - - return packet
- -
[docs] def decode(self, data): - ''' Decode a write single register packet packet request - - :param data: The request to decode - ''' - self.address, self.count, \ - self.byte_count = struct.unpack('>HHB', data[:5]) - self.values = [] # reset - for idx in range(5, (self.count * 2) + 5, 2): - self.values.append(struct.unpack('>H', data[idx:idx + 2])[0])
- -
[docs] def execute(self, context): - ''' Run a write single register request against a datastore - - :param context: The datastore to request from - :returns: An initialized response, exception message otherwise - ''' - if not (1 <= self.count <= 0x07b): - return self.doException(merror.IllegalValue) - if (self.byte_count != self.count * 2): - return self.doException(merror.IllegalValue) - if not context.validate(self.function_code, self.address, self.count): - return self.doException(merror.IllegalAddress) - - context.setValues(self.function_code, self.address, self.values) - return WriteMultipleRegistersResponse(self.address, self.count)
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :returns: A string representation of the instance - ''' - params = (self.address, self.count) - return "WriteMultipleRegisterRequest %d => %d" % params
- - -
[docs]class WriteMultipleRegistersResponse(ModbusResponse): - ''' - "The normal response returns the function code, starting address, and - quantity of registers written. - ''' - function_code = 16 - _rtu_frame_size = 8 - -
[docs] def __init__(self, address=None, count=None, **kwargs): - ''' Initializes a new instance - - :param address: The address to start writing to - :param count: The number of registers to write to - ''' - ModbusResponse.__init__(self, **kwargs) - self.address = address - self.count = count
- -
[docs] def encode(self): - ''' Encode a write single register packet packet request - - :returns: The encoded packet - ''' - return struct.pack('>HH', self.address, self.count)
- -
[docs] def decode(self, data): - ''' Decode a write single register packet packet request - - :param data: The request to decode - ''' - self.address, self.count = struct.unpack('>HH', data)
- -
[docs] def __str__(self): - ''' Returns a string representation of the instance - - :returns: A string representation of the instance - ''' - params = (self.address, self.count) - return "WriteMultipleRegisterResponse (%d,%d)" % params
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "WriteSingleRegisterRequest", "WriteSingleRegisterResponse", - "WriteMultipleRegistersRequest", "WriteMultipleRegistersResponse", -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/server/async.html b/doc/sphinx/html/_modules/pymodbus/server/async.html deleted file mode 100644 index dbbe5cea1..000000000 --- a/doc/sphinx/html/_modules/pymodbus/server/async.html +++ /dev/null @@ -1,370 +0,0 @@ - - - - - - - - pymodbus.server.async — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.server.async

-'''
-Implementation of a Twisted Modbus Server
-------------------------------------------
-
-'''
-from binascii import b2a_hex
-from twisted.internet import protocol
-from twisted.internet.protocol import ServerFactory
-
-from pymodbus.constants import Defaults
-from pymodbus.factory import ServerDecoder
-from pymodbus.datastore import ModbusServerContext
-from pymodbus.device import ModbusControlBlock
-from pymodbus.device import ModbusAccessControl
-from pymodbus.device import ModbusDeviceIdentification
-from pymodbus.exceptions import NoSuchSlaveException
-from pymodbus.transaction import ModbusSocketFramer, ModbusAsciiFramer
-from pymodbus.pdu import ModbusExceptions as merror
-from pymodbus.internal.ptwisted import InstallManagementConsole
-from pymodbus.compat import byte2int
-from twisted.internet import reactor
-
-#---------------------------------------------------------------------------#
-# Logging
-#---------------------------------------------------------------------------#
-import logging
-_logger = logging.getLogger(__name__)
-
-
-#---------------------------------------------------------------------------#
-# Modbus TCP Server
-#---------------------------------------------------------------------------#
-
[docs]class ModbusTcpProtocol(protocol.Protocol): - ''' Implements a modbus server in twisted ''' - -
[docs] def connectionMade(self): - ''' Callback for when a client connects - - ..note:: since the protocol factory cannot be accessed from the - protocol __init__, the client connection made is essentially - our __init__ method. - ''' - _logger.debug("Client Connected [%s]" % self.transport.getHost()) - self.framer = self.factory.framer(decoder=self.factory.decoder)
- -
[docs] def connectionLost(self, reason): - ''' Callback for when a client disconnects - - :param reason: The client's reason for disconnecting - ''' - _logger.debug("Client Disconnected: %s" % reason)
- -
[docs] def dataReceived(self, data): - ''' Callback when we receive any data - - :param data: The data sent by the client - ''' - if _logger.isEnabledFor(logging.DEBUG): - _logger.debug(' '.join([hex(byte2int(x)) for x in data])) - if not self.factory.control.ListenOnly: - self.framer.processIncomingPacket(data, self._execute)
- -
[docs] def _execute(self, request): - ''' Executes the request and returns the result - - :param request: The decoded request message - ''' - try: - context = self.factory.store[request.unit_id] - response = request.execute(context) - except NoSuchSlaveException as ex: - _logger.debug("requested slave does not exist: %s" % request.unit_id ) - if self.factory.ignore_missing_slaves: - return # the client will simply timeout waiting for a response - response = request.doException(merror.GatewayNoResponse) - except Exception as ex: - _logger.debug("Datastore unable to fulfill request: %s" % ex) - response = request.doException(merror.SlaveFailure) - #self.framer.populateResult(response) - response.transaction_id = request.transaction_id - response.unit_id = request.unit_id - self._send(response)
- -
[docs] def _send(self, message): - ''' Send a request (string) to the network - - :param message: The unencoded modbus response - ''' - if message.should_respond: - self.factory.control.Counter.BusMessage += 1 - pdu = self.framer.buildPacket(message) - if _logger.isEnabledFor(logging.DEBUG): - _logger.debug('send: %s' % b2a_hex(pdu)) - return self.transport.write(pdu)
- - -
[docs]class ModbusServerFactory(ServerFactory): - ''' - Builder class for a modbus server - - This also holds the server datastore so that it is - persisted between connections - ''' - - protocol = ModbusTcpProtocol - -
[docs] def __init__(self, store, framer=None, identity=None, **kwargs): - ''' Overloaded initializer for the modbus factory - - If the identify structure is not passed in, the ModbusControlBlock - uses its own empty structure. - - :param store: The ModbusServerContext datastore - :param framer: The framer strategy to use - :param identity: An optional identify structure - :param ignore_missing_slaves: True to not send errors on a request to a missing slave - ''' - self.decoder = ServerDecoder() - self.framer = framer or ModbusSocketFramer - self.store = store or ModbusServerContext() - self.control = ModbusControlBlock() - self.access = ModbusAccessControl() - self.ignore_missing_slaves = kwargs.get('ignore_missing_slaves', Defaults.IgnoreMissingSlaves) - - if isinstance(identity, ModbusDeviceIdentification): - self.control.Identity.update(identity)
- - -#---------------------------------------------------------------------------# -# Modbus UDP Server -#---------------------------------------------------------------------------# -
[docs]class ModbusUdpProtocol(protocol.DatagramProtocol): - ''' Implements a modbus udp server in twisted ''' - -
[docs] def __init__(self, store, framer=None, identity=None, **kwargs): - ''' Overloaded initializer for the modbus factory - - If the identify structure is not passed in, the ModbusControlBlock - uses its own empty structure. - - :param store: The ModbusServerContext datastore - :param framer: The framer strategy to use - :param identity: An optional identify structure - :param ignore_missing_slaves: True to not send errors on a request to a missing slave - ''' - framer = framer or ModbusSocketFramer - self.framer = framer(decoder=ServerDecoder()) - self.store = store or ModbusServerContext() - self.control = ModbusControlBlock() - self.access = ModbusAccessControl() - self.ignore_missing_slaves = kwargs.get('ignore_missing_slaves', Defaults.IgnoreMissingSlaves) - - if isinstance(identity, ModbusDeviceIdentification): - self.control.Identity.update(identity)
- -
[docs] def datagramReceived(self, data, addr): - ''' Callback when we receive any data - - :param data: The data sent by the client - ''' - _logger.debug("Client Connected [%s:%s]" % addr) - if _logger.isEnabledFor(logging.DEBUG): - _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)
- -
[docs] def _execute(self, request, addr): - ''' Executes the request and returns the result - - :param request: The decoded request message - ''' - try: - context = self.store[request.unit_id] - response = request.execute(context) - except NoSuchSlaveException as ex: - _logger.debug("requested slave does not exist: %s" % request.unit_id ) - if self.ignore_missing_slaves: - return # the client will simply timeout waiting for a response - response = request.doException(merror.GatewayNoResponse) - except Exception as ex: - _logger.debug("Datastore unable to fulfill request: %s" % ex) - response = request.doException(merror.SlaveFailure) - #self.framer.populateResult(response) - response.transaction_id = request.transaction_id - response.unit_id = request.unit_id - self._send(response, addr)
- -
[docs] def _send(self, message, addr): - ''' Send a request (string) to the network - - :param message: The unencoded modbus response - :param addr: The (host, port) to send the message to - ''' - self.control.Counter.BusMessage += 1 - pdu = self.framer.buildPacket(message) - if _logger.isEnabledFor(logging.DEBUG): - _logger.debug('send: %s' % b2a_hex(pdu)) - return self.transport.write(pdu, addr)
- - -#---------------------------------------------------------------------------# -# Starting Factories -#---------------------------------------------------------------------------# -
[docs]def StartTcpServer(context, identity=None, address=None, console=False, **kwargs): - ''' Helper method to start the Modbus Async TCP server - - :param context: The server data context - :param identify: The server identity to use (default empty) - :param address: An optional (interface, port) to bind to. - :param console: A flag indicating if you want the debug console - :param ignore_missing_slaves: True to not send errors on a request to a missing slave - ''' - from twisted.internet import reactor - - address = address or ("", Defaults.Port) - framer = ModbusSocketFramer - factory = ModbusServerFactory(context, framer, identity, **kwargs) - if console: - InstallManagementConsole({'factory': factory}) - - _logger.info("Starting Modbus TCP Server on %s:%s" % address) - reactor.listenTCP(address[1], factory, interface=address[0]) - reactor.run()
- - -
[docs]def StartUdpServer(context, identity=None, address=None, **kwargs): - ''' Helper method to start the Modbus Async Udp server - - :param context: The server data context - :param identify: The server identity to use (default empty) - :param address: An optional (interface, port) to bind to. - :param ignore_missing_slaves: True to not send errors on a request to a missing slave - ''' - from twisted.internet import reactor - - address = address or ("", Defaults.Port) - framer = ModbusSocketFramer - server = ModbusUdpProtocol(context, framer, identity, **kwargs) - - _logger.info("Starting Modbus UDP Server on %s:%s" % address) - reactor.listenUDP(address[1], server, interface=address[0]) - reactor.run()
- - -
[docs]def StartSerialServer(context, identity=None, - framer=ModbusAsciiFramer, **kwargs): - ''' Helper method to start the Modbus Async Serial server - - :param context: The server data context - :param identify: The server identity to use (default empty) - :param framer: The framer to use (default ModbusAsciiFramer) - :param port: The serial port to attach to - :param baudrate: The baud rate to use for the serial device - :param console: A flag indicating if you want the debug console - :param ignore_missing_slaves: True to not send errors on a request to a missing slave - ''' - from twisted.internet import reactor - from twisted.internet.serialport import SerialPort - - port = kwargs.get('port', '/dev/ttyS0') - baudrate = kwargs.get('baudrate', Defaults.Baudrate) - console = kwargs.get('console', False) - - _logger.info("Starting Modbus Serial Server on %s" % port) - factory = ModbusServerFactory(context, framer, identity, **kwargs) - if console: - InstallManagementConsole({'factory': factory}) - - protocol = factory.buildProtocol(None) - SerialPort.getHost = lambda self: port # hack for logging - SerialPort(protocol, port, reactor, baudrate) - reactor.run()
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "StartTcpServer", "StartUdpServer", "StartSerialServer", -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/server/sync.html b/doc/sphinx/html/_modules/pymodbus/server/sync.html deleted file mode 100644 index cd97b92e7..000000000 --- a/doc/sphinx/html/_modules/pymodbus/server/sync.html +++ /dev/null @@ -1,597 +0,0 @@ - - - - - - - - pymodbus.server.sync — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.server.sync

-'''
-Implementation of a Threaded Modbus Server
-------------------------------------------
-
-'''
-from binascii import b2a_hex
-import serial
-import socket
-import traceback
-
-from pymodbus.constants import Defaults
-from pymodbus.factory import ServerDecoder
-from pymodbus.datastore import ModbusServerContext
-from pymodbus.device import ModbusControlBlock
-from pymodbus.device import ModbusDeviceIdentification
-from pymodbus.transaction import *
-from pymodbus.exceptions import NotImplementedException, NoSuchSlaveException
-from pymodbus.pdu import ModbusExceptions as merror
-from pymodbus.compat import socketserver, byte2int
-
-#---------------------------------------------------------------------------#
-# Logging
-#---------------------------------------------------------------------------#
-import logging
-_logger = logging.getLogger(__name__)
-
-
-#---------------------------------------------------------------------------#
-# Protocol Handlers
-#---------------------------------------------------------------------------#
-
[docs]class ModbusBaseRequestHandler(socketserver.BaseRequestHandler): - ''' Implements the modbus server protocol - - This uses the socketserver.BaseRequestHandler to implement - the client handler. - ''' - -
[docs] def setup(self): - ''' Callback for when a client connects - ''' - _logger.debug("Client Connected [%s:%s]" % self.client_address) - self.running = True - self.framer = self.server.framer(self.server.decoder) - self.server.threads.append(self)
- -
[docs] def finish(self): - ''' Callback for when a client disconnects - ''' - _logger.debug("Client Disconnected [%s:%s]" % self.client_address) - self.server.threads.remove(self)
- -
[docs] def execute(self, request): - ''' The callback to call with the resulting message - - :param request: The decoded request message - ''' - try: - context = self.server.context[request.unit_id] - response = request.execute(context) - except NoSuchSlaveException as ex: - _logger.debug("requested slave does not exist: %s" % request.unit_id ) - if self.server.ignore_missing_slaves: - return # the client will simply timeout waiting for a response - response = request.doException(merror.GatewayNoResponse) - except Exception as ex: - _logger.debug("Datastore unable to fulfill request: %s; %s", ex, traceback.format_exc() ) - response = request.doException(merror.SlaveFailure) - response.transaction_id = request.transaction_id - response.unit_id = request.unit_id - self.send(response)
- - #---------------------------------------------------------------------------# - # Base class implementations - #---------------------------------------------------------------------------# -
[docs] def handle(self): - ''' Callback when we receive any data - ''' - raise NotImplementedException("Method not implemented by derived class")
- -
[docs] def send(self, message): - ''' Send a request (string) to the network - - :param message: The unencoded modbus response - ''' - raise NotImplementedException("Method not implemented by derived class")
- - -# class ModbusSingleRequestHandler(ModbusBaseRequestHandler): -# ''' Implements the modbus server protocol -# -# This uses the socketserver.BaseRequestHandler to implement -# the client handler for a single client(serial clients) -# ''' -# -# def handle(self): -# ''' Callback when we receive any data -# ''' -# while self.running: -# try: -# data = self.request.recv(1024) -# if data: -# if _logger.isEnabledFor(logging.DEBUG): -# _logger.debug(' '.join([hex(byte2int(x)) for x in data])) -# self.framer.processIncomingPacket(data, self.execute) -# except Exception as msg: -# # since we only have a single socket, we cannot exit -# _logger.error("Socket error occurred %s" % msg) -# -# def send(self, message): -# ''' Send a request (string) to the network -# -# :param message: The unencoded modbus response -# ''' - - -
[docs]class ModbusSingleRequestHandler(ModbusBaseRequestHandler): - ''' Implements the modbus server protocol - - This uses the socketserver.BaseRequestHandler to implement - the client handler for a single client(serial clients) - ''' - -
[docs] def handle(self): - ''' Callback when we receive any data - ''' - while self.running: - try: - data = self.request.recv(1024) - if data: - if _logger.isEnabledFor(logging.DEBUG): - _logger.debug(" ".join([hex(byte2int(x)) for x in data])) - self.framer.processIncomingPacket(data, self.execute) - except Exception as msg: - # since we only have a single socket, we cannot exit - _logger.error("Socket error occurred %s" % msg)
- -
[docs] def send(self, message): - ''' Send a request (string) to the network - - :param message: The unencoded modbus response - ''' - if message.should_respond: - #self.server.control.Counter.BusMessage += 1 - pdu = self.framer.buildPacket(message) - if _logger.isEnabledFor(logging.DEBUG): - _logger.debug('send: %s' % b2a_hex(pdu)) - return self.request.send(pdu)
- - -
[docs]class ModbusConnectedRequestHandler(ModbusBaseRequestHandler): - ''' Implements the modbus server protocol - - This uses the socketserver.BaseRequestHandler to implement - the client handler for a connected protocol (TCP). - ''' - -
[docs] def handle(self): - '''Callback when we receive any data, until self.running becomes not True. Blocks indefinitely - awaiting data. If shutdown is required, then the global socket.settimeout(<seconds>) may be - used, to allow timely checking of self.running. However, since this also affects socket - connects, if there are outgoing socket connections used in the same program, then these will - be prevented, if the specfied timeout is too short. Hence, this is unreliable. - - To respond to Modbus...Server.server_close() (which clears each handler's self.running), - derive from this class to provide an alternative handler that awakens from time to time when - no input is available and checks self.running. Use Modbus...Server( handler=... ) keyword - to supply the alternative request handler class. - - ''' - while self.running: - try: - data = self.request.recv(1024) - if not data: self.running = False - if _logger.isEnabledFor(logging.DEBUG): - _logger.debug(' '.join([hex(byte2int(x)) for x in data])) - # if not self.server.control.ListenOnly: - self.framer.processIncomingPacket(data, self.execute) - except socket.timeout as msg: - if _logger.isEnabledFor(logging.DEBUG): - _logger.debug("Socket timeout occurred %s", msg) - pass - except socket.error as msg: - _logger.error("Socket error occurred %s" % msg) - self.running = False - except: - _logger.error("Socket exception occurred %s" % traceback.format_exc() ) - self.running = False
- -
[docs] def send(self, message): - ''' Send a request (string) to the network - - :param message: The unencoded modbus response - ''' - if message.should_respond: - #self.server.control.Counter.BusMessage += 1 - pdu = self.framer.buildPacket(message) - if _logger.isEnabledFor(logging.DEBUG): - _logger.debug('send: %s' % b2a_hex(pdu)) - return self.request.send(pdu)
- - -
[docs]class ModbusDisconnectedRequestHandler(ModbusBaseRequestHandler): - ''' Implements the modbus server protocol - - This uses the socketserver.BaseRequestHandler to implement - the client handler for a disconnected protocol (UDP). The - only difference is that we have to specify who to send the - resulting packet data to. - ''' - -
[docs] def handle(self): - ''' Callback when we receive any data - ''' - while self.running: - try: - data, self.request = self.request - if not data: self.running = False - if _logger.isEnabledFor(logging.DEBUG): - _logger.debug(' '.join([hex(byte2int(x)) for x in data])) - # if not self.server.control.ListenOnly: - self.framer.processIncomingPacket(data, self.execute) - except socket.timeout: pass - except socket.error as msg: - _logger.error("Socket error occurred %s" % msg) - self.running = False - except: self.running = False
- -
[docs] def send(self, message): - ''' Send a request (string) to the network - - :param message: The unencoded modbus response - ''' - if message.should_respond: - #self.server.control.Counter.BusMessage += 1 - pdu = self.framer.buildPacket(message) - if _logger.isEnabledFor(logging.DEBUG): - _logger.debug('send: %s' % b2a_hex(pdu)) - return self.request.sendto(pdu, self.client_address)
- - -#---------------------------------------------------------------------------# -# Server Implementations -#---------------------------------------------------------------------------# -
[docs]class ModbusTcpServer(socketserver.ThreadingTCPServer): - ''' - A modbus threaded tcp socket server - - We inherit and overload the socket server so that we - can control the client threads as well as have a single - server context instance. - ''' - -
[docs] def __init__(self, context, framer=None, identity=None, address=None, handler=None, **kwargs): - ''' Overloaded initializer for the socket server - - If the identify structure is not passed in, the ModbusControlBlock - uses its own empty structure. - - :param context: The ModbusServerContext datastore - :param framer: The framer strategy to use - :param identity: An optional identify structure - :param address: An optional (interface, port) to bind to. - :param handler: A handler for each client session; default is ModbusConnectedRequestHandler - :param ignore_missing_slaves: True to not send errors on a request to a missing slave - ''' - self.threads = [] - self.decoder = ServerDecoder() - self.framer = framer or ModbusSocketFramer - self.context = context or ModbusServerContext() - self.control = ModbusControlBlock() - self.address = address or ("", Defaults.Port) - self.ignore_missing_slaves = kwargs.get('ignore_missing_slaves', Defaults.IgnoreMissingSlaves) - - if isinstance(identity, ModbusDeviceIdentification): - self.control.Identity.update(identity) - - socketserver.ThreadingTCPServer.__init__(self, - self.address, ModbusConnectedRequestHandler)
- -
[docs] def process_request(self, request, client): - ''' Callback for connecting a new client thread - - :param request: The request to handle - :param client: The address of the client - ''' - _logger.debug("Started thread to serve client at " + str(client)) - socketserver.ThreadingTCPServer.process_request(self, request, client)
- -
[docs] def shutdown(self): - ''' Stops the serve_forever loop. - - Overridden to signal handlers to stop. - ''' - for thread in self.threads: - thread.running = False - socketserver.ThreadingTCPServer.shutdown(self)
- -
[docs] def server_close(self): - ''' Callback for stopping the running server - ''' - _logger.debug("Modbus server stopped") - self.socket.close() - for thread in self.threads: - thread.running = False
- - -
[docs]class ModbusUdpServer(socketserver.ThreadingUDPServer): - ''' - A modbus threaded udp socket server - - We inherit and overload the socket server so that we - can control the client threads as well as have a single - server context instance. - ''' - -
[docs] def __init__(self, context, framer=None, identity=None, address=None, handler=None, **kwargs): - ''' Overloaded initializer for the socket server - - If the identify structure is not passed in, the ModbusControlBlock - uses its own empty structure. - - :param context: The ModbusServerContext datastore - :param framer: The framer strategy to use - :param identity: An optional identify structure - :param address: An optional (interface, port) to bind to. - :param handler: A handler for each client session; default is ModbusDisonnectedRequestHandler - :param ignore_missing_slaves: True to not send errors on a request to a missing slave - ''' - self.threads = [] - self.decoder = ServerDecoder() - self.framer = framer or ModbusSocketFramer - self.context = context or ModbusServerContext() - self.control = ModbusControlBlock() - self.address = address or ("", Defaults.Port) - self.ignore_missing_slaves = kwargs.get('ignore_missing_slaves', Defaults.IgnoreMissingSlaves) - - if isinstance(identity, ModbusDeviceIdentification): - self.control.Identity.update(identity) - - socketserver.ThreadingUDPServer.__init__(self, - self.address, ModbusDisconnectedRequestHandler)
- -
[docs] def process_request(self, request, client): - ''' Callback for connecting a new client thread - - :param request: The request to handle - :param client: The address of the client - ''' - packet, socket = request # TODO I might have to rewrite - _logger.debug("Started thread to serve client at " + str(client)) - socketserver.ThreadingUDPServer.process_request(self, request, client)
- -
[docs] def server_close(self): - ''' Callback for stopping the running server - ''' - _logger.debug("Modbus server stopped") - self.socket.close() - for thread in self.threads: - thread.running = False
- - -
[docs]class ModbusSerialServer(object): - ''' - A modbus threaded serial socket server - - We inherit and overload the socket server so that we - can control the client threads as well as have a single - server context instance. - ''' - -
[docs] def __init__(self, context, framer=None, identity=None, **kwargs): - ''' Overloaded initializer for the socket server - - If the identify structure is not passed in, the ModbusControlBlock - uses its own empty structure. - - :param context: The ModbusServerContext datastore - :param framer: The framer strategy to use - :param identity: An optional identify structure - :param port: The serial port to attach to - :param stopbits: The number of stop bits to use - :param bytesize: The bytesize of the serial messages - :param parity: Which kind of parity to use - :param baudrate: The baud rate to use for the serial device - :param timeout: The timeout to use for the serial device - :param ignore_missing_slaves: True to not send errors on a request to a missing slave - ''' - self.threads = [] - self.decoder = ServerDecoder() - self.framer = framer or ModbusAsciiFramer - self.context = context or ModbusServerContext() - self.control = ModbusControlBlock() - - if isinstance(identity, ModbusDeviceIdentification): - self.control.Identity.update(identity) - - self.device = kwargs.get('port', 0) - self.stopbits = kwargs.get('stopbits', Defaults.Stopbits) - self.bytesize = kwargs.get('bytesize', Defaults.Bytesize) - self.parity = kwargs.get('parity', Defaults.Parity) - self.baudrate = kwargs.get('baudrate', Defaults.Baudrate) - self.timeout = kwargs.get('timeout', Defaults.Timeout) - self.ignore_missing_slaves = kwargs.get('ignore_missing_slaves', Defaults.IgnoreMissingSlaves) - self.socket = None - self._connect() - self.is_running = True
- -
[docs] def _connect(self): - ''' Connect to the serial server - - :returns: True if connection succeeded, False otherwise - ''' - if self.socket: return True - try: - self.socket = serial.Serial(port=self.device, timeout=self.timeout, - bytesize=self.bytesize, stopbits=self.stopbits, - baudrate=self.baudrate, parity=self.parity) - except serial.SerialException as msg: - _logger.error(msg) - return self.socket != None
- -
[docs] def _build_handler(self): - ''' A helper method to create and monkeypatch - a serial handler. - - :returns: A patched handler - ''' - request = self.socket - request.send = request.write - request.recv = request.read - handler = ModbusSingleRequestHandler(request, - (self.device, self.device), self) - return handler
- -
[docs] def serve_forever(self): - ''' Callback for connecting a new client thread - - :param request: The request to handle - :param client: The address of the client - ''' - _logger.debug("Started thread to serve client") - handler = self._build_handler() - while self.is_running: - handler.handle()
- -
[docs] def server_close(self): - ''' Callback for stopping the running server - ''' - _logger.debug("Modbus server stopped") - self.is_running = False - self.socket.close()
- - -#---------------------------------------------------------------------------# -# Creation Factories -#---------------------------------------------------------------------------# -
[docs]def StartTcpServer(context=None, identity=None, address=None, **kwargs): - ''' A factory to start and run a tcp modbus server - - :param context: The ModbusServerContext datastore - :param identity: An optional identify structure - :param address: An optional (interface, port) to bind to. - :param ignore_missing_slaves: True to not send errors on a request to a missing slave - ''' - framer = ModbusSocketFramer - server = ModbusTcpServer(context, framer, identity, address, **kwargs) - server.serve_forever()
- - -
[docs]def StartUdpServer(context=None, identity=None, address=None, **kwargs): - ''' A factory to start and run a udp modbus server - - :param context: The ModbusServerContext datastore - :param identity: An optional identify structure - :param address: An optional (interface, port) to bind to. - :param framer: The framer to operate with (default ModbusSocketFramer) - :param ignore_missing_slaves: True to not send errors on a request to a missing slave - ''' - framer = kwargs.pop('framer', ModbusSocketFramer) - server = ModbusUdpServer(context, framer, identity, address, **kwargs) - server.serve_forever()
- - -
[docs]def StartSerialServer(context=None, identity=None, **kwargs): - ''' A factory to start and run a serial modbus server - - :param context: The ModbusServerContext datastore - :param identity: An optional identify structure - :param framer: The framer to operate with (default ModbusAsciiFramer) - :param port: The serial port to attach to - :param stopbits: The number of stop bits to use - :param bytesize: The bytesize of the serial messages - :param parity: Which kind of parity to use - :param baudrate: The baud rate to use for the serial device - :param timeout: The timeout to use for the serial device - :param ignore_missing_slaves: True to not send errors on a request to a missing slave - ''' - framer = kwargs.pop('framer', ModbusAsciiFramer) - server = ModbusSerialServer(context, framer, identity, **kwargs) - server.serve_forever()
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "StartTcpServer", "StartUdpServer", "StartSerialServer" -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/transaction.html b/doc/sphinx/html/_modules/pymodbus/transaction.html deleted file mode 100644 index c7d53ea22..000000000 --- a/doc/sphinx/html/_modules/pymodbus/transaction.html +++ /dev/null @@ -1,1064 +0,0 @@ - - - - - - - - pymodbus.transaction — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.transaction

-'''
-Collection of transaction based abstractions
-'''
-import sys
-import struct
-import socket
-from binascii import b2a_hex, a2b_hex
-
-from pymodbus.exceptions import ModbusIOException, NotImplementedException
-from pymodbus.constants  import Defaults
-from pymodbus.interfaces import IModbusFramer
-from pymodbus.utilities  import checkCRC, computeCRC
-from pymodbus.utilities  import checkLRC, computeLRC
-from pymodbus.compat import iterkeys, imap, byte2int
-
-#---------------------------------------------------------------------------#
-# Logging
-#---------------------------------------------------------------------------#
-import logging
-_logger = logging.getLogger(__name__)
-
-
-#---------------------------------------------------------------------------#
-# The Global Transaction Manager
-#---------------------------------------------------------------------------#
-class ModbusTransactionManager(object):
-    ''' Impelements a transaction for a manager
-
-    The transaction protocol can be represented by the following pseudo code::
-
-        count = 0
-        do
-          result = send(message)
-          if (timeout or result == bad)
-             count++
-          else break
-        while (count < 3)
-
-    This module helps to abstract this away from the framer and protocol.
-    '''
-
-    def __init__(self, client, **kwargs):
-        ''' Initializes an instance of the ModbusTransactionManager
-
-        :param client: The client socket wrapper
-        :param retry_on_empty: Should the client retry on empty
-        :param retries: The number of retries to allow
-        '''
-        self.tid = Defaults.TransactionId
-        self.client = client
-        self.retry_on_empty = kwargs.get('retry_on_empty', Defaults.RetryOnEmpty)
-        self.retries = kwargs.get('retries', Defaults.Retries)
-        if client:
-            self._set_adu_size()
-
-    def _set_adu_size(self):
-        # base ADU size of modbus frame in bytes
-        if isinstance(self.client.framer, ModbusSocketFramer):
-            self.base_adu_size = 7 # tid(2), pid(2), length(2), uid(1)
-        elif isinstance(self.client.framer, ModbusRtuFramer):
-            self.base_adu_size = 3 # address(1), CRC(2)
-        elif isinstance(self.client.framer, ModbusAsciiFramer):
-            self.base_adu_size = 4 # Address(2), LRC(2)
-        elif isinstance(self.client.framer, ModbusBinaryFramer):
-            self.base_adu_size = 3 #, Address(1), CRC(2)
-        else:
-            self.base_adu_size = -1
-
-    def _calculate_response_length(self, expected_pdu_size):
-        if self.base_adu_size == -1:
-            return 1024
-        else:
-            return self.base_adu_size + expected_pdu_size
-
-    def execute(self, request):
-        ''' Starts the producer to send the next request to
-        consumer.write(Frame(request))
-        '''
-        retries = self.retries
-        request.transaction_id = self.getNextTID()
-        _logger.debug("Running transaction %d" % request.transaction_id)
-        if hasattr(request, "get_response_pdu_size"):
-            response_pdu_size = request.get_response_pdu_size()
-            expected_response_length = self._calculate_response_length(response_pdu_size)
-        else:
-            expected_response_length = 1024
-
-        while retries > 0:
-            try:
-                self.client.connect()
-                self.client._send(self.client.framer.buildPacket(request))
-                result = self.client._recv(expected_response_length)
-
-                if not result and self.retry_on_empty:
-                    retries -= 1
-                    continue
-                if _logger.isEnabledFor(logging.DEBUG):
-                    _logger.debug("recv: " + " ".join([hex(byte2int(x)) for x in result]))
-                self.client.framer.processIncomingPacket(result, self.addTransaction)
-                break;
-            except socket.error as msg:
-                self.client.close()
-                _logger.debug("Transaction failed. (%s) " % msg)
-                retries -= 1
-        return self.getTransaction(request.transaction_id)
-
-
-    def addTransaction(self, request, tid=None):
-        ''' Adds a transaction to the handler
-
-        This holds the requets in case it needs to be resent.
-        After being sent, the request is removed.
-
-        :param request: The request to hold on to
-        :param tid: The overloaded transaction id to use
-        '''
-        raise NotImplementedException("addTransaction")
-
-    def getTransaction(self, tid):
-        ''' Returns a transaction matching the referenced tid
-
-        If the transaction does not exist, None is returned
-
-        :param tid: The transaction to retrieve
-        '''
-        raise NotImplementedException("getTransaction")
-
-    def delTransaction(self, tid):
-        ''' Removes a transaction matching the referenced tid
-
-        :param tid: The transaction to remove
-        '''
-        raise NotImplementedException("delTransaction")
-
-    def getNextTID(self):
-        ''' Retrieve the next unique transaction identifier
-
-        This handles incrementing the identifier after
-        retrieval
-
-        :returns: The next unique transaction identifier
-        '''
-        self.tid = (self.tid + 1) & 0xffff
-        return self.tid
-
-    def reset(self):
-        ''' Resets the transaction identifier '''
-        self.tid = Defaults.TransactionId
-        self.transactions = type(self.transactions)()
-
-
-
[docs]class DictTransactionManager(ModbusTransactionManager): - ''' Impelements a transaction for a manager where the - results are keyed based on the supplied transaction id. - ''' - -
[docs] def __init__(self, client, **kwargs): - ''' Initializes an instance of the ModbusTransactionManager - - :param client: The client socket wrapper - ''' - self.transactions = {} - super(DictTransactionManager, self).__init__(client, **kwargs)
- -
[docs] def __iter__(self): - ''' Iterater over the current managed transactions - - :returns: An iterator of the managed transactions - ''' - return iterkeys(self.transactions)
- -
[docs] def addTransaction(self, request, tid=None): - ''' Adds a transaction to the handler - - This holds the requets in case it needs to be resent. - After being sent, the request is removed. - - :param request: The request to hold on to - :param tid: The overloaded transaction id to use - ''' - tid = tid if tid != None else request.transaction_id - _logger.debug("adding transaction %d" % tid) - self.transactions[tid] = request
- -
[docs] def getTransaction(self, tid): - ''' Returns a transaction matching the referenced tid - - If the transaction does not exist, None is returned - - :param tid: The transaction to retrieve - ''' - _logger.debug("getting transaction %d" % tid) - return self.transactions.pop(tid, None)
- -
[docs] def delTransaction(self, tid): - ''' Removes a transaction matching the referenced tid - - :param tid: The transaction to remove - ''' - _logger.debug("deleting transaction %d" % tid) - self.transactions.pop(tid, None)
- - -
[docs]class FifoTransactionManager(ModbusTransactionManager): - ''' Impelements a transaction for a manager where the - results are returned in a FIFO manner. - ''' - -
[docs] def __init__(self, client, **kwargs): - ''' Initializes an instance of the ModbusTransactionManager - - :param client: The client socket wrapper - ''' - super(FifoTransactionManager, self).__init__(client, **kwargs) - self.transactions = []
- -
[docs] def __iter__(self): - ''' Iterater over the current managed transactions - - :returns: An iterator of the managed transactions - ''' - return iter(self.transactions)
- -
[docs] def addTransaction(self, request, tid=None): - ''' Adds a transaction to the handler - - This holds the requets in case it needs to be resent. - After being sent, the request is removed. - - :param request: The request to hold on to - :param tid: The overloaded transaction id to use - ''' - tid = tid if tid != None else request.transaction_id - _logger.debug("adding transaction %d" % tid) - self.transactions.append(request)
- -
[docs] def getTransaction(self, tid): - ''' Returns a transaction matching the referenced tid - - If the transaction does not exist, None is returned - - :param tid: The transaction to retrieve - ''' - _logger.debug("getting transaction %s" % str(tid)) - return self.transactions.pop(0) if self.transactions else None
- -
[docs] def delTransaction(self, tid): - ''' Removes a transaction matching the referenced tid - - :param tid: The transaction to remove - ''' - _logger.debug("deleting transaction %d" % tid) - if self.transactions: self.transactions.pop(0)
- - -#---------------------------------------------------------------------------# -# Modbus TCP Message -#---------------------------------------------------------------------------# -
[docs]class ModbusSocketFramer(IModbusFramer): - ''' Modbus Socket Frame controller - - Before each modbus TCP message is an MBAP header which is used as a - message frame. It allows us to easily separate messages as follows:: - - [ MBAP Header ] [ Function Code] [ Data ] - [ tid ][ pid ][ length ][ uid ] - 2b 2b 2b 1b 1b Nb - - while len(message) > 0: - tid, pid, length`, uid = struct.unpack(">HHHB", message) - request = message[0:7 + length - 1`] - message = [7 + length - 1:] - - * length = uid + function code + data - * The -1 is to account for the uid byte - ''' - -
[docs] def __init__(self, decoder): - ''' Initializes a new instance of the framer - - :param decoder: The decoder factory implementation to use - ''' - self.__buffer = b'' - self.__header = {'tid':0, 'pid':0, 'len':0, 'uid':0} - self.__hsize = 0x07 - self.decoder = decoder
- - #-----------------------------------------------------------------------# - # Private Helper Functions - #-----------------------------------------------------------------------# -
[docs] def checkFrame(self): - ''' - Check and decode the next frame Return true if we were successful - ''' - if len(self.__buffer) > self.__hsize: - self.__header['tid'], self.__header['pid'], \ - self.__header['len'], self.__header['uid'] = struct.unpack( - '>HHHB', self.__buffer[0:self.__hsize]) - - # someone sent us an error? ignore it - if self.__header['len'] < 2: - self.advanceFrame() - # we have at least a complete message, continue - elif len(self.__buffer) - self.__hsize + 1 >= self.__header['len']: - return True - # we don't have enough of a message yet, wait - return False
- -
[docs] def advanceFrame(self): - ''' Skip over the current framed message - This allows us to skip over the current message after we have processed - it or determined that it contains an error. It also has to reset the - current frame header handle - ''' - length = self.__hsize + self.__header['len'] - 1 - self.__buffer = self.__buffer[length:] - self.__header = {'tid':0, 'pid':0, 'len':0, 'uid':0}
- -
[docs] def isFrameReady(self): - ''' Check if we should continue decode logic - This is meant to be used in a while loop in the decoding phase to let - the decoder factory know that there is still data in the buffer. - - :returns: True if ready, False otherwise - ''' - return len(self.__buffer) > self.__hsize
- -
[docs] def addToFrame(self, message): - ''' Adds new packet data to the current frame buffer - - :param message: The most recent packet - ''' - self.__buffer += message
- -
[docs] def getFrame(self): - ''' Return the next frame from the buffered data - - :returns: The next full frame buffer - ''' - length = self.__hsize + self.__header['len'] - 1 - return self.__buffer[self.__hsize:length]
- -
[docs] def populateResult(self, result): - ''' - Populates the modbus result with the transport specific header - information (pid, tid, uid, checksum, etc) - - :param result: The response packet - ''' - result.transaction_id = self.__header['tid'] - result.protocol_id = self.__header['pid'] - result.unit_id = self.__header['uid']
- - #-----------------------------------------------------------------------# - # Public Member Functions - #-----------------------------------------------------------------------# -
[docs] def processIncomingPacket(self, data, callback): - ''' The new packet processing pattern - - This takes in a new request packet, adds it to the current - packet stream, and performs framing on it. That is, checks - for complete messages, and once found, will process all that - exist. This handles the case when we read N + 1 or 1 / N - messages at a time instead of 1. - - The processed and decoded messages are pushed to the callback - function to process and send. - - :param data: The new packet data - :param callback: The function to send results to - ''' - _logger.debug(' '.join([hex(byte2int(x)) for x in data])) - self.addToFrame(data) - while True: - if self.isFrameReady(): - if self.checkFrame(): - self._process(callback) - else: self.resetFrame() - else: - if len(self.__buffer): - # Possible error ??? - if self.__header['len'] < 2: - self._process(callback, error=True) - break
- -
[docs] def _process(self, callback, error=False): - """ - Process incoming packets irrespective error condition - """ - data = self.getRawFrame() if error else self.getFrame() - result = self.decoder.decode(data) - if result is None: - raise ModbusIOException("Unable to decode request") - self.populateResult(result) - self.advanceFrame() - callback(result) # defer or push to a thread?
- -
[docs] def resetFrame(self): - ''' Reset the entire message frame. - This allows us to skip ovver errors that may be in the stream. - It is hard to know if we are simply out of sync or if there is - an error in the stream as we have no way to check the start or - end of the message (python just doesn't have the resolution to - check for millisecond delays). - ''' - self.__buffer = '' - self.__header = {}
- -
[docs] def getRawFrame(self): - """ - Returns the complete buffer - """ - return self.__buffer
- -
[docs] def buildPacket(self, message): - ''' Creates a ready to send modbus packet - - :param message: The populated request/response to send - ''' - data = message.encode() - packet = struct.pack('>HHHBB', - message.transaction_id, - message.protocol_id, - len(data) + 2, - message.unit_id, - message.function_code) + data - return packet
- - -#---------------------------------------------------------------------------# -# Modbus RTU Message -#---------------------------------------------------------------------------# -
[docs]class ModbusRtuFramer(IModbusFramer): - ''' - Modbus RTU Frame controller:: - - [ Start Wait ] [Address ][ Function Code] [ Data ][ CRC ][ End Wait ] - 3.5 chars 1b 1b Nb 2b 3.5 chars - - Wait refers to the amount of time required to transmist at least x many - characters. In this case it is 3.5 characters. Also, if we recieve a - wait of 1.5 characters at any point, we must trigger an error message. - Also, it appears as though this message is little endian. The logic is - simplified as the following:: - - block-on-read: - read until 3.5 delay - check for errors - decode - - The following table is a listing of the baud wait times for the specified - baud rates:: - - ------------------------------------------------------------------ - Baud 1.5c (18 bits) 3.5c (38 bits) - ------------------------------------------------------------------ - 1200 13333.3 us 31666.7 us - 4800 3333.3 us 7916.7 us - 9600 1666.7 us 3958.3 us - 19200 833.3 us 1979.2 us - 38400 416.7 us 989.6 us - ------------------------------------------------------------------ - 1 Byte = start + 8 bits + parity + stop = 11 bits - (1/Baud)(bits) = delay seconds - ''' - -
[docs] def __init__(self, decoder): - ''' Initializes a new instance of the framer - - :param decoder: The decoder factory implementation to use - ''' - self.__buffer = b'' - self.__header = {} - self.__hsize = 0x01 - self.__end = b'\x0d\x0a' - self.__min_frame_size = 4 - self.decoder = decoder
- - #-----------------------------------------------------------------------# - # Private Helper Functions - #-----------------------------------------------------------------------# -
[docs] def checkFrame(self): - ''' - Check if the next frame is available. Return True if we were - successful. - ''' - try: - self.populateHeader() - frame_size = self.__header['len'] - data = self.__buffer[:frame_size - 2] - crc = self.__buffer[frame_size - 2:frame_size] - crc_val = (byte2int(crc[0]) << 8) + byte2int(crc[1]) - return checkCRC(data, crc_val) - except (IndexError, KeyError): - return False
- -
[docs] def advanceFrame(self): - ''' Skip over the current framed message - This allows us to skip over the current message after we have processed - it or determined that it contains an error. It also has to reset the - current frame header handle - ''' - try: - self.__buffer = self.__buffer[self.__header['len']:] - except KeyError: - # Error response, no header len found - self.resetFrame() - self.__header = {}
- -
[docs] def resetFrame(self): - ''' Reset the entire message frame. - This allows us to skip ovver errors that may be in the stream. - It is hard to know if we are simply out of sync or if there is - an error in the stream as we have no way to check the start or - end of the message (python just doesn't have the resolution to - check for millisecond delays). - ''' - self.__buffer = b'' - self.__header = {}
- -
[docs] def isFrameReady(self): - ''' Check if we should continue decode logic - This is meant to be used in a while loop in the decoding phase to let - the decoder know that there is still data in the buffer. - - :returns: True if ready, False otherwise - ''' - return len(self.__buffer) > self.__hsize
- -
[docs] def populateHeader(self): - ''' Try to set the headers `uid`, `len` and `crc`. - - This method examines `self.__buffer` and writes meta - information into `self.__header`. It calculates only the - values for headers that are not already in the dictionary. - - Beware that this method will raise an IndexError if - `self.__buffer` is not yet long enough. - ''' - self.__header['uid'] = byte2int(self.__buffer[0]) - func_code = byte2int(self.__buffer[1]) - pdu_class = self.decoder.lookupPduClass(func_code) - size = pdu_class.calculateRtuFrameSize(self.__buffer) - self.__header['len'] = size - self.__header['crc'] = self.__buffer[size - 2:size]
- -
[docs] def addToFrame(self, message): - ''' - This should be used before the decoding while loop to add the received - data to the buffer handle. - - :param message: The most recent packet - ''' - self.__buffer += message
- -
[docs] def getFrame(self): - ''' Get the next frame from the buffer - - :returns: The frame data or '' - ''' - start = self.__hsize - end = self.__header['len'] - 2 - buffer = self.__buffer[start:end] - if end > 0: return buffer - return ''
- -
[docs] def populateResult(self, result): - ''' Populates the modbus result header - - The serial packets do not have any header information - that is copied. - - :param result: The response packet - ''' - result.unit_id = self.__header['uid']
- - #-----------------------------------------------------------------------# - # Public Member Functions - #-----------------------------------------------------------------------# -
[docs] def processIncomingPacket(self, data, callback): - ''' The new packet processing pattern - - This takes in a new request packet, adds it to the current - packet stream, and performs framing on it. That is, checks - for complete messages, and once found, will process all that - exist. This handles the case when we read N + 1 or 1 / N - messages at a time instead of 1. - - The processed and decoded messages are pushed to the callback - function to process and send. - - :param data: The new packet data - :param callback: The function to send results to - ''' - self.addToFrame(data) - while True: - if self.isFrameReady(): - if self.checkFrame(): - self._process(callback) - else: - # Could be an error response - if len(self.__buffer): - # Possible error ??? - self._process(callback, error=True) - else: - if len(self.__buffer): - # Possible error ??? - if self.__header.get('len', 0) < 2: - self._process(callback, error=True) - break
- -
[docs] def buildPacket(self, message): - ''' Creates a ready to send modbus packet - - :param message: The populated request/response to send - ''' - data = message.encode() - packet = struct.pack('>BB', - message.unit_id, - message.function_code) + data - packet += struct.pack(">H", computeCRC(packet)) - return packet
- -
[docs] def _process(self, callback, error=False): - """ - Process incoming packets irrespective error condition - """ - data = self.getRawFrame() if error else self.getFrame() - result = self.decoder.decode(data) - if result is None: - raise ModbusIOException("Unable to decode request") - self.populateResult(result) - self.advanceFrame() - callback(result) # defer or push to a thread?
- -
[docs] def getRawFrame(self): - """ - Returns the complete buffer - """ - return self.__buffer
- - - -#---------------------------------------------------------------------------# -# Modbus ASCII Message -#---------------------------------------------------------------------------# -
[docs]class ModbusAsciiFramer(IModbusFramer): - ''' - Modbus ASCII Frame Controller:: - - [ Start ][Address ][ Function ][ Data ][ LRC ][ End ] - 1c 2c 2c Nc 2c 2c - - * data can be 0 - 2x252 chars - * end is '\\r\\n' (Carriage return line feed), however the line feed - character can be changed via a special command - * start is ':' - - This framer is used for serial transmission. Unlike the RTU protocol, - the data in this framer is transferred in plain text ascii. - ''' - -
[docs] def __init__(self, decoder): - ''' Initializes a new instance of the framer - - :param decoder: The decoder implementation to use - ''' - self.__buffer = b'' - self.__header = {'lrc':'0000', 'len':0, 'uid':0x00} - self.__hsize = 0x02 - self.__start = b':' - self.__end = b"\r\n" - self.decoder = decoder
- - #-----------------------------------------------------------------------# - # Private Helper Functions - #-----------------------------------------------------------------------# -
[docs] def checkFrame(self): - ''' Check and decode the next frame - - :returns: True if we successful, False otherwise - ''' - start = self.__buffer.find(self.__start) - if start == -1: return False - if start > 0 : # go ahead and skip old bad data - self.__buffer = self.__buffer[start:] - start = 0 - - end = self.__buffer.find(self.__end) - if (end != -1): - self.__header['len'] = end - self.__header['uid'] = int(self.__buffer[1:3], 16) - self.__header['lrc'] = int(self.__buffer[end - 2:end], 16) - data = a2b_hex(self.__buffer[start + 1:end - 2]) - return checkLRC(data, self.__header['lrc']) - return False
- -
[docs] def advanceFrame(self): - ''' Skip over the current framed message - This allows us to skip over the current message after we have processed - it or determined that it contains an error. It also has to reset the - current frame header handle - ''' - self.__buffer = self.__buffer[self.__header['len'] + 2:] - self.__header = {'lrc':'0000', 'len':0, 'uid':0x00}
- -
[docs] def isFrameReady(self): - ''' Check if we should continue decode logic - This is meant to be used in a while loop in the decoding phase to let - the decoder know that there is still data in the buffer. - - :returns: True if ready, False otherwise - ''' - return len(self.__buffer) > 1
- -
[docs] def addToFrame(self, message): - ''' Add the next message to the frame buffer - This should be used before the decoding while loop to add the received - data to the buffer handle. - - :param message: The most recent packet - ''' - self.__buffer += message
- -
[docs] def getFrame(self): - ''' Get the next frame from the buffer - - :returns: The frame data or '' - ''' - start = self.__hsize + 1 - end = self.__header['len'] - 2 - buffer = self.__buffer[start:end] - if end > 0: return a2b_hex(buffer) - return b''
- -
[docs] def populateResult(self, result): - ''' Populates the modbus result header - - The serial packets do not have any header information - that is copied. - - :param result: The response packet - ''' - result.unit_id = self.__header['uid']
- - #-----------------------------------------------------------------------# - # Public Member Functions - #-----------------------------------------------------------------------# -
[docs] def processIncomingPacket(self, data, callback): - ''' The new packet processing pattern - - This takes in a new request packet, adds it to the current - packet stream, and performs framing on it. That is, checks - for complete messages, and once found, will process all that - exist. This handles the case when we read N + 1 or 1 / N - messages at a time instead of 1. - - The processed and decoded messages are pushed to the callback - function to process and send. - - :param data: The new packet data - :param callback: The function to send results to - ''' - self.addToFrame(data) - while self.isFrameReady(): - if self.checkFrame(): - result = self.decoder.decode(self.getFrame()) - if result is None: - raise ModbusIOException("Unable to decode response") - self.populateResult(result) - self.advanceFrame() - callback(result) # defer this - else: break
- -
[docs] def buildPacket(self, message): - ''' Creates a ready to send modbus packet - Built off of a modbus request/response - - :param message: The request/response to send - :return: The encoded packet - ''' - encoded = message.encode() - buffer = struct.pack('>BB', message.unit_id, message.function_code) - checksum = computeLRC(encoded + buffer) - - packet = bytearray() - params = (message.unit_id, message.function_code) - packet.extend(self.__start) - packet.extend(('%02x%02x' % params).encode()) - packet.extend(b2a_hex(encoded)) - packet.extend(('%02x' % checksum).encode()) - packet.extend(self.__end) - return bytes(packet).upper()
- - -#---------------------------------------------------------------------------# -# Modbus Binary Message -#---------------------------------------------------------------------------# -
[docs]class ModbusBinaryFramer(IModbusFramer): - ''' - Modbus Binary Frame Controller:: - - [ Start ][Address ][ Function ][ Data ][ CRC ][ End ] - 1b 1b 1b Nb 2b 1b - - * data can be 0 - 2x252 chars - * end is '}' - * start is '{' - - The idea here is that we implement the RTU protocol, however, - instead of using timing for message delimiting, we use start - and end of message characters (in this case { and }). Basically, - this is a binary framer. - - The only case we have to watch out for is when a message contains - the { or } characters. If we encounter these characters, we - simply duplicate them. Hopefully we will not encounter those - characters that often and will save a little bit of bandwitch - without a real-time system. - - Protocol defined by jamod.sourceforge.net. - ''' - -
[docs] def __init__(self, decoder): - ''' Initializes a new instance of the framer - - :param decoder: The decoder implementation to use - ''' - self.__buffer = b'' - self.__header = {'crc':0x0000, 'len':0, 'uid':0x00} - self.__hsize = 0x02 - self.__start = b'\x7b' # { - self.__end = b'\x7d' # } - self.__repeat = [b'}'[0], b'{'[0]] # python3 hack - self.decoder = decoder
- - #-----------------------------------------------------------------------# - # Private Helper Functions - #-----------------------------------------------------------------------# -
[docs] def checkFrame(self): - ''' Check and decode the next frame - - :returns: True if we are successful, False otherwise - ''' - start = self.__buffer.find(self.__start) - if start == -1: return False - if start > 0 : # go ahead and skip old bad data - self.__buffer = self.__buffer[start:] - - end = self.__buffer.find(self.__end) - if (end != -1): - self.__header['len'] = end - self.__header['uid'] = struct.unpack('>B', self.__buffer[1:2]) - self.__header['crc'] = struct.unpack('>H', self.__buffer[end - 2:end])[0] - data = self.__buffer[start + 1:end - 2] - return checkCRC(data, self.__header['crc']) - return False
- -
[docs] def advanceFrame(self): - ''' Skip over the current framed message - This allows us to skip over the current message after we have processed - it or determined that it contains an error. It also has to reset the - current frame header handle - ''' - self.__buffer = self.__buffer[self.__header['len'] + 2:] - self.__header = {'crc':0x0000, 'len':0, 'uid':0x00}
- -
[docs] def isFrameReady(self): - ''' Check if we should continue decode logic - This is meant to be used in a while loop in the decoding phase to let - the decoder know that there is still data in the buffer. - - :returns: True if ready, False otherwise - ''' - return len(self.__buffer) > 1
- -
[docs] def addToFrame(self, message): - ''' Add the next message to the frame buffer - This should be used before the decoding while loop to add the received - data to the buffer handle. - - :param message: The most recent packet - ''' - self.__buffer += message
- -
[docs] def getFrame(self): - ''' Get the next frame from the buffer - - :returns: The frame data or '' - ''' - start = self.__hsize + 1 - end = self.__header['len'] - 2 - buffer = self.__buffer[start:end] - if end > 0: return buffer - return b''
- -
[docs] def populateResult(self, result): - ''' Populates the modbus result header - - The serial packets do not have any header information - that is copied. - - :param result: The response packet - ''' - result.unit_id = self.__header['uid']
- - #-----------------------------------------------------------------------# - # Public Member Functions - #-----------------------------------------------------------------------# -
[docs] def processIncomingPacket(self, data, callback): - ''' The new packet processing pattern - - This takes in a new request packet, adds it to the current - packet stream, and performs framing on it. That is, checks - for complete messages, and once found, will process all that - exist. This handles the case when we read N + 1 or 1 / N - messages at a time instead of 1. - - The processed and decoded messages are pushed to the callback - function to process and send. - - :param data: The new packet data - :param callback: The function to send results to - ''' - self.addToFrame(data) - while self.isFrameReady(): - if self.checkFrame(): - result = self.decoder.decode(self.getFrame()) - if result is None: - raise ModbusIOException("Unable to decode response") - self.populateResult(result) - self.advanceFrame() - callback(result) # defer or push to a thread? - else: break
- -
[docs] def buildPacket(self, message): - ''' Creates a ready to send modbus packet - - :param message: The request/response to send - :returns: The encoded packet - ''' - data = self._preflight(message.encode()) - packet = struct.pack('>BB', - message.unit_id, - message.function_code) + data - packet += struct.pack(">H", computeCRC(packet)) - packet = self.__start + packet + self.__end - return packet
- -
[docs] def _preflight(self, data): - ''' Preflight buffer test - - This basically scans the buffer for start and end - tags and if found, escapes them. - - :param data: The message to escape - :returns: the escaped packet - ''' - array = bytearray() - for d in data: - if d in self.__repeat: - array.append(d) - array.append(d) - return bytes(array)
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - "FifoTransactionManager", - "DictTransactionManager", - "ModbusSocketFramer", "ModbusRtuFramer", - "ModbusAsciiFramer", "ModbusBinaryFramer", -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_modules/pymodbus/utilities.html b/doc/sphinx/html/_modules/pymodbus/utilities.html deleted file mode 100644 index a81af94bf..000000000 --- a/doc/sphinx/html/_modules/pymodbus/utilities.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - - - - pymodbus.utilities — pymodbus 1.3.0.rc2 documentation - - - - - - - - - - - - - - -
-
-
-
- -

Source code for pymodbus.utilities

-'''
-Modbus Utilities
------------------
-
-A collection of utilities for packing data, unpacking
-data computing checksums, and decode checksums.
-'''
-from pymodbus.compat import int2byte, byte2int
-
-
-#---------------------------------------------------------------------------#
-# Helpers
-#---------------------------------------------------------------------------#
-
[docs]def default(value): - ''' - Given a python object, return the default value - of that object. - - :param value: The value to get the default of - :returns: The default value - ''' - return type(value)()
- - -
[docs]def dict_property(store, index): - ''' Helper to create class properties from a dictionary. - Basically this allows you to remove a lot of possible - boilerplate code. - - :param store: The store store to pull from - :param index: The index into the store to close over - :returns: An initialized property set - ''' - if hasattr(store, '__call__'): - getter = lambda self: store(self)[index] - setter = lambda self, value: store(self).__setitem__(index, value) - elif isinstance(store, str): - getter = lambda self: self.__getattribute__(store)[index] - setter = lambda self, value: self.__getattribute__(store).__setitem__( - index, value) - else: - getter = lambda self: store[index] - setter = lambda self, value: store.__setitem__(index, value) - - return property(getter, setter)
- - -#---------------------------------------------------------------------------# -# Bit packing functions -#---------------------------------------------------------------------------# -
[docs]def pack_bitstring(bits): - ''' Creates a string out of an array of bits - - :param bits: A bit array - - example:: - - bits = [False, True, False, True] - result = pack_bitstring(bits) - ''' - ret = b'' - i = packed = 0 - for bit in bits: - if bit: packed += 128 - i += 1 - if i == 8: - ret += int2byte(packed) - i = packed = 0 - else: packed >>= 1 - if i > 0 and i < 8: - packed >>= (7 - i) - ret += int2byte(packed) - return ret
- - -
[docs]def unpack_bitstring(string): - ''' Creates bit array out of a string - - :param string: The modbus data packet to decode - - example:: - - bytes = 'bytes to decode' - result = unpack_bitstring(bytes) - ''' - byte_count = len(string) - bits = [] - for byte in range(byte_count): - value = byte2int(string[byte]) - for _ in range(8): - bits.append((value & 1) == 1) - value >>= 1 - return bits
- - -#---------------------------------------------------------------------------# -# Error Detection Functions -#---------------------------------------------------------------------------# -
[docs]def __generate_crc16_table(): - ''' Generates a crc16 lookup table - - .. note:: This will only be generated once - ''' - result = [] - for byte in range(256): - crc = 0x0000 - for _ in range(8): - if (byte ^ crc) & 0x0001: - crc = (crc >> 1) ^ 0xa001 - else: crc >>= 1 - byte >>= 1 - result.append(crc) - return result
- -__crc16_table = __generate_crc16_table() - - -
[docs]def computeCRC(data): - ''' Computes a crc16 on the passed in string. For modbus, - this is only used on the binary serial protocols (in this - case RTU). - - The difference between modbus's crc16 and a normal crc16 - is that modbus starts the crc value out at 0xffff. - - :param data: The data to create a crc16 of - :returns: The calculated CRC - ''' - crc = 0xffff - for a in data: - idx = __crc16_table[(crc ^ byte2int(a)) & 0xff]; - crc = ((crc >> 8) & 0xff) ^ idx - swapped = ((crc << 8) & 0xff00) | ((crc >> 8) & 0x00ff) - return swapped
- - -
[docs]def checkCRC(data, check): - ''' Checks if the data matches the passed in CRC - - :param data: The data to create a crc16 of - :param check: The CRC to validate - :returns: True if matched, False otherwise - ''' - return computeCRC(data) == check
- - -
[docs]def computeLRC(data): - ''' Used to compute the longitudinal redundancy check - against a string. This is only used on the serial ASCII - modbus protocol. A full description of this implementation - can be found in appendex B of the serial line modbus description. - - :param data: The data to apply a lrc to - :returns: The calculated LRC - - ''' - lrc = sum(byte2int(a) for a in data) & 0xff - lrc = (lrc ^ 0xff) + 1 - return lrc & 0xff
- - -
[docs]def checkLRC(data, check): - ''' Checks if the passed in data matches the LRC - - :param data: The data to calculate - :param check: The LRC to validate - :returns: True if matched, False otherwise - ''' - return computeLRC(data) == check
- - -
[docs]def rtuFrameSize(data, byte_count_pos): - ''' Calculates the size of the frame based on the byte count. - - :param data: The buffer containing the frame. - :param byte_count_pos: The index of the byte count in the buffer. - :returns: The size of the frame. - - The structure of frames with a byte count field is always the - same: - - - first, there are some header fields - - then the byte count field - - then as many data bytes as indicated by the byte count, - - finally the CRC (two bytes). - - To calculate the frame size, it is therefore sufficient to extract - the contents of the byte count field, add the position of this - field, and finally increment the sum by three (one byte for the - byte count field, two for the CRC). - ''' - return byte2int(data[byte_count_pos]) + byte_count_pos + 3
- -#---------------------------------------------------------------------------# -# Exported symbols -#---------------------------------------------------------------------------# -__all__ = [ - 'pack_bitstring', 'unpack_bitstring', 'default', - 'computeCRC', 'checkCRC', 'computeLRC', 'checkLRC', 'rtuFrameSize' -] -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/sphinx/html/_sources/examples/asynchronous-client.rst.txt b/doc/sphinx/html/_sources/examples/asynchronous-client.rst.txt deleted file mode 100644 index 7f5b7d3c3..000000000 --- a/doc/sphinx/html/_sources/examples/asynchronous-client.rst.txt +++ /dev/null @@ -1,16 +0,0 @@ -================================================== -Asynchronous Client Example -================================================== - -The asynchronous client functions in the same way as the synchronous -client, however, the asynchronous client uses twisted to return deferreds -for the response result. Just like the synchronous version, it works against -TCP, UDP, serial ASCII, and serial RTU devices. - -Below an asynchronous tcp client is demonstrated running against a -reference server. If you do not have a device to test with, feel free -to run a pymodbus server instance or start the reference tester in -the tools directory. - -.. literalinclude:: ../../../examples/common/asynchronous-client.py - diff --git a/doc/sphinx/html/_sources/examples/asynchronous-processor.rst.txt b/doc/sphinx/html/_sources/examples/asynchronous-processor.rst.txt deleted file mode 100644 index 4afd8504e..000000000 --- a/doc/sphinx/html/_sources/examples/asynchronous-processor.rst.txt +++ /dev/null @@ -1,15 +0,0 @@ -================================================== -Asynchronous Processor Example -================================================== - -Below is a simplified asynchronous client skeleton that was -submitted by a user of the library. It can be used as a guide -for implementing more complex pollers or state machines. - -Feel free to test it against whatever device you currently have -available. If you do not have a device to test with, feel free -to run a pymodbus server instance or start the reference tester in -the tools directory. - -.. literalinclude:: ../../../examples/common/asynchronous-processor.py - diff --git a/doc/sphinx/html/_sources/examples/asynchronous-server.rst.txt b/doc/sphinx/html/_sources/examples/asynchronous-server.rst.txt deleted file mode 100644 index 14aeef298..000000000 --- a/doc/sphinx/html/_sources/examples/asynchronous-server.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Asynchronous Server Example -================================================== - -.. literalinclude:: ../../../examples/common/asynchronous-server.py - diff --git a/doc/sphinx/html/_sources/examples/bcd-payload.rst.txt b/doc/sphinx/html/_sources/examples/bcd-payload.rst.txt deleted file mode 100644 index a95c5e7a6..000000000 --- a/doc/sphinx/html/_sources/examples/bcd-payload.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Binary Coded Decimal Example -================================================== - -.. literalinclude:: ../../../examples/contrib/bcd-payload.py - diff --git a/doc/sphinx/html/_sources/examples/bottle-frontend.rst.txt b/doc/sphinx/html/_sources/examples/bottle-frontend.rst.txt deleted file mode 100644 index 95507c5a8..000000000 --- a/doc/sphinx/html/_sources/examples/bottle-frontend.rst.txt +++ /dev/null @@ -1,22 +0,0 @@ -================================================== -Bottle Web Frontend Example -================================================== - --------------------------------------------------- -Summary --------------------------------------------------- - -This is a simple example of adding a live REST api -on top of a running pymodbus server. This uses the -bottle microframework to achieve this. - -The example can be hosted under twisted as well as -the bottle internal server and can furthermore be -run behind gunicorn, cherrypi, etc wsgi containers. - --------------------------------------------------- -Main Program --------------------------------------------------- - -.. literalinclude:: ../../../examples/gui/bottle/frontend.py - diff --git a/doc/sphinx/html/_sources/examples/callback-server.rst.txt b/doc/sphinx/html/_sources/examples/callback-server.rst.txt deleted file mode 100644 index e57475216..000000000 --- a/doc/sphinx/html/_sources/examples/callback-server.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Callback Server Example -================================================== - -.. literalinclude:: ../../../examples/common/callback-server.py - diff --git a/doc/sphinx/html/_sources/examples/changing-framers.rst.txt b/doc/sphinx/html/_sources/examples/changing-framers.rst.txt deleted file mode 100644 index 3679aa43f..000000000 --- a/doc/sphinx/html/_sources/examples/changing-framers.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Changing Default Framers -================================================== - -.. literalinclude:: ../../../examples/common/changing-framers.py - diff --git a/doc/sphinx/html/_sources/examples/concurrent-client.rst.txt b/doc/sphinx/html/_sources/examples/concurrent-client.rst.txt deleted file mode 100644 index 1a3799ac9..000000000 --- a/doc/sphinx/html/_sources/examples/concurrent-client.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Modbus Concurrent Client Example -================================================== - -.. literalinclude:: ../../../examples/contrib/concurrent-client.py - diff --git a/doc/sphinx/html/_sources/examples/custom-datablock.rst.txt b/doc/sphinx/html/_sources/examples/custom-datablock.rst.txt deleted file mode 100644 index 7139c0f08..000000000 --- a/doc/sphinx/html/_sources/examples/custom-datablock.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Custom Datablock Example -================================================== - -.. literalinclude:: ../../../examples/common/custom-datablock.py - diff --git a/doc/sphinx/html/_sources/examples/database-datastore.rst.txt b/doc/sphinx/html/_sources/examples/database-datastore.rst.txt deleted file mode 100644 index 9186be812..000000000 --- a/doc/sphinx/html/_sources/examples/database-datastore.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Database Datastore Example -================================================== - -.. literalinclude:: ../../../examples/contrib/database-datastore.py - diff --git a/doc/sphinx/html/_sources/examples/gtk-frontend.rst.txt b/doc/sphinx/html/_sources/examples/gtk-frontend.rst.txt deleted file mode 100644 index 3efc72644..000000000 --- a/doc/sphinx/html/_sources/examples/gtk-frontend.rst.txt +++ /dev/null @@ -1,26 +0,0 @@ -================================================== -Glade/GTK Frontend Example -================================================== - -Main Program --------------------------------------------------- - -This is an example simulator that is written using the pygtk -bindings. Although it currently does not have a frontend for -modifying the context values, it does allow one to expose N -virtual modbus devices to a network which is useful for testing -data center monitoring tools. - -.. note:: The virtual networking code will only work on linux - -.. literalinclude:: ../../../examples/gui/gtk/simulator.py - :language: python - -Glade Layout File --------------------------------------------------- - -The following is the glade layout file that is used by this script: - -.. literalinclude:: ../../../examples/gui/gtk/simulator.glade - :language: xml - diff --git a/doc/sphinx/html/_sources/examples/index.rst.txt b/doc/sphinx/html/_sources/examples/index.rst.txt deleted file mode 100644 index a41f01129..000000000 --- a/doc/sphinx/html/_sources/examples/index.rst.txt +++ /dev/null @@ -1,60 +0,0 @@ - -Pymodbus Library Examples -==================================== - -*What follows is a collection of examples using the pymodbus -library in various ways* - -Example Library Code --------------------------------------------------- - -.. toctree:: - :maxdepth: 2 - - asynchronous-client - asynchronous-server - asynchronous-processor - custom-message - custom-datablock - modbus-logging - modbus-payload - modbus-payload-server - synchronous-client - synchronous-client-ext - synchronous-server - performance - updating-server - callback-server - changing-framers - thread-safe-datastore - -Custom Pymodbus Code --------------------------------------------------- - -.. toctree:: - :maxdepth: 2 - - redis-datastore - database-datastore - bcd-payload - modicon-payload - message-generator - message-parser - serial-forwarder - modbus-scraper - modbus-simulator - concurrent-client - libmodbus-client - remote-server-context - -Example Frontend Code --------------------------------------------------- - -.. toctree:: - :maxdepth: 2 - - gtk-frontend - tk-frontend - wx-frontend - bottle-frontend - diff --git a/doc/sphinx/html/_sources/examples/libmodbus-client.rst.txt b/doc/sphinx/html/_sources/examples/libmodbus-client.rst.txt deleted file mode 100644 index 17ac8e2cf..000000000 --- a/doc/sphinx/html/_sources/examples/libmodbus-client.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Libmodbus Client Facade -================================================== - -.. literalinclude:: ../../../examples/contrib/libmodbus-client.py - diff --git a/doc/sphinx/html/_sources/examples/message-generator.rst.txt b/doc/sphinx/html/_sources/examples/message-generator.rst.txt deleted file mode 100644 index 605554c45..000000000 --- a/doc/sphinx/html/_sources/examples/message-generator.rst.txt +++ /dev/null @@ -1,26 +0,0 @@ -================================================== -Modbus Message Generator Example -================================================== - -This is an example of a utility that will build -examples of modbus messages in all the available -formats in the pymodbus package. - --------------------------------------------------- -Program Source --------------------------------------------------- - -.. literalinclude:: ../../../examples/contrib/message-generator.py - --------------------------------------------------- -Example Request Messages --------------------------------------------------- - -.. literalinclude:: ../../../examples/contrib/tx-messages - --------------------------------------------------- -Example Response Messages --------------------------------------------------- - -.. literalinclude:: ../../../examples/contrib/rx-messages - diff --git a/doc/sphinx/html/_sources/examples/message-parser.rst.txt b/doc/sphinx/html/_sources/examples/message-parser.rst.txt deleted file mode 100644 index 0bbaee9fc..000000000 --- a/doc/sphinx/html/_sources/examples/message-parser.rst.txt +++ /dev/null @@ -1,55 +0,0 @@ -================================================== -Modbus Message Parsing Example -================================================== - -This is an example of a parser to decode raw messages -to a readable description. It will attempt to decode -a message to the request and response version of a -message if possible. Here is an example output:: - - $./message-parser.py -b -m 000112340006ff076d - ================================================================================ - Decoding Message 000112340006ff076d - ================================================================================ - ServerDecoder - -------------------------------------------------------------------------------- - name = ReadExceptionStatusRequest - check = 0x0 - unit_id = 0xff - transaction_id = 0x1 - protocol_id = 0x1234 - documentation = - This function code is used to read the contents of eight Exception Status - outputs in a remote device. The function provides a simple method for - accessing this information, because the Exception Output references are - known (no output reference is needed in the function). - - ClientDecoder - -------------------------------------------------------------------------------- - name = ReadExceptionStatusResponse - check = 0x0 - status = 0x6d - unit_id = 0xff - transaction_id = 0x1 - protocol_id = 0x1234 - documentation = - The normal response contains the status of the eight Exception Status - outputs. The outputs are packed into one data byte, with one bit - per output. The status of the lowest output reference is contained - in the least significant bit of the byte. The contents of the eight - Exception Status outputs are device specific. - --------------------------------------------------- -Program Source --------------------------------------------------- - -.. literalinclude:: ../../../examples/contrib/message-parser.py - --------------------------------------------------- -Example Messages --------------------------------------------------- - -See the documentation for the message generator -for a collection of messages that can be parsed -by this utility. - diff --git a/doc/sphinx/html/_sources/examples/modbus-payload-server.rst.txt b/doc/sphinx/html/_sources/examples/modbus-payload-server.rst.txt deleted file mode 100644 index 9144f0f53..000000000 --- a/doc/sphinx/html/_sources/examples/modbus-payload-server.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Modbus Payload Server Context Building Example -================================================== - -.. literalinclude:: ../../../examples/common/modbus-payload-server.py - diff --git a/doc/sphinx/html/_sources/examples/modbus-payload.rst.txt b/doc/sphinx/html/_sources/examples/modbus-payload.rst.txt deleted file mode 100644 index 79e46dfdb..000000000 --- a/doc/sphinx/html/_sources/examples/modbus-payload.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Modbus Payload Building/Decoding Example -================================================== - -.. literalinclude:: ../../../examples/common/modbus-payload.py - diff --git a/doc/sphinx/html/_sources/examples/modbus-simulator.rst.txt b/doc/sphinx/html/_sources/examples/modbus-simulator.rst.txt deleted file mode 100644 index 5adcee5ee..000000000 --- a/doc/sphinx/html/_sources/examples/modbus-simulator.rst.txt +++ /dev/null @@ -1,5 +0,0 @@ -================================================== -Modbus Simulator Example -================================================== - -.. literalinclude:: ../../../examples/contrib/modbus-simulator.py diff --git a/doc/sphinx/html/_sources/examples/modicon-payload.rst.txt b/doc/sphinx/html/_sources/examples/modicon-payload.rst.txt deleted file mode 100644 index 997a12f50..000000000 --- a/doc/sphinx/html/_sources/examples/modicon-payload.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Modicon Encoded Example -================================================== - -.. literalinclude:: ../../../examples/contrib/modicon-payload.py - diff --git a/doc/sphinx/html/_sources/examples/performance.rst.txt b/doc/sphinx/html/_sources/examples/performance.rst.txt deleted file mode 100644 index 93185bdea..000000000 --- a/doc/sphinx/html/_sources/examples/performance.rst.txt +++ /dev/null @@ -1,11 +0,0 @@ -================================================== -Synchronous Client Performance Check -================================================== - -Below is a quick example of how to test the performance of a tcp modbus -device using the synchronous tcp client. If you do not have a device -to test with, feel free to run a pymodbus server instance or start -the reference tester in the tools directory. - -.. literalinclude:: ../../../examples/common/performance.py - diff --git a/doc/sphinx/html/_sources/examples/redis-datastore.rst.txt b/doc/sphinx/html/_sources/examples/redis-datastore.rst.txt deleted file mode 100644 index bb5554e04..000000000 --- a/doc/sphinx/html/_sources/examples/redis-datastore.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Redis Datastore Example -================================================== - -.. literalinclude:: ../../../examples/contrib/redis-datastore.py - diff --git a/doc/sphinx/html/_sources/examples/remote-server-context.rst.txt b/doc/sphinx/html/_sources/examples/remote-server-context.rst.txt deleted file mode 100644 index 2a2ac3c05..000000000 --- a/doc/sphinx/html/_sources/examples/remote-server-context.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Remote Single Server Context -================================================== - -.. literalinclude:: ../../../examples/contrib/remote_server_context.py - diff --git a/doc/sphinx/html/_sources/examples/serial-forwarder.rst.txt b/doc/sphinx/html/_sources/examples/serial-forwarder.rst.txt deleted file mode 100644 index 87f6e0a0c..000000000 --- a/doc/sphinx/html/_sources/examples/serial-forwarder.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Synchronous Serial Forwarder -================================================== - -.. literalinclude:: ../../../examples/contrib/serial-forwarder.py - diff --git a/doc/sphinx/html/_sources/examples/synchronous-client-ext.rst.txt b/doc/sphinx/html/_sources/examples/synchronous-client-ext.rst.txt deleted file mode 100644 index 5012ec8b0..000000000 --- a/doc/sphinx/html/_sources/examples/synchronous-client-ext.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Synchronous Client Extended Example -================================================== - -.. literalinclude:: ../../../examples/common/synchronous-client-ext.py - diff --git a/doc/sphinx/html/_sources/examples/synchronous-client.rst.txt b/doc/sphinx/html/_sources/examples/synchronous-client.rst.txt deleted file mode 100644 index b90563402..000000000 --- a/doc/sphinx/html/_sources/examples/synchronous-client.rst.txt +++ /dev/null @@ -1,19 +0,0 @@ -================================================== -Synchronous Client Example -================================================== - -It should be noted that each request will block waiting for the result. If asynchronous -behaviour is required, please use the asynchronous client implementations. -The synchronous client, works against TCP, UDP, serial ASCII, and serial RTU devices. - -The synchronous client exposes the most popular methods of the modbus protocol, -however, if you want to execute other methods against the device, -simple create a request instance and pass it to the execute method. - -Below an synchronous tcp client is demonstrated running against a -reference server. If you do not have a device to test with, feel free -to run a pymodbus server instance or start the reference tester in -the tools directory. - -.. literalinclude:: ../../../examples/common/synchronous-client.py - diff --git a/doc/sphinx/html/_sources/examples/synchronous-server.rst.txt b/doc/sphinx/html/_sources/examples/synchronous-server.rst.txt deleted file mode 100644 index 1db715d7f..000000000 --- a/doc/sphinx/html/_sources/examples/synchronous-server.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Synchronous Server Example -================================================== - -.. literalinclude:: ../../../examples/common/synchronous-server.py - diff --git a/doc/sphinx/html/_sources/examples/thread-safe-datastore.rst.txt b/doc/sphinx/html/_sources/examples/thread-safe-datastore.rst.txt deleted file mode 100644 index 7a965a3f4..000000000 --- a/doc/sphinx/html/_sources/examples/thread-safe-datastore.rst.txt +++ /dev/null @@ -1,6 +0,0 @@ -================================================== -Thread Safe Datastore Example -================================================== - -.. literalinclude:: ../../../examples/contrib/thread_safe_datastore.py - diff --git a/doc/sphinx/html/_sources/examples/tk-frontend.rst.txt b/doc/sphinx/html/_sources/examples/tk-frontend.rst.txt deleted file mode 100644 index 1849d0abc..000000000 --- a/doc/sphinx/html/_sources/examples/tk-frontend.rst.txt +++ /dev/null @@ -1,17 +0,0 @@ -================================================== -TK Frontend Example -================================================== - -Main Program --------------------------------------------------- - -This is an example simulator that is written using the native tk -toolkit. Although it currently does not have a frontend for -modifying the context values, it does allow one to expose N -virtual modbus devices to a network which is useful for testing -data center monitoring tools. - -.. note:: The virtual networking code will only work on linux - -.. literalinclude:: ../../../examples/gui/tk/simulator.py - diff --git a/doc/sphinx/html/_sources/examples/wx-frontend.rst.txt b/doc/sphinx/html/_sources/examples/wx-frontend.rst.txt deleted file mode 100644 index 5d68142c0..000000000 --- a/doc/sphinx/html/_sources/examples/wx-frontend.rst.txt +++ /dev/null @@ -1,17 +0,0 @@ -================================================== -WX Frontend Example -================================================== - -Main Program --------------------------------------------------- - -This is an example simulator that is written using the python wx -bindings. Although it currently does not have a frontend for -modifying the context values, it does allow one to expose N -virtual modbus devices to a network which is useful for testing -data center monitoring tools. - -.. note:: The virtual networking code will only work on linux - -.. literalinclude:: ../../../examples/gui/wx/simulator.py - diff --git a/doc/sphinx/html/_sources/index.rst.txt b/doc/sphinx/html/_sources/index.rst.txt deleted file mode 100644 index 7017018f2..000000000 --- a/doc/sphinx/html/_sources/index.rst.txt +++ /dev/null @@ -1,23 +0,0 @@ -.. PyModbus documentation master file, created by - sphinx-quickstart on Tue Apr 14 19:11:16 2009. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to PyModbus's documentation! -==================================== - -Contents: - -.. toctree:: - :maxdepth: 2 - - examples/index.rst - library/index.rst - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/doc/sphinx/html/_sources/library/async-client.rst.txt b/doc/sphinx/html/_sources/library/async-client.rst.txt deleted file mode 100644 index c325706dc..000000000 --- a/doc/sphinx/html/_sources/library/async-client.rst.txt +++ /dev/null @@ -1,19 +0,0 @@ -:mod:`client.async` --- Twisted Async Modbus Client -==================================================== - -.. module:: client.async - :synopsis: Twisted Asynchronous Modbus Client - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation ------------------- - -.. automodule:: pymodbus.client.async - -.. autoclass:: ModbusClientProtocol - :members: - -.. autoclass:: ModbusClientFactory - :members: diff --git a/doc/sphinx/html/_sources/library/async-server.rst.txt b/doc/sphinx/html/_sources/library/async-server.rst.txt deleted file mode 100644 index 8f2dcdb7b..000000000 --- a/doc/sphinx/html/_sources/library/async-server.rst.txt +++ /dev/null @@ -1,29 +0,0 @@ -:mod:`server.async` --- Twisted Asynchronous Modbus Server -============================================================ - -.. module:: server.async - :synopsis: Twisted Asynchronous Modbus Server - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.server.async - -.. autoclass:: ModbusTcpProtocol - :members: - -.. autoclass:: ModbusUdpProtocol - :members: - -.. autoclass:: ModbusServerFactory - :members: - -.. autofunction:: StartTcpServer - -.. autofunction:: StartUdpServer - -.. autofunction:: StartSerialServer - diff --git a/doc/sphinx/html/_sources/library/bit-read-message.rst.txt b/doc/sphinx/html/_sources/library/bit-read-message.rst.txt deleted file mode 100644 index 9ea4b0cfa..000000000 --- a/doc/sphinx/html/_sources/library/bit-read-message.rst.txt +++ /dev/null @@ -1,32 +0,0 @@ -:mod:`bit_read_message` --- Bit Read Modbus Messages -============================================================ - -.. module:: bit_read_message - :synopsis: Bit Read Modbus Messages - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.bit_read_message - -.. autoclass:: ReadBitsRequestBase - :members: - -.. autoclass:: ReadBitsResponseBase - :members: - -.. autoclass:: ReadCoilsRequest - :members: - -.. autoclass:: ReadCoilsResponse - :members: - -.. autoclass:: ReadDiscreteInputsRequest - :members: - -.. autoclass:: ReadDiscreteInputsResponse - :members: - diff --git a/doc/sphinx/html/_sources/library/bit-write-message.rst.txt b/doc/sphinx/html/_sources/library/bit-write-message.rst.txt deleted file mode 100644 index 6a73f9a46..000000000 --- a/doc/sphinx/html/_sources/library/bit-write-message.rst.txt +++ /dev/null @@ -1,26 +0,0 @@ -:mod:`bit_write_message` --- Bit Write Modbus Messages -============================================================ - -.. module:: bit_write_message - :synopsis: Bit Write Modbus Messages - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.bit_write_message - -.. autoclass:: WriteSingleCoilRequest - :members: - -.. autoclass:: WriteSingleCoilResponse - :members: - -.. autoclass:: WriteMultipleCoilsRequest - :members: - -.. autoclass:: WriteMultipleCoilsResponse - :members: - diff --git a/doc/sphinx/html/_sources/library/client-common.rst.txt b/doc/sphinx/html/_sources/library/client-common.rst.txt deleted file mode 100644 index 5cca7ada3..000000000 --- a/doc/sphinx/html/_sources/library/client-common.rst.txt +++ /dev/null @@ -1,16 +0,0 @@ -:mod:`client.common` --- Twisted Async Modbus Client -==================================================== - -.. module:: client.common - :synopsis: Modbus common client clode - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation ------------------- - -.. automodule:: pymodbus.client.common - -.. autoclass:: ModbusClientMixin - :members: diff --git a/doc/sphinx/html/_sources/library/constants.rst.txt b/doc/sphinx/html/_sources/library/constants.rst.txt deleted file mode 100644 index a99e207c6..000000000 --- a/doc/sphinx/html/_sources/library/constants.rst.txt +++ /dev/null @@ -1,31 +0,0 @@ -:mod:`constants` --- Modbus Default Values -============================================================ - -.. module:: constants - :synopsis: Modbus Default Values - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.constants - -.. autoclass:: Defaults - :members: - -.. autoclass:: ModbusStatus - :members: - -.. autoclass:: Endian - :members: - -.. autoclass:: ModbusPlusOperation - :members: - -.. autoclass:: DeviceInformation - :members: - -.. autoclass:: MoreData - :members: diff --git a/doc/sphinx/html/_sources/library/datastore/context.rst.txt b/doc/sphinx/html/_sources/library/datastore/context.rst.txt deleted file mode 100644 index 16a62e2e1..000000000 --- a/doc/sphinx/html/_sources/library/datastore/context.rst.txt +++ /dev/null @@ -1,20 +0,0 @@ -:mod:`context` --- Modbus Server Contexts -============================================================ - -.. module:: context - :synopsis: Modbus Server Contexts - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.datastore.context - -.. autoclass:: ModbusSlaveContext - :members: - -.. autoclass:: ModbusServerContext - :members: - diff --git a/doc/sphinx/html/_sources/library/datastore/index.rst.txt b/doc/sphinx/html/_sources/library/datastore/index.rst.txt deleted file mode 100644 index 6ea14b24e..000000000 --- a/doc/sphinx/html/_sources/library/datastore/index.rst.txt +++ /dev/null @@ -1,13 +0,0 @@ - -Server Datastores and Contexts -==================================== - -*The following are the API documentation strings taken -from the sourcecode* - -.. toctree:: - :maxdepth: 2 - - store.rst - context.rst - remote.rst diff --git a/doc/sphinx/html/_sources/library/datastore/remote.rst.txt b/doc/sphinx/html/_sources/library/datastore/remote.rst.txt deleted file mode 100644 index 551f0b17b..000000000 --- a/doc/sphinx/html/_sources/library/datastore/remote.rst.txt +++ /dev/null @@ -1,16 +0,0 @@ -:mod:`remote` --- Remote Slave Context -============================================================ - -.. module:: remote - :synopsis: Remote Slave Context - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.datastore.remote - -.. autoclass:: RemoteSlaveContext - :members: diff --git a/doc/sphinx/html/_sources/library/datastore/store.rst.txt b/doc/sphinx/html/_sources/library/datastore/store.rst.txt deleted file mode 100644 index 1a5ff2d67..000000000 --- a/doc/sphinx/html/_sources/library/datastore/store.rst.txt +++ /dev/null @@ -1,23 +0,0 @@ -:mod:`store` --- Datastore for Modbus Server Context -============================================================ - -.. module:: store - :synopsis: Datastore for Modbus Server Context - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.datastore.store - -.. autoclass:: BaseModbusDataBlock - :members: - -.. autoclass:: ModbusSequentialDataBlock - :members: - -.. autoclass:: ModbusSparseDataBlock - :members: - diff --git a/doc/sphinx/html/_sources/library/device.rst.txt b/doc/sphinx/html/_sources/library/device.rst.txt deleted file mode 100644 index 59b996de4..000000000 --- a/doc/sphinx/html/_sources/library/device.rst.txt +++ /dev/null @@ -1,28 +0,0 @@ -:mod:`device` --- Modbus Device Representation -============================================================ - -.. module:: device - :synopsis: Modbus Device Representation - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.device - -.. autoclass:: ModbusAccessControl - :members: - -.. autoclass:: ModbusPlusStatistics - :members: - -.. autoclass:: ModbusDeviceIdentification - :members: - -.. autoclass:: DeviceInformationFactory - :members: - -.. autoclass:: ModbusControlBlock - :members: diff --git a/doc/sphinx/html/_sources/library/diag-message.rst.txt b/doc/sphinx/html/_sources/library/diag-message.rst.txt deleted file mode 100644 index 5500a1cbc..000000000 --- a/doc/sphinx/html/_sources/library/diag-message.rst.txt +++ /dev/null @@ -1,128 +0,0 @@ -:mod:`diag_message` --- Diagnostic Modbus Messages -============================================================ - -.. module:: diag_message - :synopsis: Diagnostic Modbus Messages - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.diag_message - -.. autoclass:: DiagnosticStatusRequest - :members: - -.. autoclass:: DiagnosticStatusResponse - :members: - -.. autoclass:: DiagnosticStatusSimpleRequest - :members: - -.. autoclass:: DiagnosticStatusSimpleResponse - :members: - -.. autoclass:: ReturnQueryDataRequest - :members: - -.. autoclass:: ReturnQueryDataResponse - :members: - -.. autoclass:: RestartCommunicationsOptionRequest - :members: - -.. autoclass:: RestartCommunicationsOptionResponse - :members: - -.. autoclass:: ReturnDiagnosticRegisterRequest - :members: - -.. autoclass:: ReturnDiagnosticRegisterResponse - :members: - -.. autoclass:: ChangeAsciiInputDelimiterRequest - :members: - -.. autoclass:: ChangeAsciiInputDelimiterResponse - :members: - -.. autoclass:: ForceListenOnlyModeRequest - :members: - -.. autoclass:: ForceListenOnlyModeResponse - :members: - -.. autoclass:: ClearCountersRequest - :members: - -.. autoclass:: ClearCountersResponse - :members: - -.. autoclass:: ReturnBusMessageCountRequest - :members: - -.. autoclass:: ReturnBusMessageCountResponse - :members: - -.. autoclass:: ReturnBusCommunicationErrorCountRequest - :members: - -.. autoclass:: ReturnBusCommunicationErrorCountResponse - :members: - -.. autoclass:: ReturnBusExceptionErrorCountRequest - :members: - -.. autoclass:: ReturnBusExceptionErrorCountResponse - :members: - -.. autoclass:: ReturnSlaveMessageCountRequest - :members: - -.. autoclass:: ReturnSlaveMessageCountResponse - :members: - -.. autoclass:: ReturnSlaveNoResponseCountRequest - :members: - -.. autoclass:: ReturnSlaveNoReponseCountResponse - :members: - -.. autoclass:: ReturnSlaveNAKCountRequest - :members: - -.. autoclass:: ReturnSlaveNAKCountResponse - :members: - -.. autoclass:: ReturnSlaveBusyCountRequest - :members: - -.. autoclass:: ReturnSlaveBusyCountResponse - :members: - -.. autoclass:: ReturnSlaveBusCharacterOverrunCountRequest - :members: - -.. autoclass:: ReturnSlaveBusCharacterOverrunCountResponse - :members: - -.. autoclass:: ReturnIopOverrunCountRequest - :members: - -.. autoclass:: ReturnIopOverrunCountResponse - :members: - -.. autoclass:: ClearOverrunCountRequest - :members: - -.. autoclass:: ClearOverrunCountResponse - :members: - -.. autoclass:: GetClearModbusPlusRequest - :members: - -.. autoclass:: GetClearModbusPlusResponse - :members: - diff --git a/doc/sphinx/html/_sources/library/events.rst.txt b/doc/sphinx/html/_sources/library/events.rst.txt deleted file mode 100644 index 5bc4d466e..000000000 --- a/doc/sphinx/html/_sources/library/events.rst.txt +++ /dev/null @@ -1,28 +0,0 @@ -:mod:`events` --- Events Used in PyModbus -============================================================ - -.. module:: events - :synopsis: Events Used in PyModbus - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.events - -.. autoclass:: ModbusEvent - :members: - -.. autoclass:: RemoteReceiveEvent - :members: - -.. autoclass:: RemoteSendEvent - :members: - -.. autoclass:: EnteredListenModeEvent - :members: - -.. autoclass:: CommunicationRestartEvent - :members: diff --git a/doc/sphinx/html/_sources/library/exceptions.rst.txt b/doc/sphinx/html/_sources/library/exceptions.rst.txt deleted file mode 100644 index 03c05ea71..000000000 --- a/doc/sphinx/html/_sources/library/exceptions.rst.txt +++ /dev/null @@ -1,26 +0,0 @@ -:mod:`exceptions` --- Exceptions Used in PyModbus -============================================================ - -.. module:: exceptions - :synopsis: Exceptions Used in PyModbus - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.exceptions - -.. autoclass:: ModbusException - :members: - -.. autoclass:: ModbusIOException - :members: - -.. autoclass:: ParameterException - :members: - -.. autoclass:: NotImplementedException - :members: - diff --git a/doc/sphinx/html/_sources/library/factory.rst.txt b/doc/sphinx/html/_sources/library/factory.rst.txt deleted file mode 100644 index 5f0fcc83a..000000000 --- a/doc/sphinx/html/_sources/library/factory.rst.txt +++ /dev/null @@ -1,19 +0,0 @@ -:mod:`factory` --- Request/Response Decoders -============================================================ - -.. module:: factory - :synopsis: Request/Response Decoders - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.factory - -.. autoclass:: ServerDecoder - :members: - -.. autoclass:: ClientDecoder - :members: diff --git a/doc/sphinx/html/_sources/library/file-message.rst.txt b/doc/sphinx/html/_sources/library/file-message.rst.txt deleted file mode 100644 index e5d0b666d..000000000 --- a/doc/sphinx/html/_sources/library/file-message.rst.txt +++ /dev/null @@ -1,34 +0,0 @@ -:mod:`file_message` --- File Modbus Messages -============================================================ - -.. module:: file_message - :synopsis: File Modbus Messages - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.file_message - -.. autoclass:: FileRecord - :members: - -.. autoclass:: ReadFileRecordRequest - :members: - -.. autoclass:: ReadFileRecordResponse - :members: - -.. autoclass:: WriteFileRecordRequest - :members: - -.. autoclass:: WriteFileRecordResponse - :members: - -.. autoclass:: ReadFifoQueueRequest - :members: - -.. autoclass:: ReadFifoQueueResponse - :members: diff --git a/doc/sphinx/html/_sources/library/index.rst.txt b/doc/sphinx/html/_sources/library/index.rst.txt deleted file mode 100644 index f21e8e4a7..000000000 --- a/doc/sphinx/html/_sources/library/index.rst.txt +++ /dev/null @@ -1,35 +0,0 @@ - -Pymodbus Library API Documentation -==================================== - -*The following are the API documentation strings taken -from the sourcecode* - -.. toctree:: - :maxdepth: 2 - - bit-read-message.rst - bit-write-message.rst - client-common.rst - sync-client.rst - async-client.rst - constants.rst - datastore/index.rst - diag-message.rst - device.rst - factory.rst - interfaces.rst - exceptions.rst - other-message.rst - mei-message.rst - file-message.rst - events.rst - payload.rst - pdu.rst - pymodbus.rst - register-read-message.rst - register-write-message.rst - sync-server.rst - async-server.rst - transaction.rst - utilities.rst diff --git a/doc/sphinx/html/_sources/library/interfaces.rst.txt b/doc/sphinx/html/_sources/library/interfaces.rst.txt deleted file mode 100644 index cb10d0c62..000000000 --- a/doc/sphinx/html/_sources/library/interfaces.rst.txt +++ /dev/null @@ -1,28 +0,0 @@ -:mod:`interfaces` --- System Interfaces -============================================================ - -.. module:: interfaces - :synopsis: System Interfaces - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.interfaces - -.. autoclass:: Singleton - :members: - -.. autoclass:: IModbusDecoder - :members: - -.. autoclass:: IModbusFramer - :members: - -.. autoclass:: IModbusSlaveContext - :members: - -.. autoclass:: IPayloadBuilder - :members: diff --git a/doc/sphinx/html/_sources/library/mei-message.rst.txt b/doc/sphinx/html/_sources/library/mei-message.rst.txt deleted file mode 100644 index d75809445..000000000 --- a/doc/sphinx/html/_sources/library/mei-message.rst.txt +++ /dev/null @@ -1,19 +0,0 @@ -:mod:`mei_message` --- MEI Modbus Messages -============================================================ - -.. module:: mei_message - :synopsis: MEI Modbus Messages - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.mei_message - -.. autoclass:: ReadDeviceInformationRequest - :members: - -.. autoclass:: ReadDeviceInformationResponse - :members: diff --git a/doc/sphinx/html/_sources/library/other-message.rst.txt b/doc/sphinx/html/_sources/library/other-message.rst.txt deleted file mode 100644 index 3baf24888..000000000 --- a/doc/sphinx/html/_sources/library/other-message.rst.txt +++ /dev/null @@ -1,31 +0,0 @@ -:mod:`other_message` --- Other Modbus Messages -============================================================ - -.. module:: other_message - :synopsis: Other Modbus Messages - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.other_message - -.. autoclass:: ReadExceptionStatusRequest - :members: - -.. autoclass:: ReadExceptionStatusResponse - :members: - -.. autoclass:: GetCommEventCounterRequest - :members: - -.. autoclass:: GetCommEventCounterResponse - :members: - -.. autoclass:: ReportSlaveIdRequest - :members: - -.. autoclass:: ReportSlaveIdResponse - :members: diff --git a/doc/sphinx/html/_sources/library/payload.rst.txt b/doc/sphinx/html/_sources/library/payload.rst.txt deleted file mode 100644 index 4083aa2ca..000000000 --- a/doc/sphinx/html/_sources/library/payload.rst.txt +++ /dev/null @@ -1,19 +0,0 @@ -:mod:`payload` --- Modbus Payload Utilities -============================================================ - -.. module:: payload - :synopsis: Modbus Payload Utilities - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.payload - -.. autoclass:: BinaryPayloadBuilder - :members: - -.. autoclass:: BinaryPayloadDecoder - :members: diff --git a/doc/sphinx/html/_sources/library/pdu.rst.txt b/doc/sphinx/html/_sources/library/pdu.rst.txt deleted file mode 100644 index 46b8fd456..000000000 --- a/doc/sphinx/html/_sources/library/pdu.rst.txt +++ /dev/null @@ -1,32 +0,0 @@ -:mod:`pdu` --- Base Structures -============================================================ - -.. module:: pdu - :synopsis: Base Structures - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.pdu - -.. autoclass:: ModbusPDU - :members: - -.. autoclass:: ModbusRequest - :members: - -.. autoclass:: ModbusResponse - :members: - -.. autoclass:: ModbusExceptions - :members: - -.. autoclass:: ExceptionResponse - :members: - -.. autoclass:: IllegalFunctionRequest - :members: - diff --git a/doc/sphinx/html/_sources/library/pymodbus.rst.txt b/doc/sphinx/html/_sources/library/pymodbus.rst.txt deleted file mode 100644 index 54719825d..000000000 --- a/doc/sphinx/html/_sources/library/pymodbus.rst.txt +++ /dev/null @@ -1,7 +0,0 @@ -:mod:`pymodbus` --- Pymodbus Library -============================================================ - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -.. automodule:: pymodbus diff --git a/doc/sphinx/html/_sources/library/register-read-message.rst.txt b/doc/sphinx/html/_sources/library/register-read-message.rst.txt deleted file mode 100644 index aeb4c3402..000000000 --- a/doc/sphinx/html/_sources/library/register-read-message.rst.txt +++ /dev/null @@ -1,38 +0,0 @@ -:mod:`register_read_message` --- Register Read Messages -============================================================ - -.. module:: register_read_message - :synopsis: Register Read Messages - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.register_read_message - -.. autoclass:: ReadRegistersRequestBase - :members: - -.. autoclass:: ReadRegistersResponseBase - :members: - -.. autoclass:: ReadHoldingRegistersRequest - :members: - -.. autoclass:: ReadHoldingRegistersResponse - :members: - -.. autoclass:: ReadInputRegistersRequest - :members: - -.. autoclass:: ReadInputRegistersResponse - :members: - -.. autoclass:: ReadWriteMultipleRegistersRequest - :members: - -.. autoclass:: ReadWriteMultipleRegistersResponse - :members: - diff --git a/doc/sphinx/html/_sources/library/register-write-message.rst.txt b/doc/sphinx/html/_sources/library/register-write-message.rst.txt deleted file mode 100644 index 71a917646..000000000 --- a/doc/sphinx/html/_sources/library/register-write-message.rst.txt +++ /dev/null @@ -1,26 +0,0 @@ -:mod:`register_write_message` --- Register Write Messages -============================================================ - -.. module:: register_write_message - :synopsis: Register Write Messages - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.register_write_message - -.. autoclass:: WriteSingleRegisterRequest - :members: - -.. autoclass:: WriteSingleRegisterResponse - :members: - -.. autoclass:: WriteMultipleRegistersRequest - :members: - -.. autoclass:: WriteMultipleRegistersResponse - :members: - diff --git a/doc/sphinx/html/_sources/library/sync-client.rst.txt b/doc/sphinx/html/_sources/library/sync-client.rst.txt deleted file mode 100644 index 5f60a3a50..000000000 --- a/doc/sphinx/html/_sources/library/sync-client.rst.txt +++ /dev/null @@ -1,26 +0,0 @@ -:mod:`client.sync` --- Twisted Synchronous Modbus Client -========================================================= - -.. module:: client.sync - :synopsis: Twisted Synchronous Modbus Client - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation ------------------- - -.. automodule:: pymodbus.client.sync - -.. autoclass:: BaseModbusClient - :members: - -.. autoclass:: ModbusTcpClient - :members: - -.. autoclass:: ModbusUdpClient - :members: - -.. autoclass:: ModbusSerialClient - :members: - diff --git a/doc/sphinx/html/_sources/library/sync-server.rst.txt b/doc/sphinx/html/_sources/library/sync-server.rst.txt deleted file mode 100644 index 3dcf9e04d..000000000 --- a/doc/sphinx/html/_sources/library/sync-server.rst.txt +++ /dev/null @@ -1,40 +0,0 @@ -:mod:`server.sync` --- Twisted Synchronous Modbus Server -============================================================ - -.. module:: server.sync - :synopsis: Twisted Synchronous Modbus Server - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.server.sync - -.. autoclass:: ModbusBaseRequestHandler - :members: - -.. autoclass:: ModbusSingleRequestHandler - :members: - -.. autoclass:: ModbusConnectedRequestHandler - :members: - -.. autoclass:: ModbusDisconnectedRequestHandler - :members: - -.. autoclass:: ModbusTcpServer - :members: - -.. autoclass:: ModbusUdpServer - :members: - -.. autoclass:: ModbusSerialServer - :members: - -.. autofunction:: StartTcpServer - -.. autofunction:: StartUdpServer - -.. autofunction:: StartSerialServer diff --git a/doc/sphinx/html/_sources/library/transaction.rst.txt b/doc/sphinx/html/_sources/library/transaction.rst.txt deleted file mode 100644 index b6ee89a8a..000000000 --- a/doc/sphinx/html/_sources/library/transaction.rst.txt +++ /dev/null @@ -1,31 +0,0 @@ -:mod:`transaction` --- Transaction Controllers for Pymodbus -============================================================ - -.. module:: transaction - :synopsis: Transaction controllers for pymodbus - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.transaction - -.. autoclass:: DictTransactionManager - :members: - -.. autoclass:: FifoTransactionManager - :members: - -.. autoclass:: ModbusSocketFramer - :members: - -.. autoclass:: ModbusRtuFramer - :members: - -.. autoclass:: ModbusAsciiFramer - :members: - -.. autoclass:: ModbusBinaryFramer - :members: diff --git a/doc/sphinx/html/_sources/library/utilities.rst.txt b/doc/sphinx/html/_sources/library/utilities.rst.txt deleted file mode 100644 index d8e78527e..000000000 --- a/doc/sphinx/html/_sources/library/utilities.rst.txt +++ /dev/null @@ -1,33 +0,0 @@ -:mod:`utilities` --- Extra Modbus Helpers -========================================== - -.. module:: utilities - :synopsis: Extra Modbus Helpers - -.. moduleauthor:: Galen Collins -.. sectionauthor:: Galen Collins - -API Documentation -------------------- - -.. automodule:: pymodbus.utilities - -.. autofunction:: default - -.. autofunction:: dict_property - -.. autofunction:: pack_bitstring - -.. autofunction:: unpack_bitstring - -.. autofunction:: __generate_crc16_table - -.. autofunction:: computeCRC - -.. autofunction:: checkCRC - -.. autofunction:: computeLRC - -.. autofunction:: checkLRC - -.. autofunction:: rtuFrameSize diff --git a/doc/sphinx/html/_static/README b/doc/sphinx/html/_static/README deleted file mode 100644 index 06016c7ce..000000000 --- a/doc/sphinx/html/_static/README +++ /dev/null @@ -1 +0,0 @@ -include any html static content here diff --git a/doc/sphinx/html/_static/ajax-loader.gif b/doc/sphinx/html/_static/ajax-loader.gif deleted file mode 100644 index 61faf8cab..000000000 Binary files a/doc/sphinx/html/_static/ajax-loader.gif and /dev/null differ diff --git a/doc/sphinx/html/_static/basic.css b/doc/sphinx/html/_static/basic.css deleted file mode 100644 index dc88b5a2d..000000000 --- a/doc/sphinx/html/_static/basic.css +++ /dev/null @@ -1,632 +0,0 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; - word-wrap: break-word; - overflow-wrap : break-word; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox input[type="text"] { - width: 170px; -} - -img { - border: 0; - max-width: 100%; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li div.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; - margin-left: auto; - margin-right: auto; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable ul { - margin-top: 0; - margin-bottom: 0; - list-style-type: none; -} - -table.indextable > tbody > tr > td > ul { - padding-left: 0em; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- domain module index --------------------------------------------------- */ - -table.modindextable td { - padding: 2px; - border-collapse: collapse; -} - -/* -- general body styles --------------------------------------------------- */ - -div.body p, div.body dd, div.body li, div.body blockquote { - -moz-hyphens: auto; - -ms-hyphens: auto; - -webkit-hyphens: auto; - hyphens: auto; -} - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink, -caption:hover > a.headerlink, -p.caption:hover > a.headerlink, -div.code-block-caption:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px 7px 0 7px; - background-color: #ffe; - width: 40%; - float: right; -} - -p.sidebar-title { - font-weight: bold; -} - -/* -- topics ---------------------------------------------------------------- */ - -div.topic { - border: 1px solid #ccc; - padding: 7px 7px 0 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - border: 0; - border-collapse: collapse; -} - -table caption span.caption-number { - font-style: italic; -} - -table caption span.caption-text { -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -table.footnote td, table.footnote th { - border: 0 !important; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -/* -- figures --------------------------------------------------------------- */ - -div.figure { - margin: 0.5em; - padding: 0.5em; -} - -div.figure p.caption { - padding: 0.3em; -} - -div.figure p.caption span.caption-number { - font-style: italic; -} - -div.figure p.caption span.caption-text { -} - -/* -- field list styles ----------------------------------------------------- */ - -table.field-list td, table.field-list th { - border: 0 !important; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -dl { - margin-bottom: 15px; -} - -dd p { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -dt:target, .highlighted { - background-color: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.optional { - font-size: 1.3em; -} - -.sig-paren { - font-size: larger; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -abbr, acronym { - border-bottom: dotted 1px; - cursor: help; -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -span.pre { - -moz-hyphens: none; - -ms-hyphens: none; - -webkit-hyphens: none; - hyphens: none; -} - -td.linenos pre { - padding: 5px 0px; - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - margin-left: 0.5em; -} - -table.highlighttable td { - padding: 0 0.5em 0 0.5em; -} - -div.code-block-caption { - padding: 2px 5px; - font-size: small; -} - -div.code-block-caption code { - background-color: transparent; -} - -div.code-block-caption + div > div.highlight > pre { - margin-top: 0; -} - -div.code-block-caption span.caption-number { - padding: 0.1em 0.3em; - font-style: italic; -} - -div.code-block-caption span.caption-text { -} - -div.literal-block-wrapper { - padding: 1em 1em 0; -} - -div.literal-block-wrapper div.highlight { - margin: 0; -} - -code.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -code.descclassname { - background-color: transparent; -} - -code.xref, a code { - background-color: transparent; - font-weight: bold; -} - -h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -span.eqno a.headerlink { - position: relative; - left: 0px; - z-index: 1; -} - -div.math:hover a.headerlink { - visibility: visible; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} \ No newline at end of file diff --git a/doc/sphinx/html/_static/classic.css b/doc/sphinx/html/_static/classic.css deleted file mode 100644 index 22fa0bde7..000000000 --- a/doc/sphinx/html/_static/classic.css +++ /dev/null @@ -1,261 +0,0 @@ -/* - * classic.css_t - * ~~~~~~~~~~~~~ - * - * Sphinx stylesheet -- classic theme. - * - * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -body { - font-family: sans-serif; - font-size: 100%; - background-color: #11303d; - color: #000; - margin: 0; - padding: 0; -} - -div.document { - background-color: #1c4e63; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 230px; -} - -div.body { - background-color: #ffffff; - color: #000000; - padding: 0 20px 30px 20px; -} - -div.footer { - color: #ffffff; - width: 100%; - padding: 9px 0 9px 0; - text-align: center; - font-size: 75%; -} - -div.footer a { - color: #ffffff; - text-decoration: underline; -} - -div.related { - background-color: #133f52; - line-height: 30px; - color: #ffffff; -} - -div.related a { - color: #ffffff; -} - -div.sphinxsidebar { -} - -div.sphinxsidebar h3 { - font-family: 'Trebuchet MS', sans-serif; - color: #ffffff; - font-size: 1.4em; - font-weight: normal; - margin: 0; - padding: 0; -} - -div.sphinxsidebar h3 a { - color: #ffffff; -} - -div.sphinxsidebar h4 { - font-family: 'Trebuchet MS', sans-serif; - color: #ffffff; - font-size: 1.3em; - font-weight: normal; - margin: 5px 0 0 0; - padding: 0; -} - -div.sphinxsidebar p { - color: #ffffff; -} - -div.sphinxsidebar p.topless { - margin: 5px 10px 10px 10px; -} - -div.sphinxsidebar ul { - margin: 10px; - padding: 0; - color: #ffffff; -} - -div.sphinxsidebar a { - color: #98dbcc; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - - - -/* -- hyperlink styles ------------------------------------------------------ */ - -a { - color: #355f7c; - text-decoration: none; -} - -a:visited { - color: #355f7c; - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - - - -/* -- body styles ----------------------------------------------------------- */ - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: 'Trebuchet MS', sans-serif; - background-color: #f2f2f2; - font-weight: normal; - color: #20435c; - border-bottom: 1px solid #ccc; - margin: 20px -20px 10px -20px; - padding: 3px 0 3px 10px; -} - -div.body h1 { margin-top: 0; font-size: 200%; } -div.body h2 { font-size: 160%; } -div.body h3 { font-size: 140%; } -div.body h4 { font-size: 120%; } -div.body h5 { font-size: 110%; } -div.body h6 { font-size: 100%; } - -a.headerlink { - color: #c60f0f; - font-size: 0.8em; - padding: 0 4px 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - background-color: #c60f0f; - color: white; -} - -div.body p, div.body dd, div.body li, div.body blockquote { - text-align: justify; - line-height: 130%; -} - -div.admonition p.admonition-title + p { - display: inline; -} - -div.admonition p { - margin-bottom: 5px; -} - -div.admonition pre { - margin-bottom: 5px; -} - -div.admonition ul, div.admonition ol { - margin-bottom: 5px; -} - -div.note { - background-color: #eee; - border: 1px solid #ccc; -} - -div.seealso { - background-color: #ffc; - border: 1px solid #ff6; -} - -div.topic { - background-color: #eee; -} - -div.warning { - background-color: #ffe4e4; - border: 1px solid #f66; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre { - padding: 5px; - background-color: #eeffcc; - color: #333333; - line-height: 120%; - border: 1px solid #ac9; - border-left: none; - border-right: none; -} - -code { - background-color: #ecf0f3; - padding: 0 1px 0 1px; - font-size: 0.95em; -} - -th { - background-color: #ede; -} - -.warning code { - background: #efc2c2; -} - -.note code { - background: #d6d6d6; -} - -.viewcode-back { - font-family: sans-serif; -} - -div.viewcode-block:target { - background-color: #f4debf; - border-top: 1px solid #ac9; - border-bottom: 1px solid #ac9; -} - -div.code-block-caption { - color: #efefef; - background-color: #1c4e63; -} \ No newline at end of file diff --git a/doc/sphinx/html/_static/comment-bright.png b/doc/sphinx/html/_static/comment-bright.png deleted file mode 100644 index 15e27edb1..000000000 Binary files a/doc/sphinx/html/_static/comment-bright.png and /dev/null differ diff --git a/doc/sphinx/html/_static/comment-close.png b/doc/sphinx/html/_static/comment-close.png deleted file mode 100644 index 4d91bcf57..000000000 Binary files a/doc/sphinx/html/_static/comment-close.png and /dev/null differ diff --git a/doc/sphinx/html/_static/comment.png b/doc/sphinx/html/_static/comment.png deleted file mode 100644 index dfbc0cbd5..000000000 Binary files a/doc/sphinx/html/_static/comment.png and /dev/null differ diff --git a/doc/sphinx/html/_static/default.css b/doc/sphinx/html/_static/default.css deleted file mode 100644 index 81b936363..000000000 --- a/doc/sphinx/html/_static/default.css +++ /dev/null @@ -1 +0,0 @@ -@import url("classic.css"); diff --git a/doc/sphinx/html/_static/doctools.js b/doc/sphinx/html/_static/doctools.js deleted file mode 100644 index 565497723..000000000 --- a/doc/sphinx/html/_static/doctools.js +++ /dev/null @@ -1,287 +0,0 @@ -/* - * doctools.js - * ~~~~~~~~~~~ - * - * Sphinx JavaScript utilities for all documentation. - * - * :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/** - * select a different prefix for underscore - */ -$u = _.noConflict(); - -/** - * make the code below compatible with browsers without - * an installed firebug like debugger -if (!window.console || !console.firebug) { - var names = ["log", "debug", "info", "warn", "error", "assert", "dir", - "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", - "profile", "profileEnd"]; - window.console = {}; - for (var i = 0; i < names.length; ++i) - window.console[names[i]] = function() {}; -} - */ - -/** - * small helper function to urldecode strings - */ -jQuery.urldecode = function(x) { - return decodeURIComponent(x).replace(/\+/g, ' '); -}; - -/** - * small helper function to urlencode strings - */ -jQuery.urlencode = encodeURIComponent; - -/** - * This function returns the parsed url parameters of the - * current request. Multiple values per key are supported, - * it will always return arrays of strings for the value parts. - */ -jQuery.getQueryParameters = function(s) { - if (typeof s == 'undefined') - s = document.location.search; - var parts = s.substr(s.indexOf('?') + 1).split('&'); - var result = {}; - for (var i = 0; i < parts.length; i++) { - var tmp = parts[i].split('=', 2); - var key = jQuery.urldecode(tmp[0]); - var value = jQuery.urldecode(tmp[1]); - if (key in result) - result[key].push(value); - else - result[key] = [value]; - } - return result; -}; - -/** - * highlight a given string on a jquery object by wrapping it in - * span elements with the given class name. - */ -jQuery.fn.highlightText = function(text, className) { - function highlight(node) { - if (node.nodeType == 3) { - var val = node.nodeValue; - var pos = val.toLowerCase().indexOf(text); - if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { - var span = document.createElement("span"); - span.className = className; - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - node.parentNode.insertBefore(span, node.parentNode.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling)); - node.nodeValue = val.substr(0, pos); - } - } - else if (!jQuery(node).is("button, select, textarea")) { - jQuery.each(node.childNodes, function() { - highlight(this); - }); - } - } - return this.each(function() { - highlight(this); - }); -}; - -/* - * backward compatibility for jQuery.browser - * This will be supported until firefox bug is fixed. - */ -if (!jQuery.browser) { - jQuery.uaMatch = function(ua) { - ua = ua.toLowerCase(); - - var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || - /(webkit)[ \/]([\w.]+)/.exec(ua) || - /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || - /(msie) ([\w.]+)/.exec(ua) || - ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || - []; - - return { - browser: match[ 1 ] || "", - version: match[ 2 ] || "0" - }; - }; - jQuery.browser = {}; - jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; -} - -/** - * Small JavaScript module for the documentation. - */ -var Documentation = { - - init : function() { - this.fixFirefoxAnchorBug(); - this.highlightSearchWords(); - this.initIndexTable(); - - }, - - /** - * i18n support - */ - TRANSLATIONS : {}, - PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, - LOCALE : 'unknown', - - // gettext and ngettext don't access this so that the functions - // can safely bound to a different name (_ = Documentation.gettext) - gettext : function(string) { - var translated = Documentation.TRANSLATIONS[string]; - if (typeof translated == 'undefined') - return string; - return (typeof translated == 'string') ? translated : translated[0]; - }, - - ngettext : function(singular, plural, n) { - var translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated == 'undefined') - return (n == 1) ? singular : plural; - return translated[Documentation.PLURALEXPR(n)]; - }, - - addTranslations : function(catalog) { - for (var key in catalog.messages) - this.TRANSLATIONS[key] = catalog.messages[key]; - this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); - this.LOCALE = catalog.locale; - }, - - /** - * add context elements like header anchor links - */ - addContextElements : function() { - $('div[id] > :header:first').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this headline')). - appendTo(this); - }); - $('dt[id]').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this definition')). - appendTo(this); - }); - }, - - /** - * workaround a firefox stupidity - * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 - */ - fixFirefoxAnchorBug : function() { - if (document.location.hash) - window.setTimeout(function() { - document.location.href += ''; - }, 10); - }, - - /** - * highlight the search words provided in the url in the text - */ - highlightSearchWords : function() { - var params = $.getQueryParameters(); - var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; - if (terms.length) { - var body = $('div.body'); - if (!body.length) { - body = $('body'); - } - window.setTimeout(function() { - $.each(terms, function() { - body.highlightText(this.toLowerCase(), 'highlighted'); - }); - }, 10); - $('') - .appendTo($('#searchbox')); - } - }, - - /** - * init the domain index toggle buttons - */ - initIndexTable : function() { - var togglers = $('img.toggler').click(function() { - var src = $(this).attr('src'); - var idnum = $(this).attr('id').substr(7); - $('tr.cg-' + idnum).toggle(); - if (src.substr(-9) == 'minus.png') - $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); - else - $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); - }).css('display', ''); - if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { - togglers.click(); - } - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords : function() { - $('#searchbox .highlight-link').fadeOut(300); - $('span.highlighted').removeClass('highlighted'); - }, - - /** - * make the url absolute - */ - makeURL : function(relativeURL) { - return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; - }, - - /** - * get the current relative url - */ - getCurrentURL : function() { - var path = document.location.pathname; - var parts = path.split(/\//); - $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { - if (this == '..') - parts.pop(); - }); - var url = parts.join('/'); - return path.substring(url.lastIndexOf('/') + 1, path.length - 1); - }, - - initOnKeyListeners: function() { - $(document).keyup(function(event) { - var activeElementType = document.activeElement.tagName; - // don't navigate when in search box or textarea - if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { - switch (event.keyCode) { - case 37: // left - var prevHref = $('link[rel="prev"]').prop('href'); - if (prevHref) { - window.location.href = prevHref; - return false; - } - case 39: // right - var nextHref = $('link[rel="next"]').prop('href'); - if (nextHref) { - window.location.href = nextHref; - return false; - } - } - } - }); - } -}; - -// quick alias for translations -_ = Documentation.gettext; - -$(document).ready(function() { - Documentation.init(); -}); \ No newline at end of file diff --git a/doc/sphinx/html/_static/down-pressed.png b/doc/sphinx/html/_static/down-pressed.png deleted file mode 100644 index 5756c8cad..000000000 Binary files a/doc/sphinx/html/_static/down-pressed.png and /dev/null differ diff --git a/doc/sphinx/html/_static/down.png b/doc/sphinx/html/_static/down.png deleted file mode 100644 index 1b3bdad2c..000000000 Binary files a/doc/sphinx/html/_static/down.png and /dev/null differ diff --git a/doc/sphinx/html/_static/file.png b/doc/sphinx/html/_static/file.png deleted file mode 100644 index a858a410e..000000000 Binary files a/doc/sphinx/html/_static/file.png and /dev/null differ diff --git a/doc/sphinx/html/_static/jquery-3.1.0.js b/doc/sphinx/html/_static/jquery-3.1.0.js deleted file mode 100644 index f2fc27478..000000000 --- a/doc/sphinx/html/_static/jquery-3.1.0.js +++ /dev/null @@ -1,10074 +0,0 @@ -/*eslint-disable no-unused-vars*/ -/*! - * jQuery JavaScript Library v3.1.0 - * https://jquery.com/ - * - * Includes Sizzle.js - * https://sizzlejs.com/ - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license - * https://jquery.org/license - * - * Date: 2016-07-07T21:44Z - */ -( function( global, factory ) { - - "use strict"; - - if ( typeof module === "object" && typeof module.exports === "object" ) { - - // For CommonJS and CommonJS-like environments where a proper `window` - // is present, execute the factory and get jQuery. - // For environments that do not have a `window` with a `document` - // (such as Node.js), expose a factory as module.exports. - // This accentuates the need for the creation of a real `window`. - // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info. - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 -// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode -// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common -// enough that all such attempts are guarded in a try block. -"use strict"; - -var arr = []; - -var document = window.document; - -var getProto = Object.getPrototypeOf; - -var slice = arr.slice; - -var concat = arr.concat; - -var push = arr.push; - -var indexOf = arr.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var fnToString = hasOwn.toString; - -var ObjectFunctionString = fnToString.call( Object ); - -var support = {}; - - - - function DOMEval( code, doc ) { - doc = doc || document; - - var script = doc.createElement( "script" ); - - script.text = code; - doc.head.appendChild( script ).parentNode.removeChild( script ); - } -/* global Symbol */ -// Defining this global in .eslintrc would create a danger of using the global -// unguarded in another place, it seems safer to define global only for this module - - - -var - version = "3.1.0", - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }, - - // Support: Android <=4.0 only - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - - // Matches dashed string for camelizing - rmsPrefix = /^-ms-/, - rdashAlpha = /-([a-z])/g, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }; - -jQuery.fn = jQuery.prototype = { - - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num != null ? - - // Return just the one element from the set - ( num < 0 ? this[ num + this.length ] : this[ num ] ) : - - // Return all the elements in a clean array - slice.call( this ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - each: function( callback ) { - return jQuery.each( this, callback ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map( this, function( elem, i ) { - return callback.call( elem, i, elem ); - } ) ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[ 0 ] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // Skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { - target = {}; - } - - // Extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - - // Only deal with non-null/undefined values - if ( ( options = arguments[ i ] ) != null ) { - - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject( copy ) || - ( copyIsArray = jQuery.isArray( copy ) ) ) ) { - - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray( src ) ? src : []; - - } else { - clone = src && jQuery.isPlainObject( src ) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend( { - - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - isFunction: function( obj ) { - return jQuery.type( obj ) === "function"; - }, - - isArray: Array.isArray, - - isWindow: function( obj ) { - return obj != null && obj === obj.window; - }, - - isNumeric: function( obj ) { - - // As of jQuery 3.0, isNumeric is limited to - // strings and numbers (primitives or objects) - // that can be coerced to finite numbers (gh-2662) - var type = jQuery.type( obj ); - return ( type === "number" || type === "string" ) && - - // parseFloat NaNs numeric-cast false positives ("") - // ...but misinterprets leading-number strings, particularly hex literals ("0x...") - // subtraction forces infinities to NaN - !isNaN( obj - parseFloat( obj ) ); - }, - - isPlainObject: function( obj ) { - var proto, Ctor; - - // Detect obvious negatives - // Use toString instead of jQuery.type to catch host objects - if ( !obj || toString.call( obj ) !== "[object Object]" ) { - return false; - } - - proto = getProto( obj ); - - // Objects with no prototype (e.g., `Object.create( null )`) are plain - if ( !proto ) { - return true; - } - - // Objects with prototype are plain iff they were constructed by a global Object function - Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; - return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; - }, - - isEmptyObject: function( obj ) { - - /* eslint-disable no-unused-vars */ - // See https://github.com/eslint/eslint/issues/6125 - var name; - - for ( name in obj ) { - return false; - } - return true; - }, - - type: function( obj ) { - if ( obj == null ) { - return obj + ""; - } - - // Support: Android <=2.3 only (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; - }, - - // Evaluates a script in a global context - globalEval: function( code ) { - DOMEval( code ); - }, - - // Convert dashed to camelCase; used by the css and data modules - // Support: IE <=9 - 11, Edge 12 - 13 - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - }, - - each: function( obj, callback ) { - var length, i = 0; - - if ( isArrayLike( obj ) ) { - length = obj.length; - for ( ; i < length; i++ ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } else { - for ( i in obj ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } - - return obj; - }, - - // Support: Android <=4.0 only - trim: function( text ) { - return text == null ? - "" : - ( text + "" ).replace( rtrim, "" ); - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArrayLike( Object( arr ) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - return arr == null ? -1 : indexOf.call( arr, elem, i ); - }, - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - for ( ; j < len; j++ ) { - first[ i++ ] = second[ j ]; - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var length, value, - i = 0, - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArrayLike( elems ) ) { - length = elems.length; - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - var tmp, args, proxy; - - if ( typeof context === "string" ) { - tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - args = slice.call( arguments, 2 ); - proxy = function() { - return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; - }, - - now: Date.now, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -} ); - -if ( typeof Symbol === "function" ) { - jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; -} - -// Populate the class2type map -jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), -function( i, name ) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -} ); - -function isArrayLike( obj ) { - - // Support: real iOS 8.2 only (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, - type = jQuery.type( obj ); - - if ( type === "function" || jQuery.isWindow( obj ) ) { - return false; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} -var Sizzle = -/*! - * Sizzle CSS Selector Engine v2.3.0 - * https://sizzlejs.com/ - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2016-01-04 - */ -(function( window ) { - -var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + 1 * new Date(), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - // Instance methods - hasOwn = ({}).hasOwnProperty, - arr = [], - pop = arr.pop, - push_native = arr.push, - push = arr.push, - slice = arr.slice, - // Use a stripped-down indexOf as it's faster than native - // https://jsperf.com/thor-indexof-vs-for/5 - indexOf = function( list, elem ) { - var i = 0, - len = list.length; - for ( ; i < len; i++ ) { - if ( list[i] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - - // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + - "*\\]", - - pseudos = ":(" + identifier + ")(?:\\((" + - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), - - rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + identifier + ")" ), - "CLASS": new RegExp( "^\\.(" + identifier + ")" ), - "TAG": new RegExp( "^(" + identifier + "|[*])" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - - // CSS escapes - // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), - funescape = function( _, escaped, escapedWhitespace ) { - var high = "0x" + escaped - 0x10000; - // NaN means non-codepoint - // Support: Firefox<24 - // Workaround erroneous numeric interpretation of +"0x" - return high !== high || escapedWhitespace ? - escaped : - high < 0 ? - // BMP codepoint - String.fromCharCode( high + 0x10000 ) : - // Supplemental Plane codepoint (surrogate pair) - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }, - - // CSS string/identifier serialization - // https://drafts.csswg.org/cssom/#common-serializing-idioms - rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g, - fcssescape = function( ch, asCodePoint ) { - if ( asCodePoint ) { - - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if ( ch === "\0" ) { - return "\uFFFD"; - } - - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; - } - - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; - }, - - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function() { - setDocument(); - }, - - disabledAncestor = addCombinator( - function( elem ) { - return elem.disabled === true; - }, - { dir: "parentNode", next: "legend" } - ); - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - (arr = slice.call( preferredDoc.childNodes )), - preferredDoc.childNodes - ); - // Support: Android<4.0 - // Detect silently failing push.apply - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - push_native.apply( target, slice.call(els) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - // Can't trust NodeList.length - while ( (target[j++] = els[i++]) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var m, i, elem, nid, match, groups, newSelector, - newContext = context && context.ownerDocument, - - // nodeType defaults to 9, since context defaults to document - nodeType = context ? context.nodeType : 9; - - results = results || []; - - // Return early from calls with invalid selector or context - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { - - return results; - } - - // Try to shortcut find operations (as opposed to filters) in HTML documents - if ( !seed ) { - - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } - context = context || document; - - if ( documentIsHTML ) { - - // If the selector is sufficiently simple, try using a "get*By*" DOM method - // (excepting DocumentFragment context, where the methods don't exist) - if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { - - // ID selector - if ( (m = match[1]) ) { - - // Document context - if ( nodeType === 9 ) { - if ( (elem = context.getElementById( m )) ) { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - - // Element context - } else { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( newContext && (elem = newContext.getElementById( m )) && - contains( context, elem ) && - elem.id === m ) { - - results.push( elem ); - return results; - } - } - - // Type selector - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Class selector - } else if ( (m = match[3]) && support.getElementsByClassName && - context.getElementsByClassName ) { - - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // Take advantage of querySelectorAll - if ( support.qsa && - !compilerCache[ selector + " " ] && - (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - - if ( nodeType !== 1 ) { - newContext = context; - newSelector = selector; - - // qSA looks outside Element context, which is not what we want - // Thanks to Andrew Dupont for this workaround technique - // Support: IE <=8 - // Exclude object elements - } else if ( context.nodeName.toLowerCase() !== "object" ) { - - // Capture the context ID, setting it first if necessary - if ( (nid = context.getAttribute( "id" )) ) { - nid = nid.replace( rcssescape, fcssescape ); - } else { - context.setAttribute( "id", (nid = expando) ); - } - - // Prefix every selector in the list - groups = tokenize( selector ); - i = groups.length; - while ( i-- ) { - groups[i] = "#" + nid + " " + toSelector( groups[i] ); - } - newSelector = groups.join( "," ); - - // Expand context for sibling selectors - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; - } - - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch ( qsaError ) { - } finally { - if ( nid === expando ) { - context.removeAttribute( "id" ); - } - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {function(string, object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return (cache[ key + " " ] = value); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created element and returns a boolean result - */ -function assert( fn ) { - var el = document.createElement("fieldset"); - - try { - return !!fn( el ); - } catch (e) { - return false; - } finally { - // Remove from its parent by default - if ( el.parentNode ) { - el.parentNode.removeChild( el ); - } - // release memory in IE - el = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split("|"), - i = arr.length; - - while ( i-- ) { - Expr.attrHandle[ arr[i] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - a.sourceIndex - b.sourceIndex; - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( (cur = cur.nextSibling) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for :enabled/:disabled - * @param {Boolean} disabled true for :disabled; false for :enabled - */ -function createDisabledPseudo( disabled ) { - // Known :disabled false positives: - // IE: *[disabled]:not(button, input, select, textarea, optgroup, option, menuitem, fieldset) - // not IE: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable - return function( elem ) { - - // Check form elements and option elements for explicit disabling - return "label" in elem && elem.disabled === disabled || - "form" in elem && elem.disabled === disabled || - - // Check non-disabled form elements for fieldset[disabled] ancestors - "form" in elem && elem.disabled === false && ( - // Support: IE6-11+ - // Ancestry is covered for us - elem.isDisabled === disabled || - - // Otherwise, assume any non-