s7datablock 0.0.0a0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. s7datablock-0.0.0a0/.coveragerc +28 -0
  2. s7datablock-0.0.0a0/.github/workflows/ci.yml +91 -0
  3. s7datablock-0.0.0a0/.gitignore +54 -0
  4. s7datablock-0.0.0a0/.isort.cfg +3 -0
  5. s7datablock-0.0.0a0/.pre-commit-config.yaml +54 -0
  6. s7datablock-0.0.0a0/.readthedocs.yml +27 -0
  7. s7datablock-0.0.0a0/AUTHORS.md +3 -0
  8. s7datablock-0.0.0a0/LICENSE.txt +21 -0
  9. s7datablock-0.0.0a0/PKG-INFO +136 -0
  10. s7datablock-0.0.0a0/README.md +114 -0
  11. s7datablock-0.0.0a0/docs/Makefile +29 -0
  12. s7datablock-0.0.0a0/docs/_static/.gitignore +1 -0
  13. s7datablock-0.0.0a0/docs/authors.md +4 -0
  14. s7datablock-0.0.0a0/docs/changelog.md +4 -0
  15. s7datablock-0.0.0a0/docs/conf.py +299 -0
  16. s7datablock-0.0.0a0/docs/contributing.md +4 -0
  17. s7datablock-0.0.0a0/docs/index.md +39 -0
  18. s7datablock-0.0.0a0/docs/license.md +5 -0
  19. s7datablock-0.0.0a0/docs/readme.md +4 -0
  20. s7datablock-0.0.0a0/docs/requirements.txt +6 -0
  21. s7datablock-0.0.0a0/examples/basic_usage.py +33 -0
  22. s7datablock-0.0.0a0/examples/dtl_date.py +83 -0
  23. s7datablock-0.0.0a0/examples/parse_file.py +41 -0
  24. s7datablock-0.0.0a0/pyproject.toml +65 -0
  25. s7datablock-0.0.0a0/src/s7datablock/__init__.py +23 -0
  26. s7datablock-0.0.0a0/src/s7datablock/constants.py +93 -0
  27. s7datablock-0.0.0a0/src/s7datablock/fields.py +341 -0
  28. s7datablock-0.0.0a0/src/s7datablock/grammar.py +112 -0
  29. s7datablock-0.0.0a0/src/s7datablock/mapping.py +207 -0
  30. s7datablock-0.0.0a0/src/s7datablock/parser.py +83 -0
  31. s7datablock-0.0.0a0/src/s7datablock/py.typed +0 -0
  32. s7datablock-0.0.0a0/test_buffer_mapping_extended.py +33 -0
  33. s7datablock-0.0.0a0/tests/conftest.py +10 -0
  34. s7datablock-0.0.0a0/tests/definitions/s7_1200_out.db +24 -0
  35. s7datablock-0.0.0a0/tests/definitions/tester.db +29 -0
  36. s7datablock-0.0.0a0/tests/test_buffer_mapping.py +43 -0
  37. s7datablock-0.0.0a0/tests/test_buffer_mapping_extended.py +106 -0
  38. s7datablock-0.0.0a0/tests/test_dtl_struct.py +58 -0
  39. s7datablock-0.0.0a0/tests/test_s7_connector.py +52 -0
  40. s7datablock-0.0.0a0/tests/test_s7_parsing.py +232 -0
  41. s7datablock-0.0.0a0/tests/test_s7_utils.py +162 -0
  42. s7datablock-0.0.0a0/uv.lock +284 -0
