Compare commits

...

10 Commits

Author SHA1 Message Date
Nicolas 2a794d5a51 cff-version updated to 1.2.0 2025-08-04 21:31:16 +02:00
Nicolas 0c86ae95e6 add DOI to CITATION.cff 2025-08-04 21:23:23 +02:00
Nicolas 4e1ac7aa5b updated version to v1.1.2 2025-08-04 21:11:43 +02:00
Nicolas c3a29e0e63 Readme: "Adding new terminals" section added 2025-08-04 21:11:43 +02:00
Nicolas 49f654993e Change docs path and update publishing method 2025-08-04 21:11:43 +02:00
Nicolas 0f5eda6cfc py.typed file added indication package uses type annotations 2025-08-04 21:11:43 +02:00
Nicolas 6cb067ce43 CITATION.cff fixed and CITATION.cff validation added to CI 2025-08-04 21:11:43 +02:00
Nicolas ddec81acaa readme updated 2025-08-04 21:11:43 +02:00
Nicolas 6cb3e216a2 version number updated 2025-08-04 21:11:43 +02:00
Nicolas e160fd2162 Missing docstrings added 2025-08-04 21:11:43 +02:00
13 changed files with 122 additions and 37 deletions

View File

@ -12,9 +12,10 @@ exclude =
__pycache__,
build,
dist,
.conda
.venv
venv
.conda,
.venv,
venv,
docs/source/api
# Enable specific plugins or options
# Example: Enabling flake8-docstrings

View File

@ -27,6 +27,13 @@ jobs:
run: |
python -m pip install --upgrade pip
python -m pip install -e .[dev]
if [ "${{ matrix.python-version }}" = "3.13" ]; then
python -m pip install cffconvert
fi
- name: Validate CITATION.cff
if: ${{ matrix.python-version == '3.13' }}
run: cffconvert --validate
- name: Lint code with flake8
run: flake8

View File

