diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml index 4f03581..d990a98 100644 --- a/.github/workflows/build-and-publish.yml +++ b/.github/workflows/build-and-publish.yml @@ -8,6 +8,4 @@ on: jobs: build_and_deploy: uses: sensirion/.github/.github/workflows/driver.python.pypi_publish.yml@main - secrets: - PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }} - + secrets: inherit diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 2a29a62..d2d0f78 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -8,3 +8,5 @@ on: jobs: documentation: uses: sensirion/.github/.github/workflows/driver.python.documentation.yml@main + with: + use-project-requirements: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d2f7f2..ed13cfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.0.1] - 2025-8-28 + +### Added + +- Changed start_measurement example-value to enum ## [1.0.0] - 2025-8-25 ### Added - Inital release of SPS30 driver -[Unreleased]: https://github.com/Sensirion/python-uart-sps30/compare/1.0.0...HEAD +[Unreleased]: https://github.com/Sensirion/python-uart-sps30/compare/1.0.1...HEAD +[1.0.1]: https://github.com/Sensirion/python-uart-sps30/compare/1.0.0...1.0.1 [1.0.0]: https://github.com/Sensirion/python-uart-sps30/releases/tag/1.0.0 \ No newline at end of file diff --git a/LICENSE b/LICENSE index 2062766..8fe04ed 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2025, Sensirion AG +Copyright (c) 2026, Sensirion AG All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 18e0683..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -include CHANGELOG.rst diff --git a/ci/checkin_doc.sh b/ci/checkin_doc.sh deleted file mode 100644 index 1031751..0000000 --- a/ci/checkin_doc.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -# set shell settings (see https://sipb.mit.edu/doc/safe-shell/) -set -euv -o pipefail - -# clone the repo into a subfolder html, checkout the gh-pages into this folder and commit the freshly generated html -git clone "git@gitlab:${CI_PROJECT_PATH}.git" html -cd html -git checkout gh-pages -rm -f empty.txt -rm -f *.html -rm -f *.js -rm -rf _* -cd .. -# make sure to copy .nojekyll -cp -rf public/.[!.]* public/* html -cd html -git add . - -if git diff-index --quiet HEAD -- -then - exit 0 -fi - -git commit -m"Automatic doc update: ${CI_COMMIT_SHORT_SHA}" -git push \ No newline at end of file diff --git a/ci/set_git_config.sh b/ci/set_git_config.sh deleted file mode 100644 index 860c6aa..0000000 --- a/ci/set_git_config.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -# set shell settings (see https://sipb.mit.edu/doc/safe-shell/) -set -eufv -o pipefail - -# install ssh private key (set as CI variable in GitLab project settings) -mkdir -p ~/.ssh -echo "$SSH_DEPLOY_KEY" > ~/.ssh/id_rsa -chmod 400 ~/.ssh/id_rsa - -# change remote URL to SSH to allow pushing with SSH -git remote set-url --push origin "git@gitlab:${CI_PROJECT_PATH}.git" - -# set git author -git config --global user.name "GitLab-CI" -git config --global user.email "<>" diff --git a/docs/build-documentation.rst b/docs/build-documentation.rst index 8653cf1..a188010 100644 --- a/docs/build-documentation.rst +++ b/docs/build-documentation.rst @@ -5,10 +5,5 @@ The documentation is built with `Sphinx `_: .. code-block:: bash - python setup.py install # Install package - pip install -r docs/requirements.txt # Install requirements - cd docs # Change to docs folder - make html # Build documentation - - -The generated documentation is located in docs/_build/html. \ No newline at end of file + python -m pip install .[docs] # Install doc requirements + sphinx-build -b html docs docs/_build/html # Build documentation diff --git a/docs/conf.py b/docs/conf.py index 4d5fbd3..e4c9bf4 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -4,11 +4,14 @@ # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html + import os import sys from datetime import datetime -import pkg_resources +import importlib.metadata as metadata +import sphinx_tabs.tabs + import sphinx.ext.autodoc import sensirion_uart_sps30 @@ -17,16 +20,16 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) # -- Project information ----------------------------------------------------- -distribution = pkg_resources.get_distribution('sensirion_uart_sps30') +distribution = metadata.distribution("sensirion_uart_sps30") -project = u'sensirion_uart_sps30' +project = distribution.name copyright = u'{} Sensirion AG, Switzerland'.format(datetime.now().year) author = 'Sensirion AG' # The short X.Y version -version = sensirion_uart_sps30.__version__ +version = distribution.version # The full version, including alpha/beta/rc tags -release = sensirion_uart_sps30.__version__ +release = distribution.version # -- General configuration --------------------------------------------------- @@ -36,6 +39,7 @@ extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.viewcode', + 'sphinx_tabs.tabs', 'sphinx.ext.inheritance_diagram', 'sphinx.ext.githubpages', 'sphinx.ext.intersphinx', diff --git a/docs/dev-setup.rst b/docs/dev-setup.rst new file mode 100644 index 0000000..3e2a3e5 --- /dev/null +++ b/docs/dev-setup.rst @@ -0,0 +1,45 @@ +To prepare your development environment, check out the repository, +create a Python virtual environment, and activate it. +Then install the driver in editable mode using `pip`. + +Check out the Git repository to your local machine: + +.. code-block:: console + + git clone + cd + +Create a Python virtual environment: + +.. code-block:: console + + python -m venv .venv + +Activate the virtual environment: + +.. tabs:: + + .. group-tab:: Bash + + .. code-block:: console + + source .venv/bin/activate + + .. group-tab:: PowerShell + + .. code-block:: console + + .venv\Scripts\Activate.ps1 + + .. group-tab:: Command Prompt + + .. code-block:: console + + .venv\Scripts\activate.bat + +Install the driver in editable mode together with the development dependencies: + +.. code-block:: console + + python -m pip install -e . + diff --git a/docs/development.rst b/docs/development.rst index d169708..dddb742 100644 --- a/docs/development.rst +++ b/docs/development.rst @@ -1,6 +1,10 @@ Development =========== +For development, you first need to prepare your setup. + +.. include:: dev-setup.rst + .. toctree:: run-tests diff --git a/docs/driver-installation.rst b/docs/driver-installation.rst new file mode 100644 index 0000000..7222290 --- /dev/null +++ b/docs/driver-installation.rst @@ -0,0 +1,37 @@ +The driver installation consists of creating a Python virtual environment, +activating it, and installing the driver using `pip`. + +Create a Python virtual environment: + +.. code-block:: console + + python -m venv .venv + +Activate the virtual environment: + +.. tabs:: + + .. group-tab:: Bash + + + .. code-block:: console + + source .venv/bin/activate + + .. group-tab:: PowerShell + + .. code-block:: console + + .venv\Scripts\Activate.ps1 + + .. group-tab:: Command Prompt + + .. code-block:: console + + .venv\Scripts\activate.bat + +Install the driver: + +.. code-block:: console + + python -m pip install sensirion_uart_sps30 diff --git a/docs/execute-measurements.rst b/docs/execute-measurements.rst index fd7b415..62d3e00 100644 --- a/docs/execute-measurements.rst +++ b/docs/execute-measurements.rst @@ -1,11 +1,13 @@ -Execute measurements -==================== +Install the SPS30 Driver +------------------------ -The following steps show how to use this driver to execute a simple measurement on a Windows system. +.. include:: driver-installation.rst -1. Install the SPS30 sensor driver and all required packages as described in :ref:`Installation`. -2. Connect the SPS30 sensor to your system with the serial USB cable. -3. Run the example script from the root of the repository. +Run Usage-Example +----------------- + +1. Connect the SPS30 sensor to your system with the serial USB cable. +2. Run the example script from the root of the repository. By default the script assumes the sensor is connected to COM1 serial port. If this is different on your system, pass the port in use with the :code:`--serial-port` parameter as outlined below. @@ -15,7 +17,7 @@ The following steps show how to use this driver to execute a simple measurement python examples/example_usage_uart_sps30.py --serial-port Example script --------------- +~~~~~~~~~~~~~~ .. literalinclude:: ../examples/example_usage_uart_sps30.py :language: python \ No newline at end of file diff --git a/docs/installation.rst b/docs/installation.rst index 141bdd3..dcec370 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -3,10 +3,7 @@ Installation ============ -The package can be installed with pip: +It is assumed that you have a working Python installation on your system. +If not, please install Python first including `pip `_. -.. sourcecode:: bash - - pip install sensirion_uart_sps30 - -Recommended usage is within a virtualenv. +.. include:: driver-installation.rst \ No newline at end of file diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 5dce52d..c937bef 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -1,6 +1,10 @@ Quick Start =========== +Learn how to quickly get started with the SPS30 and perform your first measurements using +the provided usage examples. + + .. toctree:: execute-measurements diff --git a/docs/requirements.txt b/docs/requirements.txt index 5d15a64..bd93639 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,5 @@ click==8.0.4 jinja2~=3.1.0 sphinx~=7.1.0 +sphinx-tabs~=3.5.0 sphinx_rtd_theme~=1.3.0 diff --git a/examples/example_usage_uart_sps30.py b/examples/example_usage_uart_sps30.py index 995d557..fe23ca7 100644 --- a/examples/example_usage_uart_sps30.py +++ b/examples/example_usage_uart_sps30.py @@ -1,13 +1,13 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# (c) Copyright 2025 Sensirion AG, Switzerland +# (c) Copyright 2026 Sensirion AG, Switzerland # # THIS FILE IS AUTOMATICALLY GENERATED! # -# Generator: sensirion-driver-generator 1.3.3 +# Generator: sensirion-driver-generator 1.9.3 # Product: sps30 -# Model-Version: 1.0.1 +# Model-Version: 1.0.2 # import time @@ -35,7 +35,7 @@ product_type = sensor.read_product_type() print(f"product_type: {product_type}; " ) - sensor.start_measurement(OutputFormat(261)) + sensor.start_measurement(OutputFormat.OUTPUT_FORMAT_UINT16) for i in range(50): try: time.sleep(1.0) diff --git a/metadata.yml b/metadata.yml index c2ede07..ad00590 100644 --- a/metadata.yml +++ b/metadata.yml @@ -1,7 +1,7 @@ -# driver generation metadata -generator_version: 1.3.3 -model_version: 1.0.1 -dg_status: released -is_manually_modified: false -first_generated: '2025-08-15 14:57' -last_generated: '2025-08-25 12:22' +# driver generation metadata +generator_version: 1.9.3 +model_version: 1.0.2 +dg_status: released +is_manually_modified: false +first_generated: '2025-08-15 14:57' +last_generated: '2026-10-05 08:44' diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..0280dc7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,68 @@ +[build-system] +requires = ["hatchling >= 1.26", "wheel >= 0.45.0"] +build-backend = "hatchling.build" + +[project] +name = "sensirion_uart_sps30" +description = "I2C driver for the Sensirion SPS30 sensor family" + +readme = "README.md" +version = "1.0.1" + +requires-python = ">=3.8.4,<4.0" + +authors = [ + { name = "Sensirion", email = "info@sensirion.com" }, +] + +license = "BSD-3-Clause" +license-files = ["LICENSE"] + +keywords = [ + "Sensirion SPS30", + "SHDLC", + "SPS30", + ] + +classifiers = [ + "Intended Audience :: Developers", + "Topic :: System :: Hardware :: Hardware Drivers", + "Topic :: Software Development :: Libraries :: Python Modules", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", +] + +dependencies = [ + "sensirion-driver-adapters>=2.3.0,<3.0", + "sensirion-driver-support-types>=1.2.0,<2.0", + "sensirion-shdlc-driver", + ] + +[project.optional-dependencies] + +docs=[ + "jinja2~=3.1.6", + "sphinx-rtd-theme==3.0.2", + "sphinx>=7.0,<8.0;python_version < '3.11'", + "sphinx==8.2.3;python_version >= '3.11'", + "lazy-object-proxy ~=1.7.1", + "sphinx-tabs~=3.5.0", + "sphinx-autoapi~=3.0.0", +] + +test= [ + "flake8>=7.1.0", + "mock~=5.2.0", + "pytest>=8.3.5", + "pytest-cov>=5.0.0", + "mypy~=1.13.0", + "setuptools>=73.2.0" +] + +[project.urls] +Changelog = "https://github.com/Sensirion/python-uart-sps30/blob/master/CHANGELOG.md" +Repository = "https://github.com/Sensirion/python-uart-sps30" +Documentation = "https://sensirion.github.io/python-uart-sps30" + diff --git a/sensirion_uart_sps30/commands.py b/sensirion_uart_sps30/commands.py index d0e000b..e0e5326 100644 --- a/sensirion_uart_sps30/commands.py +++ b/sensirion_uart_sps30/commands.py @@ -1,13 +1,13 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# (c) Copyright 2025 Sensirion AG, Switzerland +# (c) Copyright 2026 Sensirion AG, Switzerland # # THIS FILE IS AUTOMATICALLY GENERATED! # -# Generator: sensirion-driver-generator 1.3.3 +# Generator: sensirion-driver-generator 1.9.3 # Product: sps30 -# Model-Version: 1.0.1 +# Model-Version: 1.0.2 # """ The transfer classes specify the data that is transferred between host and sensor. The generated transfer classes @@ -97,7 +97,7 @@ def pack(self): class WakeUpCommunication(Transfer): - """""" + """Wake up communication interface""" CMD_ID = 0xff diff --git a/sensirion_uart_sps30/device.py b/sensirion_uart_sps30/device.py index 98fca1a..42855fd 100644 --- a/sensirion_uart_sps30/device.py +++ b/sensirion_uart_sps30/device.py @@ -1,13 +1,13 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# (c) Copyright 2025 Sensirion AG, Switzerland +# (c) Copyright 2026 Sensirion AG, Switzerland # # THIS FILE IS AUTOMATICALLY GENERATED! # -# Generator: sensirion-driver-generator 1.3.3 +# Generator: sensirion-driver-generator 1.9.3 # Product: sps30 -# Model-Version: 1.0.1 +# Model-Version: 1.0.2 # """ The class Sps30DeviceBase implements the low level interface of the sensor. @@ -48,7 +48,7 @@ def start_measurement(self, measurement_output_format): :Example: .. code-block:: python - sensor.start_measurement(OutputFormat(261)) + sensor.start_measurement(OutputFormat.OUTPUT_FORMAT_UINT16) """ transfer = StartMeasurement(measurement_output_format) @@ -128,7 +128,7 @@ def sleep(self): return execute_transfer(self._channel, transfer) def wake_up_communication(self): - """""" + """Wake up communication interface""" transfer = WakeUpCommunication() return execute_transfer(self._channel, transfer) diff --git a/sensirion_uart_sps30/result_types.py b/sensirion_uart_sps30/result_types.py index 2d62f4b..b48aef6 100644 --- a/sensirion_uart_sps30/result_types.py +++ b/sensirion_uart_sps30/result_types.py @@ -1,13 +1,13 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# (c) Copyright 2025 Sensirion AG, Switzerland +# (c) Copyright 2026 Sensirion AG, Switzerland # # THIS FILE IS AUTOMATICALLY GENERATED! # -# Generator: sensirion-driver-generator 1.3.3 +# Generator: sensirion-driver-generator 1.9.3 # Product: sps30 -# Model-Version: 1.0.1 +# Model-Version: 1.0.2 # """ The signal classes specify transformations of the raw sensor signals into a meaningful units. @@ -15,3 +15,4 @@ """ + diff --git a/sensirion_uart_sps30/version.py b/sensirion_uart_sps30/version.py index e5ed854..d127651 100644 --- a/sensirion_uart_sps30/version.py +++ b/sensirion_uart_sps30/version.py @@ -1,5 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function +import importlib.metadata as metadata +from typing import Final -version = "1.0.0" +version: Final[str] = metadata.version("sensirion_uart_sps30") diff --git a/setup.py b/setup.py index 1ee3db9..bfae448 100644 --- a/setup.py +++ b/setup.py @@ -1,70 +1,5 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +from setuptools import setup -import os -import re - -from setuptools import setup, find_packages - -# Python versions this package is compatible with -python_requires = '>=3.6, <4' - -# Packages that this package imports. List everything apart from standard lib packages. -install_requires = [ - 'sensirion-shdlc-driver~=0.1.5', - 'sensirion-driver-adapters>=2.3.0,<3.0', - 'sensirion-driver-support-types>=1.2.0,<2.0', -] - -# Packages required for tests and docs -extras_require = { - 'test': [ - 'flake8~=3.7.8', - 'pytest~=6.2.5', - 'pytest-cov~=3.0.0', - ] -} - -# Read version number from version.py -version_line = open("sensirion_uart_sps30/version.py", "rt").read() -result = re.search(r"^version = ['\"]([^'\"]*)['\"]", version_line, re.M) -if result: - version_string = result.group(1) -else: - raise RuntimeError("Unable to find version string") - -# Use README.rst and CHANGELOG.md as package description -root_path = os.path.dirname(__file__) -long_description = open(os.path.join(root_path, 'README.md')).read() - -setup( - name='sensirion_uart_sps30', - version=version_string, - author='Sensirion', - author_email='info@sensirion.com', - description='SHDLC driver for the Sensirion SPS30 sensor family', - license='BSD', - keywords="""Sensirion SPS30 - SHDLC - UART - SPS30""", - project_urls={ - "Documentation": "https://sensirion.github.io/python-uart-sps30", - "Repository": "https://github.com/Sensirion/python-uart-sps30", - "Changelog": "https://github.com/Sensirion/python-uart-sps30/blob/master/CHANGELOG.md", - }, - packages=find_packages(exclude=['tests', 'tests.*']), - long_description=long_description, - long_description_content_type='text/markdown', - python_requires=python_requires, - install_requires=install_requires, - extras_require=extras_require, - classifiers=[ - 'Intended Audience :: Developers', - 'License :: OSI Approved :: BSD License', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.11', - 'Topic :: Software Development :: Libraries :: Python Modules' - ] -) +setup() \ No newline at end of file diff --git a/tests/test_sps30.py b/tests/test_sps30.py index 7a97fde..fdc7495 100644 --- a/tests/test_sps30.py +++ b/tests/test_sps30.py @@ -1,13 +1,13 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # -# (c) Copyright 2025 Sensirion AG, Switzerland +# (c) Copyright 2026 Sensirion AG, Switzerland # # THIS FILE IS AUTOMATICALLY GENERATED! # -# Generator: sensirion-driver-generator 1.3.3 +# Generator: sensirion-driver-generator 1.9.3 # Product: sps30 -# Model-Version: 1.0.1 +# Model-Version: 1.0.2 # import pytest @@ -26,7 +26,7 @@ def sensor(channel_provider): def test_start_measurement1(sensor): - sensor.start_measurement(OutputFormat(261)) + sensor.start_measurement(OutputFormat.OUTPUT_FORMAT_UINT16) (mc_1p0, mc_2p5, mc_4p0, mc_10p0, nc_0p5, nc_1p0, nc_2p5, nc_4p0, nc_10p0, typical_particle_size ) = sensor.read_measurement_values_float() print(f"mc_1p0: {mc_1p0}; "