adafruit-stemma-detect 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- adafruit_stemma_detect-1.0.0/LICENSE +21 -0
- adafruit_stemma_detect-1.0.0/PKG-INFO +430 -0
- adafruit_stemma_detect-1.0.0/README.rst +398 -0
- adafruit_stemma_detect-1.0.0/adafruit_stemma_detect.egg-info/PKG-INFO +430 -0
- adafruit_stemma_detect-1.0.0/adafruit_stemma_detect.egg-info/SOURCES.txt +156 -0
- adafruit_stemma_detect-1.0.0/adafruit_stemma_detect.egg-info/dependency_links.txt +1 -0
- adafruit_stemma_detect-1.0.0/adafruit_stemma_detect.egg-info/entry_points.txt +2 -0
- adafruit_stemma_detect-1.0.0/adafruit_stemma_detect.egg-info/requires.txt +12 -0
- adafruit_stemma_detect-1.0.0/adafruit_stemma_detect.egg-info/top_level.txt +1 -0
- adafruit_stemma_detect-1.0.0/pyproject.toml +61 -0
- adafruit_stemma_detect-1.0.0/setup.cfg +4 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/__init__.py +49 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/__main__.py +3 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/_version.py +3 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/bus.py +107 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/catalog.py +79 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/__init__.py +1 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/_possible.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/_sensirion.py +41 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/adt7410.py +12 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/adxl34x.py +16 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/adxl37x.py +16 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/ags02ma.py +28 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/ahtx0.py +15 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/am2320.py +32 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/apds9960.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/apds9999.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/as5600.py +21 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/as726x.py +39 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/as7331.py +13 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/as7341.py +12 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/as7343.py +24 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/aw9523.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/bh1750.py +8 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/bme280.py +27 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/bme680.py +27 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/bmp280.py +26 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/bmp3xx.py +45 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/bmp5xx.py +18 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/bno055.py +29 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/bno08x.py +8 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/cap1188.py +17 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/ccs811.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/cst8xx.py +44 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/dps310.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/drv2605.py +26 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/ds3502.py +20 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/ens160.py +12 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/fxas21002c.py +9 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/fxos8700.py +9 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/guvx_i2c.py +9 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/hdc302x.py +28 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/hts221.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/htu21d.py +27 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/htu31d.py +15 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/icm20x.py +19 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/ina219.py +24 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/ina228.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/ina23x.py +23 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/ina260.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/ina3221.py +26 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/l3gd20.py +17 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lc709203f.py +45 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lidarlite.py +28 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lis2mdl.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lis331.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lis3dh.py +12 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lis3mdl.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lps28.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lps2x.py +21 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lps35hw.py +18 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lsm303_accel.py +7 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lsm303dlh_mag.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lsm6ds.py +18 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lsm9ds0.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/lsm9ds1.py +11 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/ltr329_ltr303.py +32 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/ltr390.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/max1704x.py +12 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/max44009.py +16 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mcp3421.py +34 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mcp9600.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mcp9808.py +33 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mlx90393.py +22 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mlx90395.py +15 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mlx90614.py +30 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mlx90632.py +36 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mlx90640.py +16 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mma8451.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mmc56x3.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mpl115a2.py +16 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mpl3115a2.py +9 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mpr121.py +27 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mprls.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/mpu6050.py +13 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/ms8607.py +60 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/msa301.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/opt4048.py +9 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/pa1010d.py +41 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/pcf8591.py +17 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/pct2075.py +25 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/pmsa003i.py +37 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/qmc5883p.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/scd30.py +23 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/scd4x.py +39 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/seesaw.py +48 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/sen6x.py +30 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/sgp30.py +28 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/sgp40.py +40 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/sgp41.py +23 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/sht31d.py +24 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/sht4x.py +25 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/shtc3.py +28 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/si1145.py +12 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/si7021.py +27 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/spa06_003.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/stcc4.py +29 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/sths34pf80.py +9 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/tc74.py +15 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/tcs3430.py +9 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/tcs34725.py +12 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/tlv493d.py +7 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/tmag5273.py +25 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/tmp006.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/tmp007.py +10 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/tmp117.py +12 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/tsc2007.py +20 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/tsl2561.py +15 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/tsl2591.py +12 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/vcnl4010.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/vcnl4020.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/vcnl4030.py +20 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/vcnl4040.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/vcnl4200.py +9 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/veml6070.py +18 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/veml6075.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/veml7700.py +24 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/vl53l0x.py +14 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/vl53l1x.py +15 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/vl53l4cd.py +15 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/chips/vl6180x.py +15 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/cli.py +194 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/installer.py +163 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/mux.py +96 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/result.py +83 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/runtime.py +5 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/scanner.py +335 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/serialization.py +84 -0
- adafruit_stemma_detect-1.0.0/stemma_detect/signature.py +241 -0
- adafruit_stemma_detect-1.0.0/tests/test_bus.py +75 -0
- adafruit_stemma_detect-1.0.0/tests/test_catalog.py +178 -0
- adafruit_stemma_detect-1.0.0/tests/test_cli.py +338 -0
- adafruit_stemma_detect-1.0.0/tests/test_installer.py +145 -0
- adafruit_stemma_detect-1.0.0/tests/test_mux.py +197 -0
- adafruit_stemma_detect-1.0.0/tests/test_probes.py +968 -0
- adafruit_stemma_detect-1.0.0/tests/test_scanner.py +354 -0
- adafruit_stemma_detect-1.0.0/tests/test_serialization.py +109 -0
- adafruit_stemma_detect-1.0.0/tests/test_signature.py +122 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Melissa LeBlanc-Williams for Adafruit Industries
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: adafruit-stemma-detect
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Detect supported Adafruit STEMMA QT sensors and install their CircuitPython drivers
|
|
5
|
+
Author-email: Adafruit Industries <circuitpython@adafruit.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/adafruit/Adafruit_Stemma_Detect
|
|
8
|
+
Project-URL: Documentation, https://docs.circuitpython.org/projects/stemma-detect/en/latest/
|
|
9
|
+
Project-URL: Issues, https://github.com/adafruit/Adafruit_Stemma_Detect/issues
|
|
10
|
+
Project-URL: Source, https://github.com/adafruit/Adafruit_Stemma_Detect
|
|
11
|
+
Keywords: adafruit,blinka,circuitpython,i2c,raspberry-pi,stemma-qt
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Topic :: System :: Hardware
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/x-rst
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: Adafruit-Python-Shell>=1.14.0
|
|
22
|
+
Requires-Dist: smbus2>=0.4
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
25
|
+
Requires-Dist: pre-commit>=4; extra == "dev"
|
|
26
|
+
Requires-Dist: ruff>=0.11; extra == "dev"
|
|
27
|
+
Requires-Dist: twine>=6; extra == "dev"
|
|
28
|
+
Provides-Extra: docs
|
|
29
|
+
Requires-Dist: Sphinx>=7; extra == "docs"
|
|
30
|
+
Requires-Dist: sphinx-rtd-theme>=3; extra == "docs"
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
Introduction
|
|
34
|
+
============
|
|
35
|
+
|
|
36
|
+
.. image:: https://readthedocs.org/projects/adafruit-stemma-detect/badge/?version=latest
|
|
37
|
+
:target: https://docs.circuitpython.org/projects/stemma-detect/en/latest/
|
|
38
|
+
:alt: Documentation Status
|
|
39
|
+
|
|
40
|
+
.. image:: https://img.shields.io/discord/327254708534116352.svg
|
|
41
|
+
:target: https://adafru.it/discord
|
|
42
|
+
:alt: Discord
|
|
43
|
+
|
|
44
|
+
.. image:: https://github.com/adafruit/Adafruit_Stemma_Detect/workflows/Build%20CI/badge.svg
|
|
45
|
+
:target: https://github.com/adafruit/Adafruit_Stemma_Detect/actions
|
|
46
|
+
:alt: Build Status
|
|
47
|
+
|
|
48
|
+
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
|
|
49
|
+
:target: https://github.com/astral-sh/ruff
|
|
50
|
+
:alt: Code Style: Ruff
|
|
51
|
+
|
|
52
|
+
Detect selected Adafruit STEMMA QT sensors on a Raspberry Pi and optionally install their CircuitPython drivers. It recognizes only sensors with bundled probe modules; it is not a universal I²C device identifier.
|
|
53
|
+
|
|
54
|
+
Each sensor definition contains only:
|
|
55
|
+
|
|
56
|
+
- ``ADDRESSES``
|
|
57
|
+
- ``DEFAULT_ADDRESSES`` (optional for configurable-address sensors)
|
|
58
|
+
- ``PACKAGE``
|
|
59
|
+
- ``PROBE_CONFIDENCE``
|
|
60
|
+
- ``PROBE_RISK`` (optional for probes that send multi-byte addresses or commands)
|
|
61
|
+
- ``probe(bus, address)``
|
|
62
|
+
|
|
63
|
+
Definitions may optionally express a device signature with the helpers in
|
|
64
|
+
``stemma_detect.signature``. A signature combines several safe, read-only characteristics, such as
|
|
65
|
+
an exact chip ID, reserved-bit patterns, revision values, and nonblank factory calibration data.
|
|
66
|
+
Checks carry weights so results can expose both a categorical confidence and an evidence score.
|
|
67
|
+
|
|
68
|
+
The scanner uses ``smbus2`` for I²C access and Adafruit Python Shell for prompts and streaming installation commands. Individual CircuitPython drivers are imported neither by the scanner nor by chip definitions.
|
|
69
|
+
|
|
70
|
+
Dependencies
|
|
71
|
+
=============
|
|
72
|
+
This driver depends on:
|
|
73
|
+
|
|
74
|
+
* `Adafruit Python Shell <https://github.com/adafruit/Adafruit_Python_Shell>`_
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
Installing from PyPI
|
|
78
|
+
=====================
|
|
79
|
+
|
|
80
|
+
On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally `from
|
|
81
|
+
PyPI <https://pypi.org/project/adafruit-stemma-detect/>`_. To install for current user:
|
|
82
|
+
|
|
83
|
+
.. code-block:: shell
|
|
84
|
+
|
|
85
|
+
pip3 install adafruit-stemma-detect
|
|
86
|
+
|
|
87
|
+
To install system-wide (this may be required in some cases):
|
|
88
|
+
|
|
89
|
+
.. code-block:: shell
|
|
90
|
+
|
|
91
|
+
sudo pip3 install adafruit-stemma-detect
|
|
92
|
+
|
|
93
|
+
To install in a virtual environment in your current project:
|
|
94
|
+
|
|
95
|
+
.. code-block:: shell
|
|
96
|
+
|
|
97
|
+
mkdir project-name && cd project-name
|
|
98
|
+
python3 -m venv .env
|
|
99
|
+
source .env/bin/activate
|
|
100
|
+
pip3 install adafruit-stemma-detect
|
|
101
|
+
|
|
102
|
+
Running from a checkout
|
|
103
|
+
=======================
|
|
104
|
+
|
|
105
|
+
.. code-block:: shell
|
|
106
|
+
|
|
107
|
+
python3 -m venv --system-site-packages .venv
|
|
108
|
+
.venv/bin/python -m pip install -e .
|
|
109
|
+
.venv/bin/stemma-scan --bus 1
|
|
110
|
+
|
|
111
|
+
Use ``--install`` to install drivers for definitive matches:
|
|
112
|
+
|
|
113
|
+
.. code-block:: shell
|
|
114
|
+
|
|
115
|
+
.venv/bin/stemma-scan --bus 1 --install
|
|
116
|
+
|
|
117
|
+
Address-only or otherwise ambiguous results are reported but not installed.
|
|
118
|
+
|
|
119
|
+
To be prompted before installing a driver for each possible match, use:
|
|
120
|
+
|
|
121
|
+
.. code-block:: shell
|
|
122
|
+
|
|
123
|
+
.venv/bin/stemma-scan --bus 1 --install --prompt-possible-matches
|
|
124
|
+
|
|
125
|
+
Possible matches default to “no.” This is important because several unrelated devices can share the same I²C address.
|
|
126
|
+
|
|
127
|
+
The complete scan finishes before any prompts are shown. Definitive-capable probes run before possible-only probes at each address. A definitive match claims its I²C address immediately, so possible-only candidates are neither probed nor presented. If no definitive probe matches, the possible candidates are collected. A declined candidate is removed from the results; once one is confirmed, it is retained and all remaining candidates at that address are removed without further prompts.
|
|
128
|
+
|
|
129
|
+
Possible candidates using their default address are prompted before candidates using an alternate
|
|
130
|
+
address. The prompt labels the address as default or alternate when that information is known.
|
|
131
|
+
|
|
132
|
+
Multiplexers
|
|
133
|
+
============
|
|
134
|
+
|
|
135
|
+
The scanner automatically looks for PCA9546-compatible four-channel and PCA9548/TCA9548A-compatible
|
|
136
|
+
eight-channel multiplexers at ``0x70`` through ``0x77``. Each channel is scanned separately, and
|
|
137
|
+
the route is included in every result:
|
|
138
|
+
|
|
139
|
+
.. code-block:: text
|
|
140
|
+
|
|
141
|
+
MUX: PCA9546 at 0x70 (4 channels)
|
|
142
|
+
MUX: PCA9546 at 0x71 via mux 0x70 channel 1 (4 channels)
|
|
143
|
+
MATCH: VL53L4CD at 0x29 via mux 0x70 channel 2
|
|
144
|
+
MATCH: VL6180X at 0x29 via mux 0x70 channel 1 via mux 0x71 channel 3
|
|
145
|
+
|
|
146
|
+
No option or CircuitPython multiplexer driver is required. Detection and channel selection use the
|
|
147
|
+
project's small I²C bus interface, so this feature does not add Blinka as a dependency.
|
|
148
|
+
|
|
149
|
+
These multiplexers have no identity register. To reduce false identification, the scanner first
|
|
150
|
+
requires a plausible one-byte control value, then verifies that channel-selection writes read back
|
|
151
|
+
with the expected four- or eight-channel mask. The original control value is restored after probing
|
|
152
|
+
and again after the scan. This is still an active probe: an unrelated device at ``0x70`` through
|
|
153
|
+
``0x77`` with mux-like behavior could be changed.
|
|
154
|
+
|
|
155
|
+
Muxes are discovered recursively to a maximum of eight channel hops. Each nested mux must have an
|
|
156
|
+
address different from every mux upstream of it. Muxes chained with the same address cannot be
|
|
157
|
+
controlled independently because a channel-selection write reaches both devices; change one mux's
|
|
158
|
+
address jumpers before scanning that topology.
|
|
159
|
+
|
|
160
|
+
Using as a library
|
|
161
|
+
==================
|
|
162
|
+
|
|
163
|
+
The high-level ``detect`` function opens a Raspberry Pi I²C bus, scans it and any compatible
|
|
164
|
+
multiplexers, then closes the bus. It returns structured data without printing, prompting, or
|
|
165
|
+
installing drivers:
|
|
166
|
+
|
|
167
|
+
.. code-block:: python
|
|
168
|
+
|
|
169
|
+
from stemma_detect import detect
|
|
170
|
+
|
|
171
|
+
report = detect(bus_number=1)
|
|
172
|
+
|
|
173
|
+
for detection in report.matches:
|
|
174
|
+
print(detection.name, detection.address_hex, detection.driver_package)
|
|
175
|
+
|
|
176
|
+
for detection in report.possible_matches:
|
|
177
|
+
print("Needs confirmation:", detection.name)
|
|
178
|
+
|
|
179
|
+
Applications that already own an I²C connection can pass any object implementing
|
|
180
|
+
``I2CBusProtocol``. The built-in catalog is used automatically:
|
|
181
|
+
|
|
182
|
+
.. code-block:: python
|
|
183
|
+
|
|
184
|
+
from stemma_detect import scan_all
|
|
185
|
+
|
|
186
|
+
report = scan_all(my_i2c_bus)
|
|
187
|
+
|
|
188
|
+
Pass ``chips=discover_chips()`` explicitly only when filtering or extending the catalog. Both
|
|
189
|
+
``detect`` and ``scan_all`` accept ``diagnostic=callback`` for applications that need every probe
|
|
190
|
+
outcome.
|
|
191
|
+
|
|
192
|
+
Installing drivers from a library
|
|
193
|
+
=================================
|
|
194
|
+
|
|
195
|
+
``create_install_plan`` automatically includes definitive matches. Possible matches are excluded
|
|
196
|
+
unless the application confirms them with a callback. A script that knows its expected hardware
|
|
197
|
+
can match the sensor name, address and mux path:
|
|
198
|
+
|
|
199
|
+
.. code-block:: python
|
|
200
|
+
|
|
201
|
+
from stemma_detect import create_install_plan, detect, install_drivers
|
|
202
|
+
|
|
203
|
+
report = detect(1)
|
|
204
|
+
expected = {
|
|
205
|
+
((), 0x48): "pcf8591",
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
def confirm_possible(sensor):
|
|
209
|
+
return expected.get((sensor.path, sensor.address)) == sensor.name
|
|
210
|
+
|
|
211
|
+
plan = create_install_plan(report, confirm_possible=confirm_possible)
|
|
212
|
+
|
|
213
|
+
for item in plan:
|
|
214
|
+
state = "installed" if item.installed_version else "not installed"
|
|
215
|
+
print(item.package, state)
|
|
216
|
+
|
|
217
|
+
results = install_drivers(plan)
|
|
218
|
+
|
|
219
|
+
The callback is called only for possible matches. If it confirms two different candidates at the
|
|
220
|
+
same address and mux path, planning raises ``ValueError`` instead of silently selecting one.
|
|
221
|
+
Packages shared by multiple detected sensors are deduplicated. ``install_drivers`` does not print
|
|
222
|
+
or prompt; it returns an ``InstallResult`` for each package with an ``InstallOutcome`` of
|
|
223
|
+
``INSTALLED``, ``ALREADY_INSTALLED`` or ``FAILED``.
|
|
224
|
+
|
|
225
|
+
JSON output
|
|
226
|
+
===========
|
|
227
|
+
|
|
228
|
+
Use ``--json`` to write one machine-readable document to standard output. It contains the bus,
|
|
229
|
+
multiplexer topology, detections, confidence, signature evidence and scores, and CircuitPython
|
|
230
|
+
driver installation status. Both integer and hexadecimal forms of each I²C address are included:
|
|
231
|
+
|
|
232
|
+
.. code-block:: shell
|
|
233
|
+
|
|
234
|
+
.venv/bin/stemma-scan --bus 1 --json
|
|
235
|
+
.venv/bin/stemma-scan --bus 1 --json > stemma-scan.json
|
|
236
|
+
|
|
237
|
+
The top-level ``schema_version`` is incremented if a future release makes an incompatible output
|
|
238
|
+
change. JSON mode cannot be combined with ``--install`` or ``--diagnostics`` because prompts,
|
|
239
|
+
installation progress, and transaction traces would make standard output invalid JSON.
|
|
240
|
+
|
|
241
|
+
Library users can serialize an existing report without running another scan:
|
|
242
|
+
|
|
243
|
+
.. code-block:: python
|
|
244
|
+
|
|
245
|
+
data = report.to_dict(bus=1)
|
|
246
|
+
text = report.to_json(bus=1)
|
|
247
|
+
|
|
248
|
+
The existing ``report_to_dict`` and ``report_to_json`` functions remain available for functional
|
|
249
|
+
style code.
|
|
250
|
+
|
|
251
|
+
Diagnostics
|
|
252
|
+
===========
|
|
253
|
+
|
|
254
|
+
Use ``--diagnostics`` to show every probe attempted, including its safety category, non-matches,
|
|
255
|
+
and I²C errors that are hidden during a normal scan:
|
|
256
|
+
|
|
257
|
+
.. code-block:: shell
|
|
258
|
+
|
|
259
|
+
.venv/bin/stemma-scan --bus 1 --diagnostics
|
|
260
|
+
|
|
261
|
+
An address that does not acknowledge an I²C transaction is reported as ``NOT DETECTED``. The
|
|
262
|
+
``ERROR`` label is reserved for unexpected failures. Successful transactions include their raw
|
|
263
|
+
write and read bytes so new or mismatched identity probes can be investigated without changing the
|
|
264
|
+
chip module.
|
|
265
|
+
|
|
266
|
+
Definitive probes run before possible-only probes at each address. Within each category, probes are
|
|
267
|
+
ordered from lowest to highest risk: passive reads, ordinary one-byte register reads, then commands
|
|
268
|
+
or multi-byte register addressing. A definitive match prevents all remaining probes from touching
|
|
269
|
+
that address. When only possible matches remain, candidates with more weighted signature evidence
|
|
270
|
+
are reported and prompted first; a factory-default address adds a small score bonus.
|
|
271
|
+
|
|
272
|
+
Known limitations and planned work
|
|
273
|
+
==================================
|
|
274
|
+
|
|
275
|
+
The CLI is a consumer of the same detection API available to other programs. Library imports do not
|
|
276
|
+
scan hardware, print, prompt, install packages, or exit the process as a side effect. Diagnostics
|
|
277
|
+
and driver installation remain explicit opt-in operations.
|
|
278
|
+
|
|
279
|
+
The scanner cannot resolve two devices responding at the same address. They may corrupt each
|
|
280
|
+
other's identity responses and produce only ambiguous possible matches. Conflicting devices must be
|
|
281
|
+
readdressed or placed on separate multiplexer channels. Automatic mux scanning resolves conflicts
|
|
282
|
+
between different channels, but it cannot resolve a conflict between a root-bus device and a device
|
|
283
|
+
behind a currently selected mux channel.
|
|
284
|
+
|
|
285
|
+
Adafruit's `Troublesome Chips guide
|
|
286
|
+
<https://learn.adafruit.com/i2c-addresses/troublesome-chips>`_ identifies devices with unusual I²C
|
|
287
|
+
behavior that can cause missed detections or communication failures:
|
|
288
|
+
|
|
289
|
+
- AGS02MA requires a 20--30 kHz bus.
|
|
290
|
+
- AM2320 automatically sleeps, making scans unreliable.
|
|
291
|
+
- ATECCx08 requires slow I²C communication when waking from sleep.
|
|
292
|
+
- BNO055 and BNO085 use clock stretching, can violate timing requirements, and may need resets.
|
|
293
|
+
- CCS811 uses clock stretching.
|
|
294
|
+
- LC709203F uses repeated starts, clock stretching, and sleep mode.
|
|
295
|
+
- Older MCP9600 devices can duplicate register data; MCP9600 and MCP9601 also use repeated starts
|
|
296
|
+
and clock stretching and may ignore zero-length scan writes.
|
|
297
|
+
- PN532 uses clock stretching.
|
|
298
|
+
|
|
299
|
+
The current catalog includes AGS02MA, AM2320, BNO055, BNO08x/BNO085, CCS811, LC709203F, and
|
|
300
|
+
MCP9600. A failed probe for one of these chips does not necessarily mean the device is absent.
|
|
301
|
+
Raspberry Pi users should also consult Adafruit's `I²C clock stretching guide
|
|
302
|
+
<https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/i2c-clock-stretching>`_.
|
|
303
|
+
|
|
304
|
+
Supported sensors so far
|
|
305
|
+
========================
|
|
306
|
+
|
|
307
|
+
The catalog currently contains 122 device definitions: 93 with definitive-capable probes and 29 that
|
|
308
|
+
produce possible matches. Possible matches are never installed without
|
|
309
|
+
``--prompt-possible-matches`` and user confirmation.
|
|
310
|
+
|
|
311
|
+
Devices with definitive probes include ADT7410, AGS02MA, AM2320, APDS9960, APDS9999, AS726x,
|
|
312
|
+
AS7331, AS7341, AS7343, AW9523, BME280, BME680, BMP280, BMP3xx, BMP5xx, BNO055, CAP1188, CCS811,
|
|
313
|
+
CST8xx, DPS310, DRV2605/DRV2605L, ENS160,
|
|
314
|
+
FXAS21002C, FXOS8700, GUVX I2C, HDC302x, HTS221, HTU21D, ICM20x, INA228,
|
|
315
|
+
INA237/INA238, INA260, INA3221, LC709203F, LIS2MDL, LIS331, LIS3DH, LIS3MDL, LPS2x,
|
|
316
|
+
LPS28, L3GD20, LSM303DLH magnetometer, LSM6DS, LSM9DS0, LSM9DS1, LTR329/LTR303,
|
|
317
|
+
LTR390, MAX1704x, MCP9600, MCP9808, MLX90614, MLX90632, MMA8451, MMC5603,
|
|
318
|
+
MPL3115A2, MPU6050, MS8607, MSA301, OPT4048, PA1010D, PMSA003I, QMC5883P, SCD30, SCD4x, SEN6x,
|
|
319
|
+
Seesaw, SGP30, SGP40, SGP41, SHT31D, SHT4x, SHTC3, SI1145, Si7021, SPA06-003, STCC4,
|
|
320
|
+
STHS34PF80, TCS3430, TCS34725, TMAG5273, TMP006, TMP007, TMP117/TMP119, TSL2561,
|
|
321
|
+
TSL2591, VCNL4030, VCNL4040, VCNL4200, VEML6075, VL53L0X, VL53L1X, VL53L4CD,
|
|
322
|
+
and VL6180X.
|
|
323
|
+
|
|
324
|
+
Possible-match definitions include ADXL34x, ADXL37x, AHTx0, AS5600, BH1750, BNO08x,
|
|
325
|
+
DS3502, HTU31D, INA219, LIDAR-Lite, LPS35HW, LSM303 accelerometer,
|
|
326
|
+
MAX44009, MCP3421, MLX90393, MLX90395, MLX90640, MPL115A2, MPR121, MPRLS,
|
|
327
|
+
PCF8591, PCT2075, TC74, TLV493D, TSC2007, VCNL4010, VCNL4020, VEML6070,
|
|
328
|
+
and VEML7700.
|
|
329
|
+
|
|
330
|
+
Adding a sensor
|
|
331
|
+
===============
|
|
332
|
+
|
|
333
|
+
Add one module under ``stemma_detect/chips/``. Modules are discovered automatically, so no registry edit is needed.
|
|
334
|
+
Use one module per installable driver family: chips that cannot be distinguished but use the same
|
|
335
|
+
CircuitPython package should share a family definition and produce one detection. The catalog
|
|
336
|
+
requires package names to be unique. Keep separate definitions when ambiguity changes which driver
|
|
337
|
+
would be installed.
|
|
338
|
+
|
|
339
|
+
.. code-block:: python
|
|
340
|
+
|
|
341
|
+
from stemma_detect.result import Confidence, ProbeResult, ProbeRisk
|
|
342
|
+
|
|
343
|
+
ADDRESSES = (0x44,)
|
|
344
|
+
DEFAULT_ADDRESSES = (0x44,) # Optional; single addresses are defaults automatically.
|
|
345
|
+
PACKAGE = "adafruit-circuitpython-example"
|
|
346
|
+
PROBE_CONFIDENCE = Confidence.MATCH
|
|
347
|
+
PROBE_RISK = ProbeRisk.COMMAND # Only for commands or multi-byte addresses.
|
|
348
|
+
|
|
349
|
+
def probe(bus, address):
|
|
350
|
+
value = bus.read_register(address, 0x00, 1)
|
|
351
|
+
if value == b"\x12":
|
|
352
|
+
return ProbeResult.match({"id": value.hex()})
|
|
353
|
+
return ProbeResult.no_match()
|
|
354
|
+
|
|
355
|
+
Keep probes short, non-destructive, and independent of the package they are intended to install.
|
|
356
|
+
Most identity-register probes should omit ``PROBE_RISK`` and use the default register category.
|
|
357
|
+
Address-only definitions automatically use the passive category. Set ``ProbeRisk.COMMAND`` when a
|
|
358
|
+
probe transmits a command or a multi-byte register address that another chip could interpret as a
|
|
359
|
+
write.
|
|
360
|
+
Family probes may pass ``name`` to ``ProbeResult.match()`` when an identity register distinguishes a
|
|
361
|
+
specific chip. Ambiguous IDs should remain at the family level.
|
|
362
|
+
|
|
363
|
+
When a sensor has several useful read-only registers or safe identity commands, prefer a device
|
|
364
|
+
signature over custom probe logic. ``command_response`` supports CRC-protected serial-number and
|
|
365
|
+
feature-set commands while using the same weights and result handling as register checks.
|
|
366
|
+
|
|
367
|
+
.. code-block:: python
|
|
368
|
+
|
|
369
|
+
from stemma_detect.result import Confidence
|
|
370
|
+
from stemma_detect.signature import DeviceSignature, exact, not_blank
|
|
371
|
+
|
|
372
|
+
ADDRESSES = (0x76, 0x77)
|
|
373
|
+
PACKAGE = "adafruit-circuitpython-example"
|
|
374
|
+
PROBE_CONFIDENCE = Confidence.MATCH
|
|
375
|
+
|
|
376
|
+
SIGNATURE = DeviceSignature(
|
|
377
|
+
(
|
|
378
|
+
exact("chip_id", 0xD0, b"\x60", show_value=True, weight=10),
|
|
379
|
+
exact(
|
|
380
|
+
"status_reserved",
|
|
381
|
+
0xF3,
|
|
382
|
+
b"\x00",
|
|
383
|
+
mask=b"\xF6",
|
|
384
|
+
required=False,
|
|
385
|
+
weight=2,
|
|
386
|
+
),
|
|
387
|
+
not_blank("calibration", 0x88, 24, required=False, weight=3),
|
|
388
|
+
),
|
|
389
|
+
match_threshold=15,
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
def probe(bus, address):
|
|
393
|
+
return SIGNATURE.probe(bus, address)
|
|
394
|
+
|
|
395
|
+
Failure of a required check produces ``NO_MATCH``. Supporting checks contribute weight; missing
|
|
396
|
+
supporting evidence lowers the score and may reduce the result to ``POSSIBLE`` without rejecting it.
|
|
397
|
+
The scanner adds one weak point for a known default address but never lets that address bonus turn a
|
|
398
|
+
possible result into a definitive match. Only definitive ``MATCH`` results are installed
|
|
399
|
+
automatically.
|
|
400
|
+
|
|
401
|
+
Scores represent accumulated evidence, not a statistical probability. Weights should be kept
|
|
402
|
+
consistent across definitions: exact identity registers should dominate, while address responses
|
|
403
|
+
and default-address bonuses should remain weak evidence.
|
|
404
|
+
|
|
405
|
+
Only use documented, safe reads: avoid FIFO, read-to-clear, write-only, initialization, reset, and
|
|
406
|
+
measurement commands. Identity and serial-number commands are suitable when their datasheet says
|
|
407
|
+
they do not alter sensor state. Mark command-based probes as ``ProbeRisk.COMMAND``.
|
|
408
|
+
``not_blank`` is intended for factory-programmed blocks where all-zero and all-``0xFF`` data are
|
|
409
|
+
invalid; it should not be used for ordinary configuration or measurement registers.
|
|
410
|
+
|
|
411
|
+
Development
|
|
412
|
+
===========
|
|
413
|
+
|
|
414
|
+
.. code-block:: shell
|
|
415
|
+
|
|
416
|
+
python3 -m unittest discover -s tests -v
|
|
417
|
+
ruff check .
|
|
418
|
+
ruff format --check .
|
|
419
|
+
|
|
420
|
+
Contributing
|
|
421
|
+
============
|
|
422
|
+
|
|
423
|
+
Contributions are welcome! Please read our `Code of Conduct
|
|
424
|
+
<https://github.com/adafruit/Adafruit_Stemma_Detect/blob/main/CODE_OF_CONDUCT.md>`_
|
|
425
|
+
before contributing to help this project stay welcoming
|
|
426
|
+
|
|
427
|
+
License
|
|
428
|
+
=======
|
|
429
|
+
|
|
430
|
+
MIT, see `LICENSE <LICENSE>`_.
|