From 6eda373d58677be0935bb518695167738e3521c5 Mon Sep 17 00:00:00 2001 From: Driver Generator 2 Date: Fri, 5 Jun 2026 09:32:30 +0000 Subject: [PATCH] Generate SEN65 driver from SEN65 model version 1.4.0 --- .github/workflows/build-and-publish.yml | 4 +- .github/workflows/build-docs.yml | 6 +- .../workflows/gh_workflow_metadata_update.yml | 11 + .github/workflows/test.yml | 4 - CHANGELOG.md | 16 + LICENSE | 2 +- README.md | 8 +- ci/checkin_doc.sh | 26 - ci/set_git_config.sh | 16 - docs/conf.py | 11 +- docs/execute-measurements.rst | 2 +- examples/example_usage_linux_sen65.py | 6 +- examples/example_usage_sensorbridge_sen65.py | 6 +- images/product-image-sen6x.png | Bin 0 -> 87811 bytes images/product-pinout-sen6x.png | Bin 0 -> 73305 bytes metadata.yml | 6 +- pyproject.toml | 68 ++ sensirion_i2c_sen65/commands.py | 449 ++++++------ sensirion_i2c_sen65/device.py | 661 +++++++++--------- sensirion_i2c_sen65/response_provider.py | 3 +- sensirion_i2c_sen65/result_types.py | 160 +---- sensirion_i2c_sen65/version.py | 4 +- setup.py | 69 +- tests/test_sen65.py | 59 +- 24 files changed, 759 insertions(+), 838 deletions(-) create mode 100644 .github/workflows/gh_workflow_metadata_update.yml delete mode 100644 ci/checkin_doc.sh delete mode 100644 ci/set_git_config.sh create mode 100644 images/product-image-sen6x.png create mode 100644 images/product-pinout-sen6x.png create mode 100644 pyproject.toml 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 d200c56..d2d0f78 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -2,9 +2,11 @@ name: Publish Documentation on: workflow_dispatch: push: - tags: - - "[0-9]+.[0-9]+.[0-9]+" + branches: + - main jobs: documentation: uses: sensirion/.github/.github/workflows/driver.python.documentation.yml@main + with: + use-project-requirements: true diff --git a/.github/workflows/gh_workflow_metadata_update.yml b/.github/workflows/gh_workflow_metadata_update.yml new file mode 100644 index 0000000..7dd70ed --- /dev/null +++ b/.github/workflows/gh_workflow_metadata_update.yml @@ -0,0 +1,11 @@ +name: Driver Index Metadata Update + +on: + push: + branches: + - main + +jobs: + driver-index-metadata-update: + uses: sensirion/.github/.github/workflows/driver.common.di_metadata_update.yml@main + secrets: inherit diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c15f72f..b1cebfa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,9 +8,5 @@ on: - main jobs: - dg-metadata-validation: - if: github.event_name == 'push' && github.ref != 'refs/head/main' - uses: sensirion/.github/.github/workflows/driver.generated.metadata_check.yml@main - test: uses: sensirion/.github/.github/workflows/driver.python.test.yml@main diff --git a/CHANGELOG.md b/CHANGELOG.md index 9670de3..aa28b7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.4.0] - 2026-6-5 + +### Added + +- Added get_product_type command. +## [1.0.1] - 2026-2-13 + +### Fixed + +- Version mismatch in library.properties +## [1.0.0] - 2025-3-13 + ### Added - Support for all I2C commands for the SEN65 as described in the datasheet. +[Unreleased]: https://github.com/Sensirion/python-i2c-sen65/compare/1.4.0...HEAD +[1.4.0]: https://github.com/Sensirion/python-i2c-sen65/compare/1.0.1...1.4.0 +[1.0.1]: https://github.com/Sensirion/python-i2c-sen65/compare/1.0.0...1.0.1 +[1.0.0]: https://github.com/Sensirion/python-i2c-sen65/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/README.md b/README.md index 7efac04..cbc1445 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This repository contains the Python driver to communicate with a Sensirion SEN65 sensor over I2C. -SEN65 picture @@ -10,18 +10,18 @@ Click [here](https://sensirion.com/sen6x-air-quality-sensor-platform) to learn m -The default I²C address of [SEN65](https://www.sensirion.com/products/catalog/SEN65) is **0x6B**. +The default I²C address of [SEN65](https://www.sensirion.com/products/catalog/SEN65) is **0x6b**. ## Connect the sensor -You can connect your sensor over a [SEK-SensorBridge](https://developer.sensirion.com/sensirion-products/sek-sensorbridge/). +You can connect your sensor over a [SEK-SensorBridge](https://developer.sensirion.com/product-support/sek-sensorbridge/). For special setups you find the sensor pinout in the section below.
Sensor pinout

