Skip to content

Development and contributions

Tom Bombadil edited this page Jul 29, 2026 · 2 revisions

At first - thanks for supporting this project, much appreciated! To keep things clean and avoid chaos, please follow this simple branch workflow if you want help us developing the integration further.

Branch structure


    %%{init: {"themeCSS": ".edgeLabel, .edgeLabel p { font-size: 12px !important; line-height: 1.2 !important; background-color: transparent !important; } .labelBkg { background-color: transparent !important; } .edgeLabel rect { fill: transparent !important; opacity: 0 !important; }"}}%%

    flowchart TB

    main[":main<br/>Holds current release<br/><red>Locked - *NO* PR's!</red>"]
    develop[":develop<br/>Central mergepoint<br/>Fork from here"]

    main ~~~ develop
    develop -.->|New release version:<br/>FF merge only.| main

    develop_tom[":develop_tom<br/>working branch<br/>my changes go here"]
    develop_you[":your_branch_name<br/>create it from :develop<br/>your changes go here"]
    develop_someone[":develop_someone<br/>working branch<br/>changes go here"]
    develop_sometwo[":develop_sometwo<br/>working branch<br/>changes go here"]

    develop <-.->|FF merge| develop_tom
    develop <-.->|Your PR's| develop_you
    develop <-.->|PR's| develop_someone
    develop <-.->|PR's| develop_sometwo



    style main stroke:red,color:red
    style develop stroke:green,color:green
    style develop_you stroke:green,color:green 
Loading

develop_tom

  • personal maintainer working branch,
  • frequent local changes,
  • no automatic CI required on every push,
  • incomplete work may exist temporarily,
  • local checks are run manually when a coherent block is ready.

develop

  • shared integration and beta branch,
  • automatic CI runs on pushes and pull requests,
  • external pull requests must target this branch,
  • accepted maintainer work is integrated here,
  • should remain releasable after successful checks.

main

  • current release branch,
  • protected by repository rules,
  • only the repository's local develop branch may be the source of a pull request,
  • direct pushes and force pushes should be blocked,
  • releases are created from this branch.

Contributions: Step-by-step

  • Fork this repository first
    Please fork the repository and do your work in your own copy.

  • Create your own working branch
    Create your branch based on develop (select develop branch, then create your own working branch from it).

    git checkout develop
    git pull
    git checkout -b develop_yourname
    
  • Keep your branch up to date
    Before opening or updating a PR, please sync your branch with the latest develop.

  • Always create your pull request against develop
    All new features, fixes and experiments must go into develop first. The main branch is configured to auto-reject direct PR's.

  • Please enable editable pull requests
    When opening the PR, keep Allow edits by maintainers enabled. This makes it much easier to help with small fixes, cleanup or merge conflicts.

  • Keep your branch focused
    One topic per pull request is much easier to review than one huge mixed change.

  • Short description helps a lot
    Please briefly describe what you changed, why you changed it, and whether you already tested it.

And again: Thank you for contributing!!!

Development requirements

  • Python 3.12 or newer
  • a local source checkout of trovis-modbus
  • development dependencies for tests, Ruff, and package builds
  • optionally, a local checkout of modbus-connection for coordinated changes

Development setup with uv

uv sync
uv run pytest
uvx prek run --all-files

Development setup with a normal Python installation

Install the package in editable mode:

python -m pip install -e .
python -m pip install "pytest>=8" "pytest-asyncio>=0.24" ruff build

Run the test suite:

script/libtest.sh

Run all local quality and build checks:

script/libcheck.sh

The repository scripts resolve the repository root themselves and can be called from any working directory.

Test environment

The test suite uses the modbus-connection in-memory pytest backend. Normal unit tests do not require:

  • a physical TROVIS controller,
  • a serial adapter,
  • a network gateway,
  • an external Modbus server.

Current test areas include:

  • canonical catalog parity,
  • model-specific catalog and range selection,
  • per-model sensor capabilities,
  • hydronic system definitions and Rk roles,
  • sensor-variant resolution,
  • register and coil metadata,
  • grouped read behavior and block boundaries,
  • signed and scaled conversion,
  • invalid-value handling,
  • model and sensor probing,
  • operating-mode writes,
  • control-level behavior,
  • operational datapoints,
  • date and time decoding and encoding,
  • write ordering and preconditions,
  • enum options,
  • buffer-tank and solar availability,
  • command-line query behavior.

The development baseline should pass the complete suite with only explicitly documented expected skips.

Repository scripts

script/libtest.sh

The test script:

  • checks for the configured local modbus-connection source,
  • installs pytest dependencies when required,
  • adds both source trees to PYTHONPATH,
  • runs pytest from the repository root.

script/libcheck.sh