@ -9,7 +9,7 @@ permissions:
contents: write
jobs:
build-and-deploy:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -29,8 +29,24 @@ jobs:
rm ./source/*.rst
make html
touch ./build/html/.nojekyll
- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@v4
mkdir -p ./build/html/_autogenerated
cp ./build/html/api/* ./build/html/_autogenerated/
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
branch: gh-pages
folder: docs/build/html
path: docs/build/html
deploy:
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

View File

@ -10,6 +10,10 @@ jobs:
name: Build and publish
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/project/${{ github.event.repository.name }}/
steps:
- uses: actions/checkout@v3

2
.gitignore vendored
View File

@ -70,7 +70,7 @@ instance/
# Sphinx documentation
docs/_build/
docs/source/_autogenerated/
docs/source/api/
# Autogenerated documentation
docs/source/modules.md

View File

@ -1,15 +1,16 @@
cff-version: 1.2.0
message: "If you use this software, please cite it as below."
title: pyhoff
abstract: The pyhoff package allows easy accessing of Beckhoff and Wago terminals with python over ModBus TCP
authors:
- family-names: Kruse
given-names: Nicolas
orcid: "https://orcid.org/0000-0001-6758-2269"
version: 1.1.0
#date-released: "2025-04-01"
#identifiers:
# - description: This is the collection of archived snapshots of all versions of My Research Software
# type: doi
# value: "10.5281/"
license: MIT License
version: v1.1.2
date-released: "2025-08-04"
identifiers:
- description: This is the collection of archived snapshots of all versions of pyhoff
type: doi
value: "10.5281/zenodo.16740202"
license: MIT
repository-code: "https://github.com/Nonannet/pyhoff"

View File

@ -1,6 +1,5 @@
# Pyhoff
## Description
The pyhoff package allows you to read and write the most common
Beckhoff and WAGO bus terminals ("Busklemmen") using the Ethernet bus
coupler ("Busskoppler") BK9000, BK9050, BK9100, or WAGO 750_352
@ -55,6 +54,62 @@ bk.select(KL4002, 0).set_voltage(1, 4.2)
```
## Adding new terminals
The package comes with automatic generated code stubs for nearly all
terminals. These stubs are not tested with hardware but for most
digital IO terminals the code should be fully functional.
Such a stub looks like this:
```python
# From ./src/pyhoff/devices.py:
class KL2442(DigitalOutputTerminal):
"""
KL2442: 2-channel digital output, 24 V DC, 2 x 4 A/1 x 8 A
(Automatic generated stub)
"""
parameters = {'output_bit_width': 2, 'input_bit_width': 0}
```
For analog IO terminals the stubs are functional as well,
but they provide only a generic `read_channel_word` and
`read_normalized` function (for inputs) without scaling the
values to voltages, currents or temperatures. For better usability
they might be extended with functions. Based on the stub the
extension could look like this:
```python
from pyhoff.devices import KL3054 as KL3054_stub
class KL3054(KL3054_stub):
def read_current(self, channel: int) -> float:
return self.read_normalized(channel) * 16.0 + 4.0
```
Or for contributing to the pyhoff package, the existing stub
code can be updated like this:
```python
# From ./src/pyhoff/devices.py:
class KL3054(AnalogInputTerminal):
"""
KL3054: 4x analog input 4...20 mA 12 Bit single-ended
"""
# Input: 4 x 16 Bit Daten (optional 4x 8 Bit Control/Status)
parameters = {'input_word_width': 4}
def read_current(self, channel: int) -> float:
"""
Read the current value from a specific channel.
Args:
channel: The channel number to read from.
Returns:
The current value in mA.
"""
return self.read_normalized(channel) * 16.0 + 4.0
```
## Contributing
Other analog and digital IO terminals are easy to complement. Contributions are welcome!
Please open an issue or submit a pull request on GitHub.
@ -62,32 +117,24 @@ Please open an issue or submit a pull request on GitHub.
## Developer Guide
To get started with developing the `pyhoff` package, follow these steps:
1. **Clone the Repository**
First, clone the repository to your local machine using Git:
1. First, clone the repository to your local machine using Git:
```bash
git clone https://github.com/Nonannet/pyhoff.git
cd pyhoff
```
2. **Set Up a Virtual Environment**
It is recommended to use a virtual environment to manage dependencies. You can create one using `venv`:
2. It is recommended to use a virtual environment:
```bash
python -m venv venv
source venv/bin/activate # On Windows use `venv\Scripts\activate`
python -m venv .venv
source .venv/bin/activate # On Windows/Powershell use `.\venv\Scripts\Activate.ps1`
```
3. **Install Dev Dependencies**
Install pyhoff from source plus the dependencies required for development using `pip`:
3. Install pyhoff from source plus the development dependencies:
```bash
pip install -e .[dev]
```
4. **Run Tests**
Ensure that everything is set up correctly by running the tests:
4. Ensure that everything is set up correctly by running the tests:
```bash
pytest
```

View File

@ -24,7 +24,7 @@ def write_classes(f: TextIOWrapper, patterns: list[str], module_name: str, title
write_dochtree(f, title, classes)
for cls in classes:
with open(f'docs/source/_autogenerated/{cls}.md', 'w') as f2:
with open(f'docs/source/api/{cls}.md', 'w') as f2:
f2.write(f'# {module_name}.{cls}\n')
f2.write('```{eval-rst}\n')
f2.write(f'.. autoclass:: {module_name}.{cls}\n')
@ -52,9 +52,9 @@ def write_dochtree(f: TextIOWrapper, title: str, items: list[str]):
if __name__ == "__main__":
# Ensure the output directory exists
os.makedirs('docs/source/_autogenerated', exist_ok=True)
os.makedirs('docs/source/api', exist_ok=True)
with open('docs/source/_autogenerated/index.md', 'w') as f:
with open('docs/source/api/index.md', 'w') as f:
f.write('# Classes and Modules\n\n')
write_classes(f, ['BK*', 'WAGO_750_352'], 'pyhoff.devices', title='Bus coupler',

View File

@ -1,7 +1,8 @@
```{toctree}
:maxdepth: 1
:hidden:
_autogenerated/index
api/index
repo
```
```{include} ../../README.md

3
docs/source/repo.md Normal file
View File

@ -0,0 +1,3 @@
# Code repository
Code repository is on GitHub: [github.com/Nonannet/pyhoff](https://github.com/Nonannet/pyhoff).

View File

@ -1,6 +1,6 @@
[project]
name = "pyhoff"
version = "1.1.1"
version = "1.1.2"
authors = [
{ name="Nicolas Kruse", email="nicolas.kruse@nonan.net" },
]
@ -25,6 +25,9 @@ build-backend = "setuptools.build_meta"
[tool.setuptools.packages.find]
where = ["src"]
[tool.setuptools.package-data]
pyhoff = ["py.typed"]
[project.optional-dependencies]
dev = [
"pytest", "flake8", "mypy"

View File

@ -137,9 +137,10 @@ class AnalogInputTerminal(BusTerminal):
Args:
channel: The channel number (1 based index) to read from.
error_value: Value that is returned in case the modbus read command fails.
Returns:
The read word value.
The read word value or provided error_value if read failed.
Raises:
Exception: If the word offset or count is out of range.
@ -174,6 +175,7 @@ class AnalogOutputTerminal(BusTerminal):
Args:
channel: The channel number (1 based index) to read from.
error_value: Value that is returned in case the modbus read command fails.
Returns:
The read word value or provided error_value if read failed.

0
src/pyhoff/py.typed Normal file
View File