@@ -0,0 +1,28 @@
1
+ # .coveragerc to control coverage.py
2
+ [run]
3
+ branch = True
4
+ source = s7datablock
5
+ # omit = bad_file.py
6
+
7
+ [paths]
8
+ source =
9
+ src/
10
+ */site-packages/
11
+
12
+ [report]
13
+ # Regexes for lines to exclude from consideration
14
+ exclude_lines =
15
+ # Have to re-enable the standard pragma
16
+ pragma: no cover
17
+
18
+ # Don't complain about missing debug-only code:
19
+ def __repr__
20
+ if self\.debug
21
+
22
+ # Don't complain if tests don't hit defensive assertion code:
23
+ raise AssertionError
24
+ raise NotImplementedError
25
+
26
+ # Don't complain if non-runnable code isn't run:
27
+ if 0:
28
+ if __name__ == .__main__.:
@@ -0,0 +1,91 @@
1
+ # GitHub Actions configuration **EXAMPLE**,
2
+ # MODIFY IT ACCORDING TO YOUR NEEDS!
3
+ # Reference: https://docs.github.com/en/actions
4
+
5
+ name: CI
6
+
7
+ on:
8
+ pull_request:
9
+ push:
10
+ branches:
11
+ - "main"
12
+ tags: ['v*'] # Keep tag support for releases
13
+
14
+ permissions:
15
+ pull-requests: write
16
+ contents: write
17
+ id-token: write # Needed for PyPI publishing
18
+
19
+ env:
20
+ UV_CACHE_DIR: /tmp/.uv-cache
21
+
22
+ jobs:
23
+ test:
24
+ strategy:
25
+ matrix:
26
+ python-version: ["3.11", "3.12", "3.13"]
27
+ platform: [ubuntu-latest, ]
28
+ # platform: [ubuntu-latest, macos-latest, windows-latest] # Uncomment for cross-platform testing
29
+ runs-on: ${{ matrix.platform }}
30
+ steps:
31
+ - uses: actions/checkout@v4
32
+
33
+ - name: Install uv
34
+ uses: astral-sh/setup-uv@v5
35
+ with:
36
+ python-version: ${{ matrix.python-version }}
37
+
38
+ - name: Restore uv cache
39
+ uses: actions/cache@v4
40
+ with:
41
+ path: ${{ env.UV_CACHE_DIR }}
42
+ key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
43
+ restore-keys: |
44
+ uv-${{ runner.os }}-${{ hashFiles('uv.lock') }}
45
+ uv-${{ runner.os }}
46
+
47
+ - name: Install dependencies
48
+ run: uv sync --locked --all-extras
49
+
50
+ - name: Run linting
51
+ run: uv run ruff check .
52
+
53
+ - name: Run tests with coverage
54
+ run: uv run pytest --cov s7datablock --cov-report=term-missing
55
+
56
+ - name: Minimize uv cache
57
+ run: uv cache prune --ci
58
+
59
+ build-and-publish:
60
+ needs: test
61
+ if: startsWith(github.ref, 'refs/tags/')
62
+ runs-on: ubuntu-latest
63
+ steps:
64
+ - uses: actions/checkout@v4
65
+
66
+ - name: Install uv
67
+ uses: astral-sh/setup-uv@v5
68
+ with:
69
+ python-version: "3.11"
70
+
71
+ - name: Update version from tag
72
+ run: |
73
+ VERSION=${GITHUB_REF#refs/tags/v}
74
+ echo "Setting version to $VERSION"
75
+ sed -i 's/^version = ".*"/version = "'$VERSION'"/' pyproject.toml
76
+
77
+ - name: Build package
78
+ run: |
79
+ uv pip install build
80
+ uv run python -m build
81
+
82
+ - name: Publish to PyPI
83
+ uses: pypa/gh-action-pypi-publish@release/v1
84
+ with:
85
+ password: ${{ secrets.PYPI_API_TOKEN }}
86
+
87
+ - name: Create GitHub Release
88
+ uses: softprops/action-gh-release@v2
89
+ with:
90
+ files: dist/*
91
+ prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') }}
@@ -0,0 +1,54 @@
1
+ # Temporary and binary files
2
+ *~
3
+ *.py[cod]
4
+ *.so
5
+ *.cfg
6
+ !.isort.cfg
7
+ !setup.cfg
8
+ *.orig
9
+ *.log
10
+ *.pot
11
+ __pycache__/*
12
+ .cache/*
13
+ .*.swp
14
+ */.ipynb_checkpoints/*
15
+ .DS_Store
16
+
17
+ # Project files
18
+ .ropeproject
19
+ .project
20
+ .pydevproject
21
+ .settings
22
+ .idea
23
+ .vscode
24
+ tags
25
+
26
+ # Package files
27
+ *.egg
28
+ *.eggs/
29
+ .installed.cfg
30
+ *.egg-info
31
+
32
+ # Unittest and coverage
33
+ htmlcov/*
34
+ .coverage
35
+ .coverage.*
36
+ .tox
37
+ junit*.xml
38
+ coverage.xml
39
+ .pytest_cache/
40
+
41
+ # Build and docs folder/files
42
+ build/*
43
+ dist/*
44
+ sdist/*
45
+ docs/api/*
46
+ docs/_rst/*
47
+ docs/_build/*
48
+ cover/*
49
+ MANIFEST
50
+
51
+ # Per-project virtualenvs
52
+ .venv*/
53
+ .conda*/
54
+ .python-version
@@ -0,0 +1,3 @@
1
+ [settings]
2
+ profile = black
3
+ known_first_party = s7datablock
@@ -0,0 +1,54 @@
1
+ exclude: |
2
+ (?x)^(
3
+ docs/.*| # exclude docs folder
4
+ tests/definitions/.* # exclude files in the definitions folder
5
+ )$
6
+
7
+ repos:
8
+ - repo: https://github.com/pre-commit/pre-commit-hooks
9
+ rev: v5.0.0
10
+ hooks:
11
+ - id: trailing-whitespace
12
+ - id: check-added-large-files
13
+ - id: check-ast
14
+ - id: check-json
15
+ - id: check-merge-conflict
16
+ - id: check-xml
17
+ - id: check-yaml
18
+ - id: debug-statements
19
+ - id: end-of-file-fixer
20
+ - id: requirements-txt-fixer
21
+ - id: mixed-line-ending
22
+ args: ["--fix=auto"] # replace 'auto' with 'lf' to enforce Linux/Mac line endings or 'crlf' for Windows
23
+
24
+ # If you want to automatically "modernize" your Python code:
25
+ - repo: https://github.com/asottile/pyupgrade
26
+ rev: v3.10.1
27
+ hooks:
28
+ - id: pyupgrade
29
+ args: ["--py311-plus"]
30
+
31
+ - repo: https://github.com/PyCQA/isort
32
+ rev: 5.12.0
33
+ hooks:
34
+ - id: isort
35
+
36
+ - repo: https://github.com/psf/black
37
+ rev: 23.7.0
38
+ hooks:
39
+ - id: black
40
+ language_version: python3
41
+
42
+ - repo: https://github.com/astral-sh/ruff-pre-commit
43
+ # Ruff version.
44
+ rev: v0.0.284
45
+ hooks:
46
+ - id: ruff
47
+ args: [--fix, --exit-non-zero-on-fix]
48
+
49
+ # Check for misspells in documentation files:
50
+ - repo: https://github.com/codespell-project/codespell
51
+ rev: v2.2.5
52
+ hooks:
53
+ - id: codespell
54
+ args: [-L gud]
@@ -0,0 +1,27 @@
1
+ # Read the Docs configuration file
2
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3
+
4
+ # Required
5
+ version: 2
6
+
7
+ # Build documentation in the docs/ directory with Sphinx
8
+ sphinx:
9
+ configuration: docs/conf.py
10
+
11
+ # Build documentation with MkDocs
12
+ #mkdocs:
13
+ # configuration: mkdocs.yml
14
+
15
+ # Optionally build your docs in additional formats such as PDF
16
+ formats:
17
+ - pdf
18
+
19
+ build:
20
+ os: ubuntu-22.04
21
+ tools:
22
+ python: "3.11"
23
+
24
+ python:
25
+ install:
26
+ - requirements: docs/requirements.txt
27
+ - {path: ., method: pip}
@@ -0,0 +1,3 @@
1
+ # Contributors
2
+
3
+ * Thijs Damsma [thijs@damsma.net](mailto:thijs@damsma.net)
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 CEAD
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,136 @@
1
+ Metadata-Version: 2.4
2
+ Name: s7datablock
3
+ Version: 0.0.0a0
4
+ Summary: A Python library interacting with Siemens S7 PLC datablocks
5
+ Project-URL: Homepage, https://github.com/pyscaffold/pyscaffold/
6
+ Project-URL: Documentation, https://pyscaffold.org/
7
+ Author-email: Thijs Damsma <thijs@damsma.net>
8
+ License: MIT
9
+ License-File: AUTHORS.md
10
+ License-File: LICENSE.txt
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Programming Language :: Python
13
+ Requires-Python: >=3.11
14
+ Requires-Dist: pyparsing
15
+ Requires-Dist: python-snap7
16
+ Requires-Dist: rich
17
+ Provides-Extra: testing
18
+ Requires-Dist: pytest; extra == 'testing'
19
+ Requires-Dist: pytest-cov; extra == 'testing'
20
+ Requires-Dist: ruff; extra == 'testing'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # S7DataBlock
24
+
25
+ - [S7DataBlock](#s7datablock)
26
+ - [Introduction](#introduction)
27
+ - [Installation](#installation)
28
+ - [Parsing Data Blocks](#parsing-data-blocks)
29
+ - [Contributing and Issues](#contributing-and-issues)
30
+
31
+ ## Introduction
32
+
33
+ > A Python library for parsing Siemens S7 PLC data blocks, in conjunction with Snap7.
34
+
35
+ `s7datablock` is a Python library designed to parse and interpret Siemens S7 PLC data blocks. It works in conjunction with the [python-snap7](https://github.com/gijzelaerr/python-snap7) library, providing a set of tools and utilities to read and write the bytes in a PLC datablock as structured data, using the DB definitions as exported from a TIA Portal project. This makes it easier for developers and engineers to work with Siemens S7 PLCs in their Python applications.
36
+
37
+ Instead of manually mapping bytes, the dataformat defined in Tia Portal can be used to generate the appropriate Python mapping. The configuration file can be kept separate from the code, making it easier to track versions and support complicated data structures.
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ pip install s7datablock
43
+ ```
44
+
45
+ ### Parsing Data Blocks
46
+
47
+ In this example, we will demonstrate how to use the `s7datablock` library to parse and interpret Siemens S7 PLC data blocks.
48
+
49
+ First, we define a s7_1200_out user-defined type (UDT) and a data block in Structured Control Language (SCL). The UDT, named "s7_1200_out_udt", consists of five boolean variables and one integer variable. The data block, named "s7_1200_out", uses this UDT. This file was defined in and exported from Tia Portal, using the `generate source from blocks, including all dependent blocks` option.
50
+
51
+ ```scl
52
+ # s7_1200_out.db
53
+ TYPE "s7_1200_out_udt"
54
+ VERSION : 0.1
55
+ STRUCT
56
+ PLC_DQ_0 : Bool; # Boolean variable
57
+ PLC_DQ_1 : Bool; # Boolean variable
58
+ PLC_DQ_2 : Bool; # Boolean variable
59
+ PLC_DQ_3 : Bool; # Boolean variable
60
+ PLC_DQ_4 : Bool; # Boolean variable
61
+ SB_AQ_0 : Int; # Integer variable
62
+ END_STRUCT;
63
+ END_TYPE
64
+
65
+ DATA_BLOCK "s7_1200_out"
66
+ { S7_Optimized_Access := 'FALSE' }
67
+ VERSION : 0.1
68
+ NON_RETAIN
69
+ "s7_1200_out_udt"
70
+
71
+ BEGIN
72
+
73
+ END_DATA_BLOCK
74
+ ```
75
+
76
+ Next, we use the `S7DataBlock` class from the `s7datablock` library to parse the data block definition file. We then display the parsed data block and its initial buffer state. Finally, we modify one of the boolean variables in the data block and display the updated buffer state.
77
+
78
+ ```python
79
+ # Import necessary modules
80
+ from s7datablock.mapping import S7DataBlock
81
+ from pathlib import Path
82
+
83
+ # Parse the data block definition file
84
+ db1200 = S7DataBlock.from_definition_file(
85
+ Path("tests/definitions/s7_1200_out.db"),
86
+ db_number=1200
87
+ )
88
+
89
+ # The printing the db1200 datasrutcure produces a nicely formatted output
90
+ print(db1200)
91
+ ```
92
+
93
+ ```raw
94
+ Data Block Structure
95
+ ┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━┓
96
+ ┃ Name ┃ Data type ┃ Offset ┃ Value ┃
97
+ ┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━┩
98
+ │ PLC_DQ_0 │ Bool │ 0.0 │ False │
99
+ │ PLC_DQ_1 │ Bool │ 0.1 │ False │
100
+ │ PLC_DQ_2 │ Bool │ 0.2 │ False │
101
+ │ PLC_DQ_3 │ Bool │ 0.3 │ False │
102
+ │ PLC_DQ_4 │ Bool │ 0.4 │ False │
103
+ │ SB_AQ_0 │ Int │ 2.0 │ 0 │
104
+ │ TIMEFIELD │ DTL │ 4.0 │ None │
105
+ │ YEAR │ UInt │ 4.0 │ 0 │
106
+ │ MONTH │ USInt │ 6.0 │ 0 │
107
+ │ DAY │ USInt │ 7.0 │ 0 │
108
+ │ WEEKDAY │ USInt │ 8.0 │ 0 │
109
+ │ HOUR │ USInt │ 9.0 │ 0 │
110
+ │ MINUTE │ USInt │ 10.0 │ 0 │
111
+ │ SECOND │ USInt │ 11.0 │ 0 │
112
+ │ NANOSECOND │ UDInt │ 12.0 │ 0 │
113
+ └──────────────────┴─────────────┴──────────┴─────────────┘
114
+ Total size: 16 bytes
115
+ ```
116
+
117
+ ```python
118
+ # db1200 maps the data like a dictionary but the hood it stores the data in a continuous buffer,
119
+ # using the same format and byte ordering as the PLC
120
+ # Initially the buffer is only zeros
121
+ print(db1200.buffer)
122
+ # Output: bytearray(b'\x00\x00\x00\x00')
123
+
124
+ # Modify one of the boolean variables
125
+ db1200["PLC_DQ_3"] = True
126
+
127
+ # Now one bit has changed
128
+ print(db1200.buffer)
129
+ # Output: bytearray(b'\x08\x00\x00\x00')
130
+ ```
131
+
132
+
133
+
134
+ ## Contributing and Issues
135
+
136
+ The library is in its early stages, and contributions are welcome. Feel free to submit a pull request or open an issue on GitHub.
@@ -0,0 +1,114 @@
1
+ # S7DataBlock
2
+
3
+ - [S7DataBlock](#s7datablock)
4
+ - [Introduction](#introduction)
5
+ - [Installation](#installation)
6
+ - [Parsing Data Blocks](#parsing-data-blocks)
7
+ - [Contributing and Issues](#contributing-and-issues)
8
+
9
+ ## Introduction
10
+
11
+ > A Python library for parsing Siemens S7 PLC data blocks, in conjunction with Snap7.
12
+
13
+ `s7datablock` is a Python library designed to parse and interpret Siemens S7 PLC data blocks. It works in conjunction with the [python-snap7](https://github.com/gijzelaerr/python-snap7) library, providing a set of tools and utilities to read and write the bytes in a PLC datablock as structured data, using the DB definitions as exported from a TIA Portal project. This makes it easier for developers and engineers to work with Siemens S7 PLCs in their Python applications.
14
+
15
+ Instead of manually mapping bytes, the dataformat defined in Tia Portal can be used to generate the appropriate Python mapping. The configuration file can be kept separate from the code, making it easier to track versions and support complicated data structures.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pip install s7datablock
21
+ ```
22
+
23
+ ### Parsing Data Blocks
24
+
25
+ In this example, we will demonstrate how to use the `s7datablock` library to parse and interpret Siemens S7 PLC data blocks.
26
+
27
+ First, we define a s7_1200_out user-defined type (UDT) and a data block in Structured Control Language (SCL). The UDT, named "s7_1200_out_udt", consists of five boolean variables and one integer variable. The data block, named "s7_1200_out", uses this UDT. This file was defined in and exported from Tia Portal, using the `generate source from blocks, including all dependent blocks` option.
28
+
29
+ ```scl
30
+ # s7_1200_out.db
31
+ TYPE "s7_1200_out_udt"
32
+ VERSION : 0.1
33
+ STRUCT
34
+ PLC_DQ_0 : Bool; # Boolean variable
35
+ PLC_DQ_1 : Bool; # Boolean variable
36
+ PLC_DQ_2 : Bool; # Boolean variable
37
+ PLC_DQ_3 : Bool; # Boolean variable
38
+ PLC_DQ_4 : Bool; # Boolean variable
39
+ SB_AQ_0 : Int; # Integer variable
40
+ END_STRUCT;
41
+ END_TYPE
42
+
43
+ DATA_BLOCK "s7_1200_out"
44
+ { S7_Optimized_Access := 'FALSE' }
45
+ VERSION : 0.1
46
+ NON_RETAIN
47
+ "s7_1200_out_udt"
48
+
49
+ BEGIN
50
+
51
+ END_DATA_BLOCK
52
+ ```
53
+
54
+ Next, we use the `S7DataBlock` class from the `s7datablock` library to parse the data block definition file. We then display the parsed data block and its initial buffer state. Finally, we modify one of the boolean variables in the data block and display the updated buffer state.
55
+
56
+ ```python
57
+ # Import necessary modules
58
+ from s7datablock.mapping import S7DataBlock
59
+ from pathlib import Path
60
+
61
+ # Parse the data block definition file
62
+ db1200 = S7DataBlock.from_definition_file(
63
+ Path("tests/definitions/s7_1200_out.db"),
64
+ db_number=1200
65
+ )
66
+
67
+ # The printing the db1200 datasrutcure produces a nicely formatted output
68
+ print(db1200)
69
+ ```
70
+
71
+ ```raw
72
+ Data Block Structure
73
+ ┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━┓
74
+ ┃ Name ┃ Data type ┃ Offset ┃ Value ┃
75
+ ┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━┩
76
+ │ PLC_DQ_0 │ Bool │ 0.0 │ False │
77
+ │ PLC_DQ_1 │ Bool │ 0.1 │ False │
78
+ │ PLC_DQ_2 │ Bool │ 0.2 │ False │
79
+ │ PLC_DQ_3 │ Bool │ 0.3 │ False │
80
+ │ PLC_DQ_4 │ Bool │ 0.4 │ False │
81
+ │ SB_AQ_0 │ Int │ 2.0 │ 0 │
82
+ │ TIMEFIELD │ DTL │ 4.0 │ None │
83
+ │ YEAR │ UInt │ 4.0 │ 0 │
84
+ │ MONTH │ USInt │ 6.0 │ 0 │
85
+ │ DAY │ USInt │ 7.0 │ 0 │
86
+ │ WEEKDAY │ USInt │ 8.0 │ 0 │
87
+ │ HOUR │ USInt │ 9.0 │ 0 │
88
+ │ MINUTE │ USInt │ 10.0 │ 0 │
89
+ │ SECOND │ USInt │ 11.0 │ 0 │
90
+ │ NANOSECOND │ UDInt │ 12.0 │ 0 │
91
+ └──────────────────┴─────────────┴──────────┴─────────────┘
92
+ Total size: 16 bytes
93
+ ```
94
+
95
+ ```python
96
+ # db1200 maps the data like a dictionary but the hood it stores the data in a continuous buffer,
97
+ # using the same format and byte ordering as the PLC
98
+ # Initially the buffer is only zeros
99
+ print(db1200.buffer)
100
+ # Output: bytearray(b'\x00\x00\x00\x00')
101
+
102
+ # Modify one of the boolean variables
103
+ db1200["PLC_DQ_3"] = True
104
+
105
+ # Now one bit has changed
106
+ print(db1200.buffer)
107
+ # Output: bytearray(b'\x08\x00\x00\x00')
108
+ ```
109
+
110
+
111
+
112
+ ## Contributing and Issues
113
+
114
+ The library is in its early stages, and contributions are welcome. Feel free to submit a pull request or open an issue on GitHub.
@@ -0,0 +1,29 @@
1
+ # Makefile for Sphinx documentation
2
+ #
3
+
4
+ # You can set these variables from the command line, and also
5
+ # from the environment for the first two.
6
+ SPHINXOPTS ?=
7
+ SPHINXBUILD ?= sphinx-build
8
+ SOURCEDIR = .
9
+ BUILDDIR = _build
10
+ AUTODOCDIR = api
11
+
12
+ # User-friendly check for sphinx-build
13
+ ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $?), 1)
14
+ $(error "The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from https://sphinx-doc.org/")
15
+ endif
16
+
17
+ .PHONY: help clean Makefile
18
+
19
+ # Put it first so that "make" without argument is like "make help".
20
+ help:
21
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
22
+
23
+ clean:
24
+ rm -rf $(BUILDDIR)/* $(AUTODOCDIR)
25
+
26
+ # Catch-all target: route all unknown targets to Sphinx using the new
27
+ # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
28
+ %: Makefile
29
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@@ -0,0 +1 @@
1
+ # Empty directory
@@ -0,0 +1,4 @@
1
+ ```{include} ../AUTHORS.md
2
+ :relative-docs: docs/
3
+ :relative-images:
4
+ ```
@@ -0,0 +1,4 @@
1
+ ```{include} ../CHANGELOG.md
2
+ :relative-docs: docs/
3
+ :relative-images:
4
+ ```