-sensor wiring picture | *Pin* | *Cable Color* | *Name* | *Description* | *Comments* | 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/conf.py b/docs/conf.py index a154d77..881091e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -4,11 +4,12 @@ # 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.ext.autodoc import sensirion_i2c_sen65 @@ -17,16 +18,16 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) # -- Project information ----------------------------------------------------- -distribution = pkg_resources.get_distribution('sensirion_i2c_sen65') +distribution = metadata.distribution("sensirion_i2c_sen65") -project = u'sensirion_i2c_sen65' +project = distribution.name copyright = u'{} Sensirion AG, Switzerland'.format(datetime.now().year) author = 'Sensirion AG' # The short X.Y version -version = sensirion_i2c_sen65.__version__ +version = distribution.version # The full version, including alpha/beta/rc tags -release = sensirion_i2c_sen65.__version__ +release = distribution.version # -- General configuration --------------------------------------------------- diff --git a/docs/execute-measurements.rst b/docs/execute-measurements.rst index deb86d1..e9b665f 100644 --- a/docs/execute-measurements.rst +++ b/docs/execute-measurements.rst @@ -26,7 +26,7 @@ execute a simple measurement. python examples/example_usage_sensorbridge_sen65.py --serial-port -.. _Sensirion SEK-SensorBridge: https://developer.sensirion.com/sensirion-products/sek-sensorbridge/ +.. _Sensirion SEK-SensorBridge: https://developer.sensirion.com/product-support/sek-sensorbridge/ .. _SensorBridge FTDI Driver Installation: https://sensirion.github.io/python-shdlc-sensorbridge/sensor-bridge-installation.html Example script diff --git a/examples/example_usage_linux_sen65.py b/examples/example_usage_linux_sen65.py index ece4e5c..a4dfb2e 100644 --- a/examples/example_usage_linux_sen65.py +++ b/examples/example_usage_linux_sen65.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.1.2 +# Generator: sensirion-driver-generator 1.7.0 # Product: sen65 -# Model-Version: 1.3.0 +# Model-Version: 1.4.0 # import argparse diff --git a/examples/example_usage_sensorbridge_sen65.py b/examples/example_usage_sensorbridge_sen65.py index 9e72978..dade178 100644 --- a/examples/example_usage_sensorbridge_sen65.py +++ b/examples/example_usage_sensorbridge_sen65.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.1.2 +# Generator: sensirion-driver-generator 1.7.0 # Product: sen65 -# Model-Version: 1.3.0 +# Model-Version: 1.4.0 # import argparse diff --git a/images/product-image-sen6x.png b/images/product-image-sen6x.png new file mode 100644 index 0000000000000000000000000000000000000000..b97bde33278346b00210fe07a6b08a4470679146 GIT binary patch literal 87811 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%0AZx3W=CGY9?cbwMl5N%RH4Oa1#bQf{>M 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 EA0D2TU;qFB literal 0 HcmV?d00001 diff --git a/images/product-pinout-sen6x.png b/images/product-pinout-sen6x.png new file mode 100644 index 0000000000000000000000000000000000000000..a940971e5664525b62770efd29d8f247f04e790b GIT binary patch literal 73305 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 literal 0 HcmV?d00001 diff --git a/metadata.yml b/metadata.yml index f5643fb..5e670ff 100644 --- a/metadata.yml +++ b/metadata.yml @@ -1,7 +1,7 @@ # driver generation metadata -generator_version: 1.1.2 -model_version: 1.3.0 +generator_version: 1.7.0 +model_version: 1.4.0 dg_status: released is_manually_modified: false first_generated: '2025-02-17 07:46' -last_generated: '2025-03-13 10:28' +last_generated: '2026-06-05 09:32' diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..2f89f98 --- /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_i2c_sen65" +description = "I2C driver for the Sensirion SEN65 sensor family" + +readme = "README.md" +version = "1.4.0" + +requires-python = ">=3.8.4,<4.0" + +authors = [ + { name = "Sensirion", email = "info@sensirion.com" }, +] + +license = "BSD-3-Clause" +license-files = ["LICENSE"] + +keywords = [ + "Sensirion SEN65", + "I2C", + "SEN65", + ] + +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-i2c-driver>=1.0,<2.0", + "sensirion-shdlc-sensorbridge>=0.1.0,<2.0" + ] + +[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-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-i2c-sen65/blob/master/CHANGELOG.md" +Repository = "https://github.com/Sensirion/python-i2c-sen65" +Documentation = "https://sensirion.github.io/python-i2c-sen65" + diff --git a/sensirion_i2c_sen65/commands.py b/sensirion_i2c_sen65/commands.py index 3c40b10..91b2b7f 100644 --- a/sensirion_i2c_sen65/commands.py +++ b/sensirion_i2c_sen65/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.1.2 +# Generator: sensirion-driver-generator 1.7.0 # Product: sen65 -# Model-Version: 1.3.0 +# Model-Version: 1.4.0 # """ The transfer classes specify the data that is transferred between host and sensor. The generated transfer classes @@ -26,241 +26,228 @@ class DeviceStatus(BitfieldContainer): rht_error = BitField(offset=6, width=1) gas_error = BitField(offset=7, width=1) reserved3 = BitField(offset=8, width=1) - reserved4 = BitField(offset=9, width=1) - reserved5 = BitField(offset=10, width=1) + co2_2_error = BitField(offset=9, width=1) + hcho_error = BitField(offset=10, width=1) pm_error = BitField(offset=11, width=1) - reserved6 = BitField(offset=12, width=1) - reserved7 = BitField(offset=13, width=8) + co2_1_error = BitField(offset=12, width=1) + reserved4 = BitField(offset=13, width=8) fan_speed_warning = BitField(offset=21, width=1) + reserved5 = BitField(offset=22, width=10) -class StartContinuousMeasurement(Transfer): - """ - Starts a continuous measurement. - After starting the measurement, it takes some time (~1.1s) until the - first measurement results are available. You could poll with the command - "Get Data Ready" to check when the results are ready to read. - This command is only available in idle mode. If the device is already - in any measure mode, this command has no effect. - """ +class GetVocAlgorithmTuningParameters(Transfer): + """Gets the parameters to customize the VOC algorithm.""" - CMD_ID = 0x21 + CMD_ID = 0x60d0 def pack(self): return self.tx_data.pack([]) - tx = TxData(CMD_ID, '>H', device_busy_delay=0.05, slave_address=None, ignore_ack=False) + tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) + rx = RxData('>hhhhhh') -class StopMeasurement(Transfer): +class SetVocAlgorithmTuningParameters(Transfer): """ - Stops the measurement and returns to idle mode. After sending this - command, wait at least 1000 ms before starting a new measurement. - If the device is already in idle mode, this command has no effect. + Sets the parameters to customize the VOC algorithm. + This configuration is volatile, i.e. the parameters will be + reverted to their default values after a device reset. """ - CMD_ID = 0x104 + CMD_ID = 0x60d0 + + def __init__(self, index_offset, learning_time_offset_hours, learning_time_gain_hours, gating_max_duration_minutes, + std_initial, gain_factor): + self._index_offset = index_offset + self._learning_time_offset_hours = learning_time_offset_hours + self._learning_time_gain_hours = learning_time_gain_hours + self._gating_max_duration_minutes = gating_max_duration_minutes + self._std_initial = std_initial + self._gain_factor = gain_factor def pack(self): - return self.tx_data.pack([]) + return self.tx_data.pack([self._index_offset, self._learning_time_offset_hours, self._learning_time_gain_hours, + self._gating_max_duration_minutes, self._std_initial, self._gain_factor]) - tx = TxData(CMD_ID, '>H', device_busy_delay=1.0, slave_address=None, ignore_ack=False) + tx = TxData(CMD_ID, '>Hhhhhhh', device_busy_delay=0.02, slave_address=None, ignore_ack=False) -class GetDataReady(Transfer): +class GetVocAlgorithmState(Transfer): """ - This command can be used to check if new measurement results are ready to read. The data ready flag - is automatically reset after reading the measurement values. + Gets the current VOC algorithm state. + Allows to backup and restore the VOC algorithm state to resume operation after a power cycle or + device reset, skipping initial learning phase. By default, the VOC Engine is reset and the algorithm + state is retained if a measurement is stopped and started again. If the VOC algorithm + state shall be reset, a device reset or a power cycle can be executed. """ - CMD_ID = 0x202 + CMD_ID = 0x6181 def pack(self): return self.tx_data.pack([]) tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) - rx = RxData('>B?') + rx = RxData('>8B') -class ReadMeasuredValuesAsIntegers(Transfer): +class SetVocAlgorithmState(Transfer): """ - Returns the measured values. - The command "Get Data Ready" can be used to check if new - data is available since the last read operation. If no new data is - available, the previous values will be returned again. If no data - is available at all (e.g. measurement not running for at least one - second), all values will be at their upper limit (0xFFFF for uint16, - 0x7FFF for int16). + Sets the VOC algorithm state previously received with "Get VOC Algorithm State" command. + Allows restoration of the VOC algorithm state to resume operation after a power cycle or device + reset, skipping initial learning phase. By default, the VOC Engine is reset, and the algorithm state is retained if + a measurement is stopped and started again. If the VOC algorithm state shall be reset, a device reset, or a + power cycle can be executed. """ - CMD_ID = 0x446 + CMD_ID = 0x6181 + + def __init__(self, state): + self._state = state def pack(self): - return self.tx_data.pack([]) + return self.tx_data.pack([self._state]) - tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) - rx = RxData('>HHHHhhhh') + tx = TxData(CMD_ID, '>H8B') -class ReadNumberConcentrationValuesAsIntegers(Transfer): - """ - Returns the measured number concentration values. - The command "Get Data Ready" can be used to check if new - data is available since the last read operation. If no new data is - available, the previous values will be returned again. If no data - is available at all (e.g. measurement not running for at least one - second), all values will be at their upper limit (0xFFFF for uint16). - """ +class GetNoxAlgorithmTuningParameters(Transfer): + """Gets the parameters to customize the NOx algorithm.""" - CMD_ID = 0x316 + CMD_ID = 0x60e1 def pack(self): return self.tx_data.pack([]) tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) - rx = RxData('>HHHHH') + rx = RxData('>hhhhhh') -class ReadMeasuredRawValues(Transfer): +class SetNoxAlgorithmTuningParameters(Transfer): """ - Returns the measured raw values. - The command "Get Data Ready" can be used to check if new - data is available since the last read operation. If no new data is - available, the previous values will be returned again. If no data - is available at all (e.g. measurement not running for at least one - second), all values will be at their upper limit (0xFFFF for uint16, - 0x7FFF for int16). + Sets the parameters to customize the NOx algorithm. + This configuration is volatile, i.e. the parameters will be + reverted to their default values after a device reset. """ - CMD_ID = 0x455 + CMD_ID = 0x60e1 + + def __init__(self, index_offset, learning_time_offset_hours, learning_time_gain_hours, gating_max_duration_minutes, + std_initial, gain_factor): + self._index_offset = index_offset + self._learning_time_offset_hours = learning_time_offset_hours + self._learning_time_gain_hours = learning_time_gain_hours + self._gating_max_duration_minutes = gating_max_duration_minutes + self._std_initial = std_initial + self._gain_factor = gain_factor def pack(self): - return self.tx_data.pack([]) + return self.tx_data.pack([self._index_offset, self._learning_time_offset_hours, self._learning_time_gain_hours, + self._gating_max_duration_minutes, self._std_initial, self._gain_factor]) - tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) - rx = RxData('>hhHH') + tx = TxData(CMD_ID, '>Hhhhhhh', device_busy_delay=0.02, slave_address=None, ignore_ack=False) -class StartFanCleaning(Transfer): +class StartContinuousMeasurement(Transfer): """ - This command triggers fan cleaning. The fan is set to the maximum - speed for 10 seconds and then automatically stopped. Wait at least 10s - after this command before starting a measurement. + Starts a continuous measurement. + After starting the measurement, it takes some time (~1.1s) until the + first measurement results are available. You could poll with the command + "Get Data Ready" to check when the results are ready to read. + This command is only available in idle mode. If the device is already + in any measure mode, this command has no effect. """ - CMD_ID = 0x5607 + CMD_ID = 0x21 def pack(self): return self.tx_data.pack([]) - tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) + tx = TxData(CMD_ID, '>H', device_busy_delay=0.05, slave_address=None, ignore_ack=False) -class SetTemperatureOffsetParameters(Transfer): +class StopMeasurement(Transfer): """ - This command allows to compensate temperature effects of the - design-in at customer side by applying custom temperature offsets - to the ambient temperature. The compensated ambient temperature is - calculated as follows: - T_Ambient_Compensated = T_Ambient + (slope * T_Ambient) + offset - Where slope and offset are the values set with this command, - smoothed with the specified time constant. - All temperatures (T_Ambient_Compensated, T_Ambient and offset) - are represented in °C. - There are 5 temperature offset slots available that all contribute - additively to T_Ambient_Compensated. The default values for - the temperature offset parameters are all zero, meaning that - T_Ambient_Compensated is equal to T_Ambient by default. - The parameters can be changed in any state of the device, i.e. both in - idle mode and in measure mode. + Stops the measurement and returns to idle mode. After sending this + command, wait at least 1000 ms before starting a new measurement. + If the device is already in idle mode, this command has no effect. """ - CMD_ID = 0x60b2 - - def __init__(self, offset, slope, time_constant, slot): - self._offset = offset - self._slope = slope - self._time_constant = time_constant - self._slot = slot + CMD_ID = 0x104 def pack(self): - return self.tx_data.pack([self._offset, self._slope, self._time_constant, self._slot]) + return self.tx_data.pack([]) - tx = TxData(CMD_ID, '>HhhHH', device_busy_delay=0.02, slave_address=None, ignore_ack=False) + tx = TxData(CMD_ID, '>H', device_busy_delay=1.4, slave_address=None, ignore_ack=False) -class SetVocAlgorithmTuningParameters(Transfer): +class GetDataReady(Transfer): """ - Sets the parameters to customize the VOC algorithm. - This configuration is volatile, i.e. the parameters will be - reverted to their default values after a device reset. + This command can be used to check if new measurement results are ready to read. The data ready flag + is automatically reset after reading the measurement values. """ - CMD_ID = 0x60d0 - - def __init__(self, index_offset, learning_time_offset_hours, learning_time_gain_hours, gating_max_duration_minutes, - std_initial, gain_factor): - self._index_offset = index_offset - self._learning_time_offset_hours = learning_time_offset_hours - self._learning_time_gain_hours = learning_time_gain_hours - self._gating_max_duration_minutes = gating_max_duration_minutes - self._std_initial = std_initial - self._gain_factor = gain_factor + CMD_ID = 0x202 def pack(self): - return self.tx_data.pack([self._index_offset, self._learning_time_offset_hours, self._learning_time_gain_hours, - self._gating_max_duration_minutes, self._std_initial, self._gain_factor]) + return self.tx_data.pack([]) - tx = TxData(CMD_ID, '>Hhhhhhh', device_busy_delay=0.02, slave_address=None, ignore_ack=False) + tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) + rx = RxData('>B?') -class GetVocAlgorithmTuningParameters(Transfer): - """Gets the parameters to customize the VOC algorithm.""" +class ReadNumberConcentrationValuesAsIntegers(Transfer): + """ + Returns the measured number concentration values. + The command 0x0202 "Get Data Ready" can be used to check if new + data is available since the last read operation. If no new data is + available, the previous values will be returned again. If no data + is available at all (e.g. measurement not running for at least one + second), all values will be at their upper limit (0xFFFF for uint16). + """ - CMD_ID = 0x60d0 + CMD_ID = 0x316 def pack(self): return self.tx_data.pack([]) tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) - rx = RxData('>hhhhhh') + rx = RxData('>HHHHH') -class SetNoxAlgorithmTuningParameters(Transfer): - """ - Sets the parameters to customize the NOx algorithm. - This configuration is volatile, i.e. the parameters will be - reverted to their default values after a device reset. +class SetTemperatureOffsetParameters(Transfer): """ + This command allows to compensate temperature effects of the + design-in at customer side by applying custom temperature offsets + to the ambient temperature. - CMD_ID = 0x60e1 - - def __init__(self, index_offset, learning_time_offset_hours, learning_time_gain_hours, gating_max_duration_minutes, - std_initial, gain_factor): - self._index_offset = index_offset - self._learning_time_offset_hours = learning_time_offset_hours - self._learning_time_gain_hours = learning_time_gain_hours - self._gating_max_duration_minutes = gating_max_duration_minutes - self._std_initial = std_initial - self._gain_factor = gain_factor - - def pack(self): - return self.tx_data.pack([self._index_offset, self._learning_time_offset_hours, self._learning_time_gain_hours, - self._gating_max_duration_minutes, self._std_initial, self._gain_factor]) + The compensated ambient temperature is calculated as follows: - tx = TxData(CMD_ID, '>Hhhhhhh', device_busy_delay=0.02, slave_address=None, ignore_ack=False) + * T_Ambient_Compensated = T_Ambient + (slope * T_Ambient) + offset + Where \"slope\" and \"offset\" are the values set with this command, + smoothed with the specified time constant. + All temperatures (\"T_Ambient_Compensated\", \"T_Ambient\" and \"offset\") + are represented in °C. + There are 5 temperature offset slots available that all contribute + additively to \"T_Ambient_Compensated\". The default values for + the temperature offset parameters are all zero, meaning that + \"T_Ambient_Compensated\" is equal to \"T_Ambient\" by default. + The parameters can be changed in any state of the device, i.e. both in + idle mode and in measure mode. + """ -class GetNoxAlgorithmTuningParameters(Transfer): - """Gets the parameters to customize the NOx algorithm.""" + CMD_ID = 0x60b2 - CMD_ID = 0x60e1 + def __init__(self, offset, slope, time_constant, slot): + self._offset = offset + self._slope = slope + self._time_constant = time_constant + self._slot = slot def pack(self): - return self.tx_data.pack([]) + return self.tx_data.pack([self._offset, self._slope, self._time_constant, self._slot]) - tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) - rx = RxData('>hhhhhh') + tx = TxData(CMD_ID, '>HhhHH', device_busy_delay=0.02, slave_address=None, ignore_ack=False) class SetTemperatureAccelerationParameters(Transfer): @@ -284,157 +271,197 @@ def pack(self): tx = TxData(CMD_ID, '>HHHHH', device_busy_delay=0.02, slave_address=None, ignore_ack=False) -class SetVocAlgorithmState(Transfer): +class GetProductType(Transfer): """ - Sets the VOC algorithm state previously received with "Get VOC Algorithm State" command. - Allows restoration of the VOC algorithm state to resume operation after a power cycle or device - reset, skipping initial learning phase. By default, the VOC Engine is reset, and the algorithm state is retained if - a measurement is stopped and started again. If the VOC algorithm state shall be reset, a device reset, or a - power cycle can be executed. + Gets the product type from the device. + + The following product types are expected: + - SEN62: '00085800' + - SEN63C: '00085700' + - SEN65: '00085200' + - SEN66: '00085300' + - SEN68: '00085400' + - SEN69C: '00085900' """ - CMD_ID = 0x6181 + CMD_ID = 0xd002 - def __init__(self, state): - self._state = state + def pack(self): + return self.tx_data.pack([]) + + tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) + rx = RxData('>32s') + + +class GetProductName(Transfer): + """Gets the product name from the device.""" + + CMD_ID = 0xd014 def pack(self): - return self.tx_data.pack([self._state]) + return self.tx_data.pack([]) - tx = TxData(CMD_ID, '>H8B') + tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) + rx = RxData('>32s') -class GetVocAlgorithmState(Transfer): - """ - Gets the current VOC algorithm state. - Allows to backup and restore the VOC algorithm state to resume operation after a power cycle or - device reset, skipping initial learning phase. By default, the VOC Engine is reset and the algorithm - state is retained if a measurement is stopped and started again. If the VOC algorithm - state shall be reset, a device reset or a power cycle can be executed. - """ +class GetSerialNumber(Transfer): + """Gets the serial number from the device.""" - CMD_ID = 0x6181 + CMD_ID = 0xd033 def pack(self): return self.tx_data.pack([]) tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) - rx = RxData('>8B') + rx = RxData('>32s') -class ActivateShtHeater(Transfer): +class ReadDeviceStatus(Transfer): """ - This command allows to use the inbuilt heater in SHT sensor - to reverse creep at high humidity. - This command activates the SHT sensor heater with 200mW for 1s. - The heater is then automatically deactivated again. - The "get_sht_heater_measurements" command can be used to check if the - heater has finished. - Wait at least 20s after this command before starting a measurement to get - coherent temperature values (heating consequence to disappear). + Reads the current device status. + Use this command to get detailed information about the device status. + The device status is encoded in flags. Each device status flag + represents a single bit in a 32-bit integer value. If more than one + error is present, the device status register value is the sum of the + corresponding flag values. For details about the available flags, + refer to the device status flags documentation in the data sheet. """ - CMD_ID = 0x6765 + CMD_ID = 0xd206 def pack(self): return self.tx_data.pack([]) tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) + rx = RxData('>I') -class GetShtHeaterMeasurements(Transfer): +class ReadAndClearDeviceStatus(Transfer): """ - Get the measured values when the SHT sensor heating is triggerd. If the - heating is not finished, the returned humidity and temperature values - are 0x7FFF. + Reads the current device status (like command 0xD206 "Read Device Status") and afterwards clears + all flags. """ - CMD_ID = 0x6790 + CMD_ID = 0xd210 def pack(self): return self.tx_data.pack([]) tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) - rx = RxData('>hh') + rx = RxData('>I') -class GetProductName(Transfer): - """Gets the product name from the device.""" +class GetVersion(Transfer): + """Gets the version information for the firmware.""" - CMD_ID = 0xd014 + CMD_ID = 0xd100 def pack(self): return self.tx_data.pack([]) tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) - rx = RxData('>32s') + rx = RxData('>BB') -class GetSerialNumber(Transfer): - """Gets the serial number from the device.""" +class DeviceReset(Transfer): + """Executes a reset on the device. This has the same effect as a power cycle.""" - CMD_ID = 0xd033 + CMD_ID = 0xd304 + + def pack(self): + return self.tx_data.pack([]) + + tx = TxData(CMD_ID, '>H', device_busy_delay=1.2, slave_address=None, ignore_ack=False) + + +class StartFanCleaning(Transfer): + """ + This command triggers fan cleaning. The fan is set to the maximum + speed for 10 seconds and then automatically stopped. Wait at least 10s + after this command before starting a measurement. + """ + + CMD_ID = 0x5607 def pack(self): return self.tx_data.pack([]) tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) - rx = RxData('>32s') -class GetVersion(Transfer): - """Gets the version information for the hardware, firmware and communication protocol.""" +class ActivateShtHeater(Transfer): + """ + Activate the heater feature of the SHT4x sensor. + This command allows to use the inbuilt heater in SHT sensor + to decontaminate and reverse creep at high humidity. + This command activates the SHT sensor heater with 200mW for 1s. + The SHT heater measurement done just before deactivation can be + read using the command \"Get SHT Heater Measurements\" after + the duration of the heating feature as specified in the SHT4x + datasheet. + Wait at least 20s after this command before starting a measurement + to get coherent temperature values (heating consequence to disappear). + """ - CMD_ID = 0xd100 + CMD_ID = 0x6765 def pack(self): return self.tx_data.pack([]) tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) - rx = RxData('>BB') -class ReadDeviceStatus(Transfer): +class GetShtHeaterMeasurements(Transfer): """ - Reads the current device status. - Use this command to get detailed information about the device status. - The device status is encoded in flags. Each device status flag - represents a single bit in a 32-bit integer value. If more than one - error is present, the device status register value is the sum of the - corresponding flag values. For details about the available flags, - refer to the device status flags documentation in the data sheet. + Get the measurement values when the SHT sensor heating + is finished. """ - CMD_ID = 0xd206 + CMD_ID = 0x6790 def pack(self): return self.tx_data.pack([]) tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) - rx = RxData('>I') + rx = RxData('>hh') -class ReadAndClearDeviceStatus(Transfer): +class ReadMeasuredValuesAsIntegers(Transfer): """ - Reads the current device status (like command 0xD206 "Read Device Status") and afterwards clears - all flags. + Returns the measured values. + The command \"Get Data Ready\" can be used to check if new + data is available since the last read operation. If no new data is + available, the previous values will be returned again. If no data + is available at all (e.g. measurement not running for at least one + second), all values will be at their upper limit (0xFFFF for uint16, + 0x7FFF for int16). """ - CMD_ID = 0xd210 + CMD_ID = 0x446 def pack(self): return self.tx_data.pack([]) tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) - rx = RxData('>I') + rx = RxData('>HHHHhhhh') -class DeviceReset(Transfer): - """Executes a reset on the device. This has the same effect as a power cycle.""" +class ReadMeasuredRawValues(Transfer): + """ + Returns the measured raw values. + The command "Get Data Ready" can be used to check if new + data is available since the last read operation. If no new data is + available, the previous values will be returned again. If no data + is available at all (e.g. measurement not running for at least one + second), all values will be at their upper limit (0xFFFF for uint16, + 0x7FFF for int16). + """ - CMD_ID = 0xd304 + CMD_ID = 0x455 def pack(self): return self.tx_data.pack([]) - tx = TxData(CMD_ID, '>H', device_busy_delay=1.2, slave_address=None, ignore_ack=False) + tx = TxData(CMD_ID, '>H', device_busy_delay=0.02, slave_address=None, ignore_ack=False) + rx = RxData('>hhHH') diff --git a/sensirion_i2c_sen65/device.py b/sensirion_i2c_sen65/device.py index e959db1..b7ff22d 100644 --- a/sensirion_i2c_sen65/device.py +++ b/sensirion_i2c_sen65/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.1.2 +# Generator: sensirion-driver-generator 1.7.0 # Product: sen65 -# Model-Version: 1.3.0 +# Model-Version: 1.4.0 # """ The class Sen65DeviceBase implements the low level interface of the sensor. @@ -18,8 +18,8 @@ from sensirion_driver_adapters.transfer import execute_transfer from sensirion_driver_support_types.mixin_access import MixinAccess from sensirion_i2c_sen65.commands import (ActivateShtHeater, DeviceReset, DeviceStatus, GetDataReady, - GetNoxAlgorithmTuningParameters, GetProductName, GetSerialNumber, - GetShtHeaterMeasurements, GetVersion, GetVocAlgorithmState, + GetNoxAlgorithmTuningParameters, GetProductName, GetProductType, + GetSerialNumber, GetShtHeaterMeasurements, GetVersion, GetVocAlgorithmState, GetVocAlgorithmTuningParameters, ReadAndClearDeviceStatus, ReadDeviceStatus, ReadMeasuredRawValues, ReadMeasuredValuesAsIntegers, ReadNumberConcentrationValuesAsIntegers, SetNoxAlgorithmTuningParameters, @@ -27,12 +27,8 @@ SetVocAlgorithmState, SetVocAlgorithmTuningParameters, StartContinuousMeasurement, StartFanCleaning, StopMeasurement) -from sensirion_i2c_sen65.result_types import (SignalHumidity, SignalMassConcentrationPm10p0, - SignalMassConcentrationPm1p0, SignalMassConcentrationPm2p5, - SignalMassConcentrationPm4p0, SignalNoxIndex, - SignalNumberConcentrationPm0p5, SignalNumberConcentrationPm10p0, - SignalNumberConcentrationPm1p0, SignalNumberConcentrationPm2p5, - SignalNumberConcentrationPm4p0, SignalTemperature, SignalVocIndex) +from sensirion_i2c_sen65.result_types import (SignalDividedBy10Int16, SignalDividedBy10Uint16, SignalHumidity, + SignalTemperature) class Sen65DeviceBase: @@ -45,192 +41,31 @@ def __init__(self, channel): def channel(self): return self._channel - def start_continuous_measurement(self): - """ - Starts a continuous measurement. - After starting the measurement, it takes some time (~1.1s) until the - first measurement results are available. You could poll with the command - "Get Data Ready" to check when the results are ready to read. - This command is only available in idle mode. If the device is already - in any measure mode, this command has no effect. - """ - transfer = StartContinuousMeasurement() - return execute_transfer(self._channel, transfer) - - def stop_measurement(self): - """ - Stops the measurement and returns to idle mode. After sending this - command, wait at least 1000 ms before starting a new measurement. - If the device is already in idle mode, this command has no effect. - """ - transfer = StopMeasurement() - return execute_transfer(self._channel, transfer) - - def get_data_ready(self): - """ - This command can be used to check if new measurement results are ready to read. The data ready flag - is automatically reset after reading the measurement values. - - :return padding: - Padding byte, always 0x00. - :return data_ready: - True (0x01) if data is ready, False (0x00) if not. When no measurement is running, False will be - returned. - """ - transfer = GetDataReady() - return execute_transfer(self._channel, transfer) - - def read_measured_values_as_integers(self): - """ - Returns the measured values. - The command "Get Data Ready" can be used to check if new - data is available since the last read operation. If no new data is - available, the previous values will be returned again. If no data - is available at all (e.g. measurement not running for at least one - second), all values will be at their upper limit (0xFFFF for uint16, - 0x7FFF for int16). - - :return mass_concentration_pm1p0: - Value is scaled with factor 10: PM1.0 [µg/m³] = value / 10 - *Note: If this value is unknown, 0xFFFF is returned.* - :return mass_concentration_pm2p5: - Value is scaled with factor 10: PM2.5 [µg/m³] = value / 10 - *Note: If this value is unknown, 0xFFFF is returned.* - :return mass_concentration_pm4p0: - Value is scaled with factor 10: PM4.0 [µg/m³] = value / 10 - *Note: If this value is unknown, 0xFFFF is returned.* - :return mass_concentration_pm10p0: - Value is scaled with factor 10: PM10.0 [µg/m³] = value / 10 - *Note: If this value is unknown, 0xFFFF is returned.* - :return ambient_humidity: - Value is scaled with factor 100: RH [%] = value / 100 - *Note: If this value is unknown, 0x7FFF is returned.* - :return ambient_temperature: - Value is scaled with factor 200: T [°C] = value / 200 - *Note: If this value is unknown, 0x7FFF is returned.* - :return voc_index: - Value is scaled with factor 10: VOC Index = value / 10 - *Note: If this value is unknown, 0x7FFF is returned.* - :return nox_index: - Value is scaled with factor 10: NOx Index = value / 10 - *Note: If this value is unknown, 0x7FFF is returned. During - the first 10..11 seconds after power-on or device reset, this - value will be 0x7FFF as well.* - """ - transfer = ReadMeasuredValuesAsIntegers() - return execute_transfer(self._channel, transfer) - - def read_number_concentration_values_as_integers(self): - """ - Returns the measured number concentration values. - The command "Get Data Ready" can be used to check if new - data is available since the last read operation. If no new data is - available, the previous values will be returned again. If no data - is available at all (e.g. measurement not running for at least one - second), all values will be at their upper limit (0xFFFF for uint16). - - :return number_concentration_pm0p5: - Value is scaled with factor 10: PM0.5 [particles/cm³] = value / 10 - *Note: If this value is unknown, 0xFFFF is returned.* - :return number_concentration_pm1p0: - Value is scaled with factor 10: PM1.0 [particles/cm³] = value / 10 - *Note: If this value is unknown, 0xFFFF is returned.* - :return number_concentration_pm2p5: - Value is scaled with factor 10: PM2.5 [particles/cm³] = value / 10 - *Note: If this value is unknown, 0xFFFF is returned.* - :return number_concentration_pm4p0: - Value is scaled with factor 10: PM4.0 [particles/cm³] = value / 10 - *Note: If this value is unknown, 0xFFFF is returned.* - :return number_concentration_pm10p0: - Value is scaled with factor 10: PM10.0 [particles/cm³] = value / 10 - *Note: If this value is unknown, 0xFFFF is returned.* - """ - transfer = ReadNumberConcentrationValuesAsIntegers() - return execute_transfer(self._channel, transfer) - - def read_measured_raw_values(self): - """ - Returns the measured raw values. - The command "Get Data Ready" can be used to check if new - data is available since the last read operation. If no new data is - available, the previous values will be returned again. If no data - is available at all (e.g. measurement not running for at least one - second), all values will be at their upper limit (0xFFFF for uint16, - 0x7FFF for int16). - - :return raw_humidity: - Value is scaled with factor 100: RH [%] = value / 100 - *Note: If this value is unknown, 0x7FFF is returned.* - :return raw_temperature: - Value is scaled with factor 200: T [°C] = value / 200 - *Note: If this value is unknown, 0x7FFF is returned.* - :return raw_voc: - Raw measured VOC ticks without scale factor. - *Note: If this value is unknown, 0xFFFF is returned.* - :return raw_nox: - Raw measured NOx ticks without scale factor. - *Note: If this value is unknown, 0xFFFF is returned. During - the first 10..11 seconds after power-on or device reset, this - value will be 0xFFFF as well.* + def get_voc_algorithm_tuning_parameters(self): """ - transfer = ReadMeasuredRawValues() - return execute_transfer(self._channel, transfer) + Gets the parameters to customize the VOC algorithm. - def start_fan_cleaning(self): - """ - This command triggers fan cleaning. The fan is set to the maximum - speed for 10 seconds and then automatically stopped. Wait at least 10s - after this command before starting a measurement. + :return index_offset: + VOC index representing typical (average) conditions. + :return learning_time_offset_hours: + Time constant to estimate the VOC algorithm offset from the history in hours. Past events will be + forgotten after about twice the learning time. + :return learning_time_gain_hours: + Time constant to estimate the VOC algorithm gain from the history in hours. Past events will be + forgotten after about twice the learning time. + :return gating_max_duration_minutes: + Maximum duration of gating in minutes (freeze of estimator during high VOC index signal). Zero + disables the gating. + :return std_initial: + Initial estimate for standard deviation. Lower value boosts events during initial learning period, + but may result in larger device-to-device variations. + :return gain_factor: + Gain factor to amplify or to attenuate the VOC index output. .. note:: This command is only available in idle mode. """ - transfer = StartFanCleaning() - return execute_transfer(self._channel, transfer) - - def set_temperature_offset_parameters(self, offset, slope, time_constant, slot): - """ - This command allows to compensate temperature effects of the - design-in at customer side by applying custom temperature offsets - to the ambient temperature. The compensated ambient temperature is - calculated as follows: - T_Ambient_Compensated = T_Ambient + (slope * T_Ambient) + offset - Where slope and offset are the values set with this command, - smoothed with the specified time constant. - All temperatures (T_Ambient_Compensated, T_Ambient and offset) - are represented in °C. - There are 5 temperature offset slots available that all contribute - additively to T_Ambient_Compensated. The default values for - the temperature offset parameters are all zero, meaning that - T_Ambient_Compensated is equal to T_Ambient by default. - The parameters can be changed in any state of the device, i.e. both in - idle mode and in measure mode. - - :param offset: - Constant temperature offset scaled with factor 200 (T [°C] = value / 200). - :param slope: - Normalized temperature offset slope scaled with factor 10000 (applied factor = value / 10000). - :param time_constant: - The time constant determines how fast the new slope and offset will be applied. - After the specified value in seconds, 63% of the new slope and offset are applied. - A time constant of zero means the new values will be applied immediately - (within the next measure interval of 1 second). - :param slot: - The temperature offset slot to be modified. - Valid values are 0 .. 4. If the value is outside this range, - the parameters will not be applied. - - .. note:: - This configuration is volatile, i.e. the parameters will be reverted to their default value of zero - after a device reset. - - :Example: - .. code-block:: python - - sensor.set_temperature_offset_parameters(1, 10, 1, 0) - - """ - transfer = SetTemperatureOffsetParameters(offset, slope, time_constant, slot) + transfer = GetVocAlgorithmTuningParameters() return execute_transfer(self._channel, transfer) def set_voc_algorithm_tuning_parameters(self, index_offset, learning_time_offset_hours, learning_time_gain_hours, @@ -276,31 +111,68 @@ def set_voc_algorithm_tuning_parameters(self, index_offset, learning_time_offset gating_max_duration_minutes, std_initial, gain_factor) return execute_transfer(self._channel, transfer) - def get_voc_algorithm_tuning_parameters(self): + def get_voc_algorithm_state(self): """ - Gets the parameters to customize the VOC algorithm. + Gets the current VOC algorithm state. + Allows to backup and restore the VOC algorithm state to resume operation after a power cycle or + device reset, skipping initial learning phase. By default, the VOC Engine is reset and the algorithm + state is retained if a measurement is stopped and started again. If the VOC algorithm + state shall be reset, a device reset or a power cycle can be executed. + + :return state: + Current VOC algorithm state. + + .. note:: + This command can be used either in measure mode or in idle mode (which will then return the state at the + time when the measurement was stopped). In measure mode, the state can be read each measure interval to + always have the latest state available, even in case of a sudden power loss. + """ + transfer = GetVocAlgorithmState() + return execute_transfer(self._channel, transfer)[0] + + def set_voc_algorithm_state(self, state): + """ + Sets the VOC algorithm state previously received with "Get VOC Algorithm State" command. + Allows restoration of the VOC algorithm state to resume operation after a power cycle or device + reset, skipping initial learning phase. By default, the VOC Engine is reset, and the algorithm state is retained if + a measurement is stopped and started again. If the VOC algorithm state shall be reset, a device reset, or a + power cycle can be executed. + + :param state: + VOC algorithm state to restore. + + .. note:: + This command is only available in idle mode and the state will be applied only once when starting + the next measurement. In measure mode, this command has no effect. + """ + transfer = SetVocAlgorithmState(state) + return execute_transfer(self._channel, transfer) + + def get_nox_algorithm_tuning_parameters(self): + """ + Gets the parameters to customize the NOx algorithm. :return index_offset: - VOC index representing typical (average) conditions. + NOx index representing typical (average) conditions. :return learning_time_offset_hours: - Time constant to estimate the VOC algorithm offset from the history in hours. Past events will be + Time constant to estimate the NOx algorithm offset from the history in hours. Past events will be forgotten after about twice the learning time. :return learning_time_gain_hours: - Time constant to estimate the VOC algorithm gain from the history in hours. Past events will be - forgotten after about twice the learning time. + The time constant to estimate the NOx algorithm gain from the history has no impact for NOx. This + parameter is still in place for consistency reasons with the VOC tuning parameters command. :return gating_max_duration_minutes: - Maximum duration of gating in minutes (freeze of estimator during high VOC index signal). Zero + Maximum duration of gating in minutes (freeze of estimator during high NOx index signal). Zero disables the gating. :return std_initial: - Initial estimate for standard deviation. Lower value boosts events during initial learning period, - but may result in larger device-to-device variations. + The initial estimate for standard deviation has no impact for NOx. This parameter is still in place + for consistency reasons with the VOC tuning parameters command. :return gain_factor: - Gain factor to amplify or to attenuate the VOC index output. + Gain factor to amplify or to attenuate the NOx index output. .. note:: - This command is only available in idle mode. + This command is available only in idle mode. """ - transfer = GetVocAlgorithmTuningParameters() + transfer = GetNoxAlgorithmTuningParameters() return execute_transfer(self._channel, transfer) def set_nox_algorithm_tuning_parameters(self, index_offset, learning_time_offset_hours, learning_time_gain_hours, @@ -346,31 +218,115 @@ def set_nox_algorithm_tuning_parameters(self, index_offset, learning_time_offset gating_max_duration_minutes, std_initial, gain_factor) return execute_transfer(self._channel, transfer) - def get_nox_algorithm_tuning_parameters(self): + def start_continuous_measurement(self): """ - Gets the parameters to customize the NOx algorithm. - - :return index_offset: - NOx index representing typical (average) conditions. - :return learning_time_offset_hours: - Time constant to estimate the NOx algorithm offset from the history in hours. Past events will be - forgotten after about twice the learning time. - :return learning_time_gain_hours: - The time constant to estimate the NOx algorithm gain from the history has no impact for NOx. This - parameter is still in place for consistency reasons with the VOC tuning parameters command. - :return gating_max_duration_minutes: - Maximum duration of gating in minutes (freeze of estimator during high NOx index signal). Zero - disables the gating. - :return std_initial: - The initial estimate for standard deviation has no impact for NOx. This parameter is still in place - for consistency reasons with the VOC tuning parameters command. - :return gain_factor: - Gain factor to amplify or to attenuate the NOx index output. + Starts a continuous measurement. + After starting the measurement, it takes some time (~1.1s) until the + first measurement results are available. You could poll with the command + "Get Data Ready" to check when the results are ready to read. + This command is only available in idle mode. If the device is already + in any measure mode, this command has no effect. + """ + transfer = StartContinuousMeasurement() + return execute_transfer(self._channel, transfer) + + def stop_measurement(self): + """ + Stops the measurement and returns to idle mode. After sending this + command, wait at least 1000 ms before starting a new measurement. + If the device is already in idle mode, this command has no effect. + """ + transfer = StopMeasurement() + return execute_transfer(self._channel, transfer) + + def get_data_ready(self): + """ + This command can be used to check if new measurement results are ready to read. The data ready flag + is automatically reset after reading the measurement values. + + :return padding: + Padding byte, always 0x00. + :return data_ready: + True (0x01) if data is ready, False (0x00) if not. When no measurement is running, False will be + returned. + """ + transfer = GetDataReady() + return execute_transfer(self._channel, transfer) + + def read_number_concentration_values_as_integers(self): + """ + Returns the measured number concentration values. + The command 0x0202 "Get Data Ready" can be used to check if new + data is available since the last read operation. If no new data is + available, the previous values will be returned again. If no data + is available at all (e.g. measurement not running for at least one + second), all values will be at their upper limit (0xFFFF for uint16). + + :return number_concentration_pm0p5: + Value is scaled with factor 10: PM0.5 [particles/cm³] = value / 10. + *Note: If this value is unknown, 0xFFFF is returned.* + :return number_concentration_pm1p0: + Value is scaled with factor 10: PM1.0 [particles/cm³] = value / 10. + *Note: If this value is unknown, 0xFFFF is returned.* + :return number_concentration_pm2p5: + Value is scaled with factor 10: PM2.5 [particles/cm³] = value / 10. + *Note: If this value is unknown, 0xFFFF is returned.* + :return number_concentration_pm4p0: + Value is scaled with factor 10: PM4.0 [particles/cm³] = value / 10. + *Note: If this value is unknown, 0xFFFF is returned.* + :return number_concentration_pm10p0: + Value is scaled with factor 10: PM10.0 [particles/cm³] = value / 10. + *Note: If this value is unknown, 0xFFFF is returned.* + """ + transfer = ReadNumberConcentrationValuesAsIntegers() + return execute_transfer(self._channel, transfer) + + def set_temperature_offset_parameters(self, offset, slope, time_constant, slot): + """ + This command allows to compensate temperature effects of the + design-in at customer side by applying custom temperature offsets + to the ambient temperature. + + The compensated ambient temperature is calculated as follows: + + * T_Ambient_Compensated = T_Ambient + (slope * T_Ambient) + offset + + Where \"slope\" and \"offset\" are the values set with this command, + smoothed with the specified time constant. + All temperatures (\"T_Ambient_Compensated\", \"T_Ambient\" and \"offset\") + are represented in °C. + There are 5 temperature offset slots available that all contribute + additively to \"T_Ambient_Compensated\". The default values for + the temperature offset parameters are all zero, meaning that + \"T_Ambient_Compensated\" is equal to \"T_Ambient\" by default. + The parameters can be changed in any state of the device, i.e. both in + idle mode and in measure mode. + + :param offset: + Constant temperature offset scaled with factor 200 (T [°C] = value / 200). + :param slope: + Normalized temperature offset slope scaled with factor 10000 (applied factor = value / 10000). + :param time_constant: + The time constant determines how fast the new slope and offset will be applied. + After the specified value in seconds, 63% of the new slope and offset are applied. + A time constant of zero means the new values will be applied immediately + (within the next measure interval of 1 second). + :param slot: + The temperature offset slot to be modified. + Valid values are 0 .. 4. If the value is outside this range, + the parameters will not be applied. .. note:: - This command is available only in idle mode. + This configuration is volatile, i.e. the parameters will be reverted to their default value of zero + after a device reset. + + :Example: + .. code-block:: python + + sensor.set_temperature_offset_parameters(1, 10, 1, 0) + """ - transfer = GetNoxAlgorithmTuningParameters() + transfer = SetTemperatureOffsetParameters(offset, slope, time_constant, slot) return execute_transfer(self._channel, transfer) def set_temperature_acceleration_parameters(self, k, p, t1, t2): @@ -400,82 +356,25 @@ def set_temperature_acceleration_parameters(self, k, p, t1, t2): transfer = SetTemperatureAccelerationParameters(k, p, t1, t2) return execute_transfer(self._channel, transfer) - def set_voc_algorithm_state(self, state): - """ - Sets the VOC algorithm state previously received with "Get VOC Algorithm State" command. - Allows restoration of the VOC algorithm state to resume operation after a power cycle or device - reset, skipping initial learning phase. By default, the VOC Engine is reset, and the algorithm state is retained if - a measurement is stopped and started again. If the VOC algorithm state shall be reset, a device reset, or a - power cycle can be executed. - - :param state: - VOC algorithm state to restore. - - .. note:: - This command is only available in idle mode and the state will be applied only once when starting - the next measurement. In measure mode, this command has no effect. - """ - transfer = SetVocAlgorithmState(state) - return execute_transfer(self._channel, transfer) - - def get_voc_algorithm_state(self): + def get_product_type(self): """ - Gets the current VOC algorithm state. - Allows to backup and restore the VOC algorithm state to resume operation after a power cycle or - device reset, skipping initial learning phase. By default, the VOC Engine is reset and the algorithm - state is retained if a measurement is stopped and started again. If the VOC algorithm - state shall be reset, a device reset or a power cycle can be executed. + Gets the product type from the device. - :return state: - Current VOC algorithm state. + The following product types are expected: + - SEN62: '00085800' + - SEN63C: '00085700' + - SEN65: '00085200' + - SEN66: '00085300' + - SEN68: '00085400' + - SEN69C: '00085900' - .. note:: - This command can be used either in measure mode or in idle mode (which will then return the state at the - time when the measurement was stopped). In measure mode, the state can be read each measure interval to - always have the latest state available, even in case of a sudden power loss. + :return product_type: + Null-terminated ASCII string containing the product type. + Up to 32 characters can be read from the device. """ - transfer = GetVocAlgorithmState() + transfer = GetProductType() return execute_transfer(self._channel, transfer)[0] - def activate_sht_heater(self): - """ - This command allows to use the inbuilt heater in SHT sensor - to reverse creep at high humidity. - This command activates the SHT sensor heater with 200mW for 1s. - The heater is then automatically deactivated again. - The "get_sht_heater_measurements" command can be used to check if the - heater has finished. - Wait at least 20s after this command before starting a measurement to get - coherent temperature values (heating consequence to disappear). - - .. note:: - This command is only available in idle mode. - """ - transfer = ActivateShtHeater() - return execute_transfer(self._channel, transfer) - - def get_sht_heater_measurements(self): - """ - Get the measured values when the SHT sensor heating is triggerd. If the - heating is not finished, the returned humidity and temperature values - are 0x7FFF. - - :return humidity: - Value is scaled with factor 100: RH [%] = value / 100 - *Note: If this value is not available, 0x7FFF is returned.* - :return temperature: - Value is scaled with factor 200: T [°C] = value / 200 - *Note: If this value is not available, 0x7FFF is returned.* - - .. note:: - This command is only availble in idle mode. - This command must be used after the "activate_sht_heater" command. - The get_sht_heater_measurements command can be queried every 0.05s to get - the measurements. - """ - transfer = GetShtHeaterMeasurements() - return execute_transfer(self._channel, transfer) - def get_product_name(self): """ Gets the product name from the device. @@ -498,18 +397,6 @@ def get_serial_number(self): transfer = GetSerialNumber() return execute_transfer(self._channel, transfer)[0] - def get_version(self): - """ - Gets the version information for the hardware, firmware and communication protocol. - - :return firmware_major: - Firmware major version number. - :return firmware_minor: - Firmware minor version number. - """ - transfer = GetVersion() - return execute_transfer(self._channel, transfer) - def read_device_status(self): """ Reads the current device status. @@ -547,11 +434,146 @@ def read_and_clear_device_status(self): res_0 = execute_transfer(self._channel, transfer)[0] return DeviceStatus(res_0) + def get_version(self): + """ + Gets the version information for the firmware. + + :return firmware_major: + Firmware major version number. + :return firmware_minor: + Firmware minor version number. + """ + transfer = GetVersion() + return execute_transfer(self._channel, transfer) + def device_reset(self): """Executes a reset on the device. This has the same effect as a power cycle.""" transfer = DeviceReset() return execute_transfer(self._channel, transfer) + def start_fan_cleaning(self): + """ + This command triggers fan cleaning. The fan is set to the maximum + speed for 10 seconds and then automatically stopped. Wait at least 10s + after this command before starting a measurement. + + .. note:: + This command is only available in idle mode. + """ + transfer = StartFanCleaning() + return execute_transfer(self._channel, transfer) + + def activate_sht_heater(self): + """ + Activate the heater feature of the SHT4x sensor. + This command allows to use the inbuilt heater in SHT sensor + to decontaminate and reverse creep at high humidity. + This command activates the SHT sensor heater with 200mW for 1s. + The SHT heater measurement done just before deactivation can be + read using the command \"Get SHT Heater Measurements\" after + the duration of the heating feature as specified in the SHT4x + datasheet. + Wait at least 20s after this command before starting a measurement + to get coherent temperature values (heating consequence to disappear). + + .. note:: + This command is only available in idle mode. + """ + transfer = ActivateShtHeater() + return execute_transfer(self._channel, transfer) + + def get_sht_heater_measurements(self): + """ + Get the measurement values when the SHT sensor heating + is finished. + + :return sht_relative_humidity: + If the sht heating is completed, this value indicates + the scaled relative humidity of the SHT4x sensor. + Value is scaled with factor 100: RH [%] = value / 100 + *Note: If this value is not available, 0x7FFF is returned.* + :return sht_temperature: + If the sht heating is completed, this value indicates + the scaled temperature of the SHT4x sensor. + Value is scaled with factor 200: T [°C] = value / 200 + *Note: If this value is not available, 0x7FFF is returned.* + + .. note:: + This command must be used after the \"Activate SHT Heater\" command. The get sht heater measurements + command can be queried every 0.05s to get the measurements. This command is only available in idle + mode. + """ + transfer = GetShtHeaterMeasurements() + return execute_transfer(self._channel, transfer) + + def read_measured_values_as_integers(self): + """ + Returns the measured values. + The command \"Get Data Ready\" can be used to check if new + data is available since the last read operation. If no new data is + available, the previous values will be returned again. If no data + is available at all (e.g. measurement not running for at least one + second), all values will be at their upper limit (0xFFFF for uint16, + 0x7FFF for int16). + + :return mass_concentration_pm1p0: + Value is scaled with factor 10: PM1.0 [µg/m³] = value / 10 + *Note: If this value is unknown, 0xFFFF is returned.* + :return mass_concentration_pm2p5: + Value is scaled with factor 10: PM2.5 [µg/m³] = value / 10 + *Note: If this value is unknown, 0xFFFF is returned.* + :return mass_concentration_pm4p0: + Value is scaled with factor 10: PM4.0 [µg/m³] = value / 10 + *Note: If this value is unknown, 0xFFFF is returned.* + :return mass_concentration_pm10p0: + Value is scaled with factor 10: PM10.0 [µg/m³] = value / 10 + *Note: If this value is unknown, 0xFFFF is returned.* + :return ambient_humidity: + Value is scaled with factor 100: RH [%] = value / 100 + *Note: If this value is unknown, 0x7FFF is returned.* + :return ambient_temperature: + Value is scaled with factor 200: T [°C] = value / 200 + *Note: If this value is unknown, 0x7FFF is returned.* + :return voc_index: + Value is scaled with factor 10: VOC Index = value / 10 + *Note: If this value is unknown, 0x7FFF is returned.* + :return nox_index: + Value is scaled with factor 10: NOx Index = value / 10 + *Note: If this value is unknown, 0x7FFF is returned. During + the first 10..11 seconds after power-on or device reset, this + value will be 0x7FFF as well.* + """ + transfer = ReadMeasuredValuesAsIntegers() + return execute_transfer(self._channel, transfer) + + def read_measured_raw_values(self): + """ + Returns the measured raw values. + The command "Get Data Ready" can be used to check if new + data is available since the last read operation. If no new data is + available, the previous values will be returned again. If no data + is available at all (e.g. measurement not running for at least one + second), all values will be at their upper limit (0xFFFF for uint16, + 0x7FFF for int16). + + :return raw_humidity: + Value is scaled with factor 100: RH [%] = value / 100 + *Note: If this value is unknown, 0x7FFF is returned.* + :return raw_temperature: + Value is scaled with factor 200: T [°C] = value / 200 + *Note: If this value is unknown, 0x7FFF is returned.* + :return raw_voc: + Raw measured VOC ticks without scale factor. + *Note: If this value is unknown, 0xFFFF is returned.* + :return raw_nox: + Raw measured NOx ticks without scale factor. + *Note: If this value is unknown, 0xFFFF is returned. During + the first 10..11 seconds after power-on or device reset, this + value will be 0xFFFF as well.* + """ + transfer = ReadMeasuredRawValues() + return execute_transfer(self._channel, transfer) + class Sen65Device(Sen65DeviceBase): """Driver class implementation of SEN65""" @@ -577,20 +599,21 @@ def read_measured_values(self): :return humidity: Measured humidity in %RH. :return temperature: - Measured temperature in degrees celsius. + Measured temperature in degrees Celsius. :return voc_index: - Measured VOC Index between 0 and 500. + VOC Index :return nox_index: - Measured NOx Index between 0 and 500. + NOx Index """ (mass_concentration_pm1p0_raw, mass_concentration_pm2p5_raw, mass_concentration_pm4p0_raw, mass_concentration_pm10p0_raw, humidity_raw, temperature_raw, voc_index_raw, nox_index_raw ) = self.read_measured_values_as_integers() - return (SignalMassConcentrationPm1p0(mass_concentration_pm1p0_raw), - SignalMassConcentrationPm2p5(mass_concentration_pm2p5_raw), - SignalMassConcentrationPm4p0(mass_concentration_pm4p0_raw), - SignalMassConcentrationPm10p0(mass_concentration_pm10p0_raw), SignalHumidity(humidity_raw), - SignalTemperature(temperature_raw), SignalVocIndex(voc_index_raw), SignalNoxIndex(nox_index_raw)) + return (SignalDividedBy10Uint16(mass_concentration_pm1p0_raw), + SignalDividedBy10Uint16(mass_concentration_pm2p5_raw), + SignalDividedBy10Uint16(mass_concentration_pm4p0_raw), + SignalDividedBy10Uint16(mass_concentration_pm10p0_raw), SignalHumidity(humidity_raw), + SignalTemperature(temperature_raw), SignalDividedBy10Int16(voc_index_raw), + SignalDividedBy10Int16(nox_index_raw)) def read_number_concentration_values(self): """ @@ -610,8 +633,8 @@ def read_number_concentration_values(self): (number_concentration_pm0p5_raw, number_concentration_pm1p0_raw, number_concentration_pm2p5_raw, number_concentration_pm4p0_raw, number_concentration_pm10p0_raw ) = self.read_number_concentration_values_as_integers() - return (SignalNumberConcentrationPm0p5(number_concentration_pm0p5_raw), - SignalNumberConcentrationPm1p0(number_concentration_pm1p0_raw), - SignalNumberConcentrationPm2p5(number_concentration_pm2p5_raw), - SignalNumberConcentrationPm4p0(number_concentration_pm4p0_raw), - SignalNumberConcentrationPm10p0(number_concentration_pm10p0_raw)) + return (SignalDividedBy10Uint16(number_concentration_pm0p5_raw), + SignalDividedBy10Uint16(number_concentration_pm1p0_raw), + SignalDividedBy10Uint16(number_concentration_pm2p5_raw), + SignalDividedBy10Uint16(number_concentration_pm4p0_raw), + SignalDividedBy10Uint16(number_concentration_pm10p0_raw)) diff --git a/sensirion_i2c_sen65/response_provider.py b/sensirion_i2c_sen65/response_provider.py index c03eaaa..3f9e6d6 100644 --- a/sensirion_i2c_sen65/response_provider.py +++ b/sensirion_i2c_sen65/response_provider.py @@ -4,7 +4,8 @@ class Sen65ResponseProvider(rp.ResponseProvider): - RESPONSE_MAP = {0xd014: struct.pack('>32s', rp.random_ascii_string(32)), + RESPONSE_MAP = {0xd002: struct.pack('>32s', rp.random_ascii_string(32)), + 0xd014: struct.pack('>32s', rp.random_ascii_string(32)), 0xd033: struct.pack('>32s', rp.random_ascii_string(32))} def get_id(self) -> str: diff --git a/sensirion_i2c_sen65/result_types.py b/sensirion_i2c_sen65/result_types.py index bbf1815..dd22fba 100644 --- a/sensirion_i2c_sen65/result_types.py +++ b/sensirion_i2c_sen65/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.1.2 +# Generator: sensirion-driver-generator 1.7.0 # Product: sen65 -# Model-Version: 1.3.0 +# Model-Version: 1.4.0 # """ The signal classes specify transformations of the raw sensor signals into a meaningful units. @@ -17,134 +17,42 @@ from sensirion_driver_support_types.signals import AbstractSignal -class SignalMassConcentrationPm1p0(AbstractSignal): - """Mass concentration in μg/m³ for particles smaller than 1.0 μm""" +class SignalDividedBy10Uint16(AbstractSignal): + """ + All mass and number concentrations are scaled by a factor 10 to avoid + floating point operations on the communication interface. + """ - def __init__(self, mass_concentration_pm1p0_raw): - self._mass_concentration_pm1p0 = mass_concentration_pm1p0_raw / 10.0 + def __init__(self, scaled_integer_value): + self._divided_by_10_uint16 = scaled_integer_value / 10.0 @property def value(self): - return self._mass_concentration_pm1p0 + return self._divided_by_10_uint16 def __str__(self): return '{0:.2f}'.format(self.value) -class SignalMassConcentrationPm2p5(AbstractSignal): - """Mass concentration in μg/m³ for particles smaller than 2.5 μm""" +class SignalDividedBy10Int16(AbstractSignal): + """ + The VOC and NOx indices are scaled by a factor 10 to avoid + floating point operations on the communication interface. + """ - def __init__(self, mass_concentration_pm2p5_raw): - self._mass_concentration_pm2p5 = mass_concentration_pm2p5_raw / 10.0 + def __init__(self, scaled_integer_value): + self._divided_by_10_int16 = scaled_integer_value / 10.0 @property def value(self): - return self._mass_concentration_pm2p5 - - def __str__(self): - return '{0:.2f}'.format(self.value) - - -class SignalMassConcentrationPm4p0(AbstractSignal): - """Mass concentration in μg/m³ for particles smaller than 4.0 μm""" - - def __init__(self, mass_concentration_pm4p0_raw): - self._mass_concentration_pm4p0 = mass_concentration_pm4p0_raw / 10.0 - - @property - def value(self): - return self._mass_concentration_pm4p0 - - def __str__(self): - return '{0:.2f}'.format(self.value) - - -class SignalMassConcentrationPm10p0(AbstractSignal): - """Mass concentration in μg/m³ for particles smaller than 10.0 μm""" - - def __init__(self, mass_concentration_pm10p0_raw): - self._mass_concentration_pm10p0 = mass_concentration_pm10p0_raw / 10.0 - - @property - def value(self): - return self._mass_concentration_pm10p0 - - def __str__(self): - return '{0:.2f}'.format(self.value) - - -class SignalNumberConcentrationPm0p5(AbstractSignal): - """Number concentration in particles/cm³ for particles smaller than 0.5 μm""" - - def __init__(self, number_concentration_pm0p5_raw): - self._number_concentration_pm0p5 = number_concentration_pm0p5_raw / 10.0 - - @property - def value(self): - return self._number_concentration_pm0p5 - - def __str__(self): - return '{0:.2f}'.format(self.value) - - -class SignalNumberConcentrationPm1p0(AbstractSignal): - """Number concentration in particles/cm³ for particles smaller than 1.0 μm""" - - def __init__(self, number_concentration_pm1p0_raw): - self._number_concentration_pm1p0 = number_concentration_pm1p0_raw / 10.0 - - @property - def value(self): - return self._number_concentration_pm1p0 - - def __str__(self): - return '{0:.2f}'.format(self.value) - - -class SignalNumberConcentrationPm2p5(AbstractSignal): - """Number concentration in particles/cm³ for particles smaller than 2.5 μm""" - - def __init__(self, number_concentration_pm2p5_raw): - self._number_concentration_pm2p5 = number_concentration_pm2p5_raw / 10.0 - - @property - def value(self): - return self._number_concentration_pm2p5 - - def __str__(self): - return '{0:.2f}'.format(self.value) - - -class SignalNumberConcentrationPm4p0(AbstractSignal): - """Number concentration in particles/cm³ for particles smaller than 4.0 μm""" - - def __init__(self, number_concentration_pm4p0_raw): - self._number_concentration_pm4p0 = number_concentration_pm4p0_raw / 10.0 - - @property - def value(self): - return self._number_concentration_pm4p0 - - def __str__(self): - return '{0:.2f}'.format(self.value) - - -class SignalNumberConcentrationPm10p0(AbstractSignal): - """Number concentration in particles/cm³ for particles smaller than 10.0 μm""" - - def __init__(self, number_concentration_pm10p0_raw): - self._number_concentration_pm10p0 = number_concentration_pm10p0_raw / 10.0 - - @property - def value(self): - return self._number_concentration_pm10p0 + return self._divided_by_10_int16 def __str__(self): return '{0:.2f}'.format(self.value) class SignalTemperature(AbstractSignal): - """Measured temperature in degrees celsius. The raw value is scaled appropriately.""" + """Measured temperature in degrees Celsius. The raw value is scaled appropriately.""" def __init__(self, temperature_raw): self._temperature = temperature_raw / 200.0 @@ -170,31 +78,3 @@ def value(self): def __str__(self): return '{0:.2f}'.format(self.value) - -class SignalVocIndex(AbstractSignal): - """Measured VOC Index ticks.""" - - def __init__(self, voc_index_raw): - self._voc_index = voc_index_raw / 10.0 - - @property - def value(self): - return self._voc_index - - def __str__(self): - return '{0:.2f}'.format(self.value) - - -class SignalNoxIndex(AbstractSignal): - """Measured NOx Index ticks.""" - - def __init__(self, nox_index_raw): - self._nox_index = nox_index_raw / 10.0 - - @property - def value(self): - return self._nox_index - - def __str__(self): - return '{0:.2f}'.format(self.value) - diff --git a/sensirion_i2c_sen65/version.py b/sensirion_i2c_sen65/version.py index 338edf5..b42242e 100644 --- a/sensirion_i2c_sen65/version.py +++ b/sensirion_i2c_sen65/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 = "0.1.0" +version: Final[str] = metadata.version("sensirion_i2c_sen65") diff --git a/setup.py b/setup.py index 561f260..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-i2c-driver>=1.0.0,<2.0', - 'sensirion-driver-adapters>=2.1.9,<3.0', - 'sensirion-driver-support-types~=0.2.0', - 'sensirion-shdlc-sensorbridge>=0.1.0,<0.3.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_i2c_sen65/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_i2c_sen65', - version=version_string, - author='Sensirion', - author_email='info@sensirion.com', - description='I2C driver for the Sensirion SEN65 sensor family', - license='BSD', - keywords="""Sensirion SEN65 - I2C - SEN65""", - project_urls={ - "Documentation": "https://sensirion.github.io/python-i2c-sen65", - "Repository": "https://github.com/Sensirion/python-i2c-sen65", - "Changelog": "https://github.com/Sensirion/python-i2c-sen65/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_sen65.py b/tests/test_sen65.py index 612c406..5bf3e60 100644 --- a/tests/test_sen65.py +++ b/tests/test_sen65.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.1.2 +# Generator: sensirion-driver-generator 1.7.0 # Product: sen65 -# Model-Version: 1.3.0 +# Model-Version: 1.4.0 # import pytest @@ -24,6 +24,12 @@ def sensor(channel_provider): yield Sen65Device(channel) +def test_get_product_type1(sensor): + product_type = sensor.get_product_type() + print(f"product_type: {product_type}; " + ) + + def test_get_product_name1(sensor): product_name = sensor.get_product_name() print(f"product_name: {product_name}; " @@ -48,8 +54,24 @@ def test_set_temperature_offset_parameters1(sensor): sensor.set_temperature_offset_parameters(1, 10, 1, 0) -def test_set_voc_algorithm_tuning_parameters1(sensor): - sensor.set_voc_algorithm_tuning_parameters(100, 12, 12, 180, 50, 230) +def test_set_temperature_acceleration_parameters1(sensor): + sensor.set_temperature_acceleration_parameters(1, 1, 1, 1) + + +def test_activate_sht_heater1(sensor): + sensor.activate_sht_heater() + + +def test_read_device_status1(sensor): + device_status = sensor.read_device_status() + print(f"device_status: {device_status}; " + ) + + +def test_read_and_clear_device_status1(sensor): + device_status = sensor.read_and_clear_device_status() + print(f"device_status: {device_status}; " + ) def test_get_voc_algorithm_tuning_parameters1(sensor): @@ -65,8 +87,8 @@ def test_get_voc_algorithm_tuning_parameters1(sensor): ) -def test_set_nox_algorithm_tuning_parameters1(sensor): - sensor.set_nox_algorithm_tuning_parameters(1, 12, 12, 720, 50, 230) +def test_set_voc_algorithm_tuning_parameters1(sensor): + sensor.set_voc_algorithm_tuning_parameters(100, 12, 12, 180, 50, 230) def test_get_nox_algorithm_tuning_parameters1(sensor): @@ -82,8 +104,8 @@ def test_get_nox_algorithm_tuning_parameters1(sensor): ) -def test_set_temperature_acceleration_parameters1(sensor): - sensor.set_temperature_acceleration_parameters(1, 1, 1, 1) +def test_set_nox_algorithm_tuning_parameters1(sensor): + sensor.set_nox_algorithm_tuning_parameters(1, 12, 12, 720, 50, 230) def test_get_voc_algorithm_state1(sensor): @@ -92,22 +114,6 @@ def test_get_voc_algorithm_state1(sensor): ) -def test_activate_sht_heater1(sensor): - sensor.activate_sht_heater() - - -def test_read_device_status1(sensor): - device_status = sensor.read_device_status() - print(f"device_status: {device_status}; " - ) - - -def test_read_and_clear_device_status1(sensor): - device_status = sensor.read_and_clear_device_status() - print(f"device_status: {device_status}; " - ) - - def test_start_continuous_measurement1(sensor): sensor.start_continuous_measurement() (padding, data_ready @@ -165,8 +171,5 @@ def test_start_continuous_measurement1(sensor): f"raw_nox: {raw_nox}; " ) sensor.set_temperature_offset_parameters(1, 10, 1, 0) - state = sensor.get_voc_algorithm_state() - print(f"state: {state}; " - ) sensor.stop_measurement()