The complete local check performs:

  1. Ruff formatting check,
  2. Ruff lint,
  3. source and test compilation,
  4. the complete pytest suite,
  5. source distribution and wheel build.

Run this script before moving a completed development block to develop.

Local development checkout of modbus-connection

The project development environment may use a local checkout of modbus-connection.

The default source path used by script/libtest.sh is:

/config/dev/modbus-connection/src

Override it with:

MODBUS_CONNECTION_SRC=/another/path script/libtest.sh

A custom Python interpreter can be selected with:

PYTHON_BIN=/path/to/python script/libtest.sh

This local setup is useful for coordinated development. GitHub CI intentionally installs the package normally and verifies compatibility with the published modbus-connection dependency.

Recommended maintainer sequence

Before moving a completed block to develop:

script/libcheck.sh
git status
git add .
git commit -m "Describe the completed block"
git push

Then integrate develop_tom into develop using the repository's chosen linear-history workflow.

After integration:

  1. wait for the GitHub CI result on develop,
  2. correct failures on the working branch or a dedicated fix branch,
  3. keep develop as the tested shared baseline.

External contribution workflow

External contributions should follow this path:

  1. Fork the repository.
  2. Create a focused branch from the current develop branch.
  3. Make one coherent and testable change.
  4. Add or update tests.
  5. Run the local checks.
  6. Open a pull request against develop.
  7. Respond to review feedback without changing the pull request target to main.

Pull requests from forks directly to main are rejected by the branch guard.

A contribution should avoid mixing unrelated refactoring, new datapoints, behavior changes, and documentation cleanup in one large change unless they are inseparable parts of the same feature.

Contribution principles

When adding a datapoint or behavior:

  1. Prefer current official manufacturer documentation.
  2. Keep manufacturer references visible in the catalog.
  3. Add neutral metadata in the library.
  4. Preserve model, block, system-code, function, and parameter restrictions.
  5. Do not make a field writable without a verified write path.
  6. Add tests for conversion, metadata, availability, and behavior.
  7. Avoid duplicating presentation logic from one application.
  8. Prefer native typed values over raw display-oriented values.
  9. Prefer direct controller values over reconstructed estimates.
  10. Do not resolve ambiguous sensor roles from plausible measured values.
  11. Keep changes small enough to review, but complete enough to test as one coherent feature.

Continuous integration

The CI workflow runs on:

  • pushes to develop,
  • pushes to main,
  • pull requests targeting develop.

Its quality job performs:

checkout
setup Python
install package and test tools
ruff format --check
ruff check
compileall
pytest
build sdist and wheel

The CI runner installs the project normally and therefore verifies compatibility with the publicly available modbus-connection dependency rather than the maintainer's local source checkout.

Main-branch guard

A separate workflow runs on pull requests targeting main. It rejects the pull request unless:

  • the source branch is develop, and
  • the source branch belongs to the same repository.

The GitHub ruleset should make the relevant guard and branch-protection checks required before merging to main.

Release process

The intended release sequence is:

  1. Finish and test changes on develop_tom.
  2. Run script/libcheck.sh.
  3. Integrate the completed block into develop.
  4. Wait for the GitHub CI result.
  5. Update detailed wiki documentation where necessary.
  6. Prepare release notes for release-specific changes.
  7. Update the README only when the general project scope, supported controller list, or top-level positioning changes.
  8. Open a pull request from develop to main.
  9. Confirm the branch guard and repository protection checks.
  10. Merge the pull request.
  11. Create a GitHub release and tag.
  12. Let the publish workflow build and publish the package.

The source tree keeps the development version at 0.0.0. The publish workflow replaces it with the GitHub release tag for the package build and publishes the result through the configured PyPI environment.

Versioning

The project follows semantic versioning in principle:

  • patch release for compatible fixes,
  • minor release for compatible new public features,
  • major release for intentional breaking API changes.

Examples of compatible additions that normally fit a minor release include:

  • new typed datapoints,
  • new enums,
  • new metadata,
  • new optional subsystems,
  • new model or system definitions,
  • additional derived properties,
  • new public helper methods that do not break existing callers.

A rename or removal of a public attribute, a changed public value type, or an intentional behavior change that breaks callers requires explicit migration notes and may require a major release.

Documentation maintenance

Documentation is divided by purpose:

Location Purpose Normal update frequency
README.md Stable overview, data categories, supported controllers, wiki link Only when the general project description changes
Wiki Detailed architecture, behavior, examples, development, and limitations Whenever technical behavior or workflow changes
Release notes Changes in one specific published version Every release
Code comments and docstrings Local implementation intent and non-obvious rules With the corresponding code change

Do not copy a release changelog into the README. Do not leave detailed usage or contribution instructions only in the README when they belong in the wiki.

Clone this wiki locally