From bd71832311fc43e30bcb5131637152b9cda12396 Mon Sep 17 00:00:00 2001 From: Liron Date: Sun, 19 Jul 2026 13:52:32 +0300 Subject: [PATCH 1/9] Add PyPI version badge to the README. Co-authored-by: Cursor --- Readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Readme.md b/Readme.md index 7000386..0d50e1f 100644 --- a/Readme.md +++ b/Readme.md @@ -1,5 +1,7 @@ ## TapStrap Python SDK (beta) +[![PyPI version](https://img.shields.io/pypi/v/tap-python-sdk.svg)](https://pypi.org/project/tap-python-sdk/) + ### What Is This ? TAP python SDK allows you to build python app that can establish BLE connection with Tap Strap and TapXR, send commands and receive events and data - Thus allowing TAP to act as a controller for your app! From 6f7e60c2ab9480f3d7196aeee657123ee8b98e5e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 17:14:13 +0000 Subject: [PATCH 2/9] =?UTF-8?q?Document=20the=20SDK=20using=20Di=C3=A1taxi?= =?UTF-8?q?s=20structure=20(#42)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add docs/ with tutorial, how-to guides, reference, and explanation; slim the README to an overview that links into those sections; and add docstrings on the public API so reference and source stay aligned. Co-authored-by: Liron Ilouz --- Readme.md | 277 +++------------------------ docs/explanation/connection-model.md | 24 +++ docs/explanation/index.md | 9 + docs/explanation/input-modes.md | 14 ++ docs/explanation/raw-sensors.md | 29 +++ docs/how-to/connect-and-listen.md | 66 +++++++ docs/how-to/index.md | 13 ++ docs/how-to/install.md | 49 +++++ docs/how-to/migrate-from-0.6.md | 42 ++++ docs/how-to/send-haptics.md | 21 ++ docs/how-to/stream-raw-sensors.md | 45 +++++ docs/how-to/switch-input-modes.md | 36 ++++ docs/how-to/use-spatial-control.md | 33 ++++ docs/index.md | 21 ++ docs/reference/enumerations.md | 76 ++++++++ docs/reference/events.md | 70 +++++++ docs/reference/index.md | 11 ++ docs/reference/input-modes.md | 56 ++++++ docs/reference/package.md | 38 ++++ docs/reference/tapsdk.md | 82 ++++++++ docs/tutorial/getting-started.md | 88 +++++++++ tapsdk/__init__.py | 6 + tapsdk/enumerations.py | 12 ++ tapsdk/inputmodes.py | 23 +++ tapsdk/parsers.py | 40 ++-- tapsdk/tap.py | 47 +++++ 26 files changed, 966 insertions(+), 262 deletions(-) create mode 100644 docs/explanation/connection-model.md create mode 100644 docs/explanation/index.md create mode 100644 docs/explanation/input-modes.md create mode 100644 docs/explanation/raw-sensors.md create mode 100644 docs/how-to/connect-and-listen.md create mode 100644 docs/how-to/index.md create mode 100644 docs/how-to/install.md create mode 100644 docs/how-to/migrate-from-0.6.md create mode 100644 docs/how-to/send-haptics.md create mode 100644 docs/how-to/stream-raw-sensors.md create mode 100644 docs/how-to/switch-input-modes.md create mode 100644 docs/how-to/use-spatial-control.md create mode 100644 docs/index.md create mode 100644 docs/reference/enumerations.md create mode 100644 docs/reference/events.md create mode 100644 docs/reference/index.md create mode 100644 docs/reference/input-modes.md create mode 100644 docs/reference/package.md create mode 100644 docs/reference/tapsdk.md create mode 100644 docs/tutorial/getting-started.md diff --git a/Readme.md b/Readme.md index 0d50e1f..c7f113a 100644 --- a/Readme.md +++ b/Readme.md @@ -2,284 +2,67 @@ [![PyPI version](https://img.shields.io/pypi/v/tap-python-sdk.svg)](https://pypi.org/project/tap-python-sdk/) -### What Is This ? +BLE SDK for building Python apps that connect to **Tap Strap** and **TapXR**, send commands, and receive tap, mouse, air-gesture, and raw sensor events. -TAP python SDK allows you to build python app that can establish BLE connection with Tap Strap and TapXR, send commands and receive events and data - Thus allowing TAP to act as a controller for your app! -The library is developed with Python >= 3.9 and is **currently in beta**. +**Python ≥ 3.9** · **macOS / Windows / Linux** · **currently in beta** +### Documentation -### Supported Platforms -This package supports the following platforms: -* MacOS (tested on 10.15.2) - using Apple's CoreBluetooth library. The library depends on PyObjC which Apple includes with their Python version on OSX. Note that if you're using a different Python, be sure to install PyObjC for that version of Python. -* Windows 10 - using [Bleak](https://github.com/hbldh/bleak) with WinRT for BLE connectivity (no external DLL required). -* Linux (tested on Ubuntu 18.04) - need to install libbluetooth-dev and bluez-tools - ``` - sudo apt-get install bluez-tools libbluetooth-dev - ``` - also the user needs to be in the bluetooth group: - ``` - sudo usermod -G bluetooth -a - #and can reload groups in this shell by running the following command or by logging out and back in: - su - $USER - ``` +Docs follow [Diátaxis](https://diataxis.fr/) — pick the path that matches your goal: +| I want to… | Go to | +|------------|--------| +| Get a first working connection | [Tutorial: Getting started](docs/tutorial/getting-started.md) | +| Solve a specific task | [How-to guides](docs/how-to/index.md) | +| Look up APIs and types | [Reference](docs/reference/index.md) | +| Understand modes and sensors | [Explanation](docs/explanation/index.md) | -### Installation +Full index: [docs/index.md](docs/index.md) -Install the package from PyPI: -```console -pip install tap-python-sdk -``` +### Install -Or clone this repo and install the package locally: ```console -git clone https://github.com/TapWithUs/tap-python-sdk -cd tap-python-sdk -pip install . +pip install tap-python-sdk ``` +Platform notes (BlueZ on Linux, Bleak pins, pairing): [Install the SDK](docs/how-to/install.md). -The SDK is asyncio-based. Pair your Tap device with the OS first, then connect and register callbacks inside an async entry point: +### Quick example ```python import asyncio -from tapsdk import TapSDK +from tapsdk import TapSDK, InputModeController async def main(): - tap_device = TapSDK() - tap_device.register_tap_events(lambda identifier, tapcode: print(identifier, tapcode)) - await tap_device.run() # connects to a paired Tap, or scans until one is found + tap = TapSDK() + tap.register_tap_events(lambda identifier, tapcode: print(identifier, tapcode)) + await tap.run() + await tap.set_input_mode(InputModeController()) + await asyncio.Event().wait() asyncio.run(main()) ``` -If no Tap is already connected at the OS level, `run()` will scan and wait for a device. On Windows and MacOS it also polls for already-paired devices that reconnect without advertising. - -Also make sure that you have updated your Tap device to the latest version. - -### Features - -This SDK implements two basic interfaces with a Tap device. - -First is setting the operation mode: - -1. *Text mode* - the Tap device will operate normally, with no events being sent to the SDK -2. *Controller mode* - the Tap device will send events to the SDK -3. *Controller and Text mode* - the Tap device will operate normally, in parallel with sending events to the SDK -4. *Raw data mode* - the Tap device will stream raw sensors data to the SDK. - -Second, subscribing to the following events: - -1. *Tap event* - whenever a tap event has occurred -2. *Mouse event* - whenever a mouse movement has occurred -3. *AirGesture event* - whenever one of the gestures is detected -4. *Raw data* - whenever new raw data sample is being made. - -Additional to these functional events, there are also some state events, such as connection and disconnection of Tap devices to the SDK backend. - -#### Spatial Control - NEW -Authorized developers can gain access to the experimental Spatial Control features: -1. Extended AirGesture state - enabling aggregation for pinch, drag and swipe gestures. -2. Select input type - enabling the selection of input type to be activated - i.e. AirMouse/Tapping. - -These features are only available on TapXR and only for qualified developers. Request access [here](https://www.tapwithus.com/contact-us/) - - -### Migration from 0.6.x - -If you are upgrading from an earlier release, note these breaking changes: - -* `TapInputMode("controller")` → `InputModeController()` (and similarly for other modes). Import from `tapsdk`. -* `TapInputMode("raw", sensitivity=[2, 1, 4])` → `InputModeRaw(finger_accl_sens=..., imu_gyro_sens=..., imu_accl_sens=...)`. Use the typed enums in `tapsdk.enumerations`. -* `from tapsdk.models import AirGestures` → `from tapsdk import AirGestures` -* The `loop=` constructor argument has been removed. -* Event registration (`register_*`) is synchronous; call it before `await tap_device.run()`. -* Commands (`set_input_mode`, `set_input_type`, `send_vibration_sequence`) are async and must be awaited. -* OS-specific examples (`example_unix.py`, `example_win.py`) have been replaced by a single cross-platform `examples/basic.py`. - - -### High level API -The SDK uses callbacks to implement user functions on the various events. To register a callback, you just have to instance a TapSDK object and: - -```python -def on_tap_event(identifier, tapcode): - print(identifier + " tapped " + str(tapcode)) - -tap_device.register_tap_events(on_tap_event) -``` -#### Commands list -1. ```set_input_mode(self, input_mode:InputMode, identifier=None):``` -This function sends a mode selection command. It accepts an object of type ```InputMode``` such as ```InputModeText```, ```InputModeController```, ```InputModeControllerText```, or ```InputModeRaw```. -For example: - ```python - from tapsdk import InputModeController - await tap_device.set_input_mode(InputModeController()) - ``` - For raw sensors mode, you can specify sensitivity and scaling: - ```python - from tapsdk import InputModeRaw - from tapsdk.enumerations import FingerAcclSensitivity, ImuGyroSensitivity, ImuAcclSensitivity - await tap_device.set_input_mode(InputModeRaw( - scaled=True, - finger_accl_sens=FingerAcclSensitivity.G4, - imu_gyro_sens=ImuGyroSensitivity.DPS250, - imu_accl_sens=ImuAcclSensitivity.G4 - )) - ``` -2. ```set_input_type(self, input_type:InputType, identifier=None):``` - > **Only for TapXR and with Spatial Control experimental firmware** - - This function sends a command to force input type. It accepts an enum of type ```InputType``` initialized with any of the types ```InputType.MOUSE```, ```InputType.KEYBOARD```, or ```InputType.AUTO```. - For example: - ```python - from tapsdk import InputType - await tap_device.set_input_type(InputType.AUTO) - ``` - This will set the input to be automatically selected by the Tap device, based on hand posture. - -3. ```send_vibration_sequence(self, sequence:list, identifier=None):``` -This function sends a series of haptic activations. ```sequence``` is a list of integers indicating the activation and delay periods one after another. The periods are in millisecond units, in the range of [10,2550] and in resolution of 10ms. Each haptic command supports up to 18 period definitions (i.e. 9 haptics + delay pairs). -For example: - ```python - await tap_device.send_vibration_sequence(sequence=[1000,300,200]) - ``` - will trigger a 1s haptic, followed by 300ms delay, followed by 200ms haptic. - - -#### Events list -1. ```register_connection_events(self, listener:Callable):``` -Register callback to a Tap strap connection event. - ```python - def on_connect(tap_sdk_instance): - print("Connected to Tap device") - - tap_device.register_connection_events(on_connect) - ``` - -2. ```register_disconnection_events(self, listener:Callable):``` -Register callback to a Tap strap disconnection event. - ```python - def on_disconnect(client): - print("Tap device disconnected") +Pair the Tap with the OS first. Update firmware with Tap Manager. More complete flow: [`examples/basic.py`](examples/basic.py). - tap_device.register_disconnection_events(on_disconnect) - ``` +### Features (summary) -3. ```register_tap_events(self, listener:Callable):``` -Register callback to a tap event. - ```python - def on_tap_event(identifier, tapcode): - print(identifier + " - tapped " + str(tapcode)) +- **Modes:** Text, Controller, Controller+Text, Raw sensors +- **Events:** tap, mouse, air gesture, air-gesture state, raw packets, connect/disconnect +- **Commands:** set mode, set Spatial Control input type (TapXR), haptic sequences +- **Spatial Control** (authorized TapXR builds): see [Use Spatial Control](docs/how-to/use-spatial-control.md) - tap_device.register_tap_events(on_tap_event) - ``` - ```tapcode``` is an 8-bit unsigned number, between 1 and 31 which is formed by a binary representation of the fingers that are tapped. -The LSb is thumb finger, the MSb is the pinky finger. -For example: if combination equals 5 - its binary form is 10100 - means that the thumb and the middle fingers were tapped. +### Migrating from 0.6.x - -4. ```register_mouse_events(self, listener:Callable):``` -Register callback to a mouse or air mouse movement event. - ```python - def on_mouse_event(identifier, vx, vy, proximity): - print(identifier + " - moused: %d, %d" %(vx, vy)) - - tap_device.register_mouse_events(on_mouse_event) - ``` - ```vx``` and ```vy``` are the horizontal and vertical velocities of the mouse movement respectively. -```proximity``` is a boolean that indicates proximity with a surface. -5. ```register_raw_data_events(self, listener:Callable):``` -Register callback to raw sensors data packet received event. - ```python - def on_raw_sensor_data(identifier, packets): - for packet in packets: - print(identifier, packet["type"], packet["ts"], packet["payload"]) - - tap_device.register_raw_data_events(on_raw_sensor_data) - ``` - The callback receives a list of dicts, each with keys `type` (`"imu"` or `"accl"`), `ts` (millisecond timestamp), and `payload` (list of sample values). When `InputModeRaw(scaled=True)` is active, values are in mg and mdps. - You'll find more information on that mode in the dedicated section below or [here](https://tapwithus.atlassian.net/wiki/spaces/TD/pages/792002574/Tap+Strap+Raw+Sensors+Mode). - -6. ```register_air_gesture_events(self, listener:Callable):``` -Register callback to air gesture events. - ```python - from tapsdk import AirGestures - - def on_airgesture(identifier, gesture): - print(identifier + " - gesture: " + str(AirGestures(gesture))) - - tap_device.register_air_gesture_events(on_airgesture) - ``` - ```gesture``` is an integer code of the air gesture detected. The air gesture values are enumerated in the ```AirGestures``` class, including directional gestures (`UP_ONE_FINGER`, `PINCH`, etc.), thumb gestures (`THUMB_FINGER`, `THUMB_MIDDLE`), and spatial state gestures (`STATE_OPEN`, `STATE_FIST`, etc.). - -7. ```register_air_gesture_state_events(self, listener:Callable):``` -Register callback to mouse-mode state changes (e.g. air mouse, optical mouse). - ```python - from tapsdk.enumerations import MouseModes - - def on_mouse_mode_change(identifier, mouse_mode): - print(identifier + " - mode: " + str(mouse_mode)) - - tap_device.register_air_gesture_state_events(on_mouse_mode_change) - ``` - ```mouse_mode``` is a ```MouseModes``` enum value: `STDBY`, `AIR_MOUSE`, `OPTICAL1`, or `OPTICAL2`. - -### Raw sensors mode - -**Make sure that "Developer mode" is enabled on TapManager app for this mode to work properly** - -In raw sensors mode, the Tap device continuously sends raw data from the following sensors: -1. Five 3-axis accelerometers - one per each finger (**available only on TAP Strap and Tap Strap 2**). - * sampled at 200Hz - * allows dynamic range configuration (±2G, ±4G, ±8G, ±16G) -2. IMU (3-axis accelerometer + gyro) located on the thumb (**available on TAP Strap 2 and TapXR**). - * sampled at 208Hz. - * allows dynamic range configuration for the accelerometer (±2G, ±4G, ±8G, ±16G) and for the gyro (±125dps, ±250dps, ±500dps, ±1000dps, ±2000dps). - -The sensors measurements are given with respect to the reference system below. - -![alt text](TAP-axis-alpha.png "Tap Strap reference frame") -![alt text](TAPXR-axis.png "TapXR reference frame") - -Each sample (of accelerometer or imu) is preambled with a millisecond timestamp, referenced to an internal Tap clock. - - -The dynamic range of the sensors is determined with the ```set_input_mode``` method by passing an ```InputModeRaw``` instance with the desired sensitivity enums, and a boolean flag indicating if the data should be scaled to mg and mdps for the accelerometer and gyro respectively: -```python -from tapsdk import InputModeRaw -from tapsdk.enumerations import FingerAcclSensitivity, ImuGyroSensitivity, ImuAcclSensitivity - -await tap_device.set_input_mode(InputModeRaw( - scaled=True, - finger_accl_sens=FingerAcclSensitivity.G4, - imu_gyro_sens=ImuGyroSensitivity.DPS250, - imu_accl_sens=ImuAcclSensitivity.G4 -)) -``` -Refer to `FingerAcclSensitivity`, `ImuGyroSensitivity`, and `ImuAcclSensitivity` in [`tapsdk.enumerations`](tapsdk/enumerations.py) for the available sensitivity values. - -### Examples - -You can find some examples in the [examples folder](examples). +Breaking API changes are listed in [Migrate from 0.6](docs/how-to/migrate-from-0.6.md) and [History.md](History.md). ### Testing -To run the tests, first install the development dependencies: - ```bash pip install .[dev] -``` - -Then run the tests using pytest: - -```bash pytest ``` - -### Known Issues -See [History.md](History.md) for release notes. No known issues at 0.7.0. - ### Support -Please refer to the issues tab! :) +Use the [GitHub issues](https://github.com/TapWithUs/tap-python-sdk/issues) tab. diff --git a/docs/explanation/connection-model.md b/docs/explanation/connection-model.md new file mode 100644 index 0000000..15d8e6f --- /dev/null +++ b/docs/explanation/connection-model.md @@ -0,0 +1,24 @@ +# Connection model + +The Tap is a Bluetooth Low Energy peripheral. This SDK does not use HID for app control; it opens a GATT session with Bleak and talks to Tap’s proprietary service plus a Nordic UART-style service for mode commands and raw data. + +## Why pair with the OS first + +On every platform the most reliable path is: pair in system Bluetooth settings, ensure the device is connected (or connectable), then call `TapSDK.run()`. The SDK then attaches to that session instead of racing a cold advertisement scan. + +Platform differences matter: + +- **macOS** retrieves already-connected peripherals that expose the Tap service. +- **Windows** uses WinRT to find connected Tap devices and opens a GATT session without Bleak’s normal connect wait (which can hang if the session is already active). If nothing is connected, it scans and also polls for paired reconnects that do not advertise. +- **Linux** lists BlueZ devices with `bt-device` and connects to names starting with `Tap`. + +## Single device today + +Method signatures accept an `identifier` argument on commands, but the SDK currently drives one `TapClient` at a time. Multi-device support is a separate concern from documentation of the present API. + +## Notifications vs commands + +- **Commands** (mode, input type, haptics) are GATT writes. +- **Events** (tap, mouse, air gesture, raw) are GATT notifications parsed into callback arguments. + +After you set a mode, a background refresh task rewrites mode and input type periodically so a flaky link is less likely to leave the device in the wrong state. diff --git a/docs/explanation/index.md b/docs/explanation/index.md new file mode 100644 index 0000000..dca09fe --- /dev/null +++ b/docs/explanation/index.md @@ -0,0 +1,9 @@ +# Explanation + +Understanding-oriented background. For steps, use the [tutorial](../tutorial/getting-started.md) or [how-to guides](../how-to/index.md). + +| Topic | Page | +|-------|------| +| How the SDK talks to Tap over BLE | [Connection model](connection-model.md) | +| Why input modes exist | [Input modes](input-modes.md) | +| Raw sensors, frames, and scaling | [Raw sensors](raw-sensors.md) | diff --git a/docs/explanation/input-modes.md b/docs/explanation/input-modes.md new file mode 100644 index 0000000..12c25f8 --- /dev/null +++ b/docs/explanation/input-modes.md @@ -0,0 +1,14 @@ +# Input modes + +Tap hardware always has a “personality” toward the host: it can act as a keyboard/mouse for the operating system, stream structured controller events to an app, stream raw IMU data, or combine some of these. + +The SDK models that personality as **input modes**: + +- **Text** — OS-facing HID behavior; your Python callbacks stay quiet for taps. +- **Controller** — events are for your app; classic typing to the OS is not the goal. +- **Controller + Text** — parallel paths when users still need to type. +- **Raw** — bypass gesture interpretation and ship sensor samples. + +Modes are orthogonal to **Spatial Control input type** (mouse vs keyboard vs auto) on TapXR. Mode answers “who receives data and in what form?”; input type answers “which XR input modality is forced?” when you have experimental firmware access. + +Switching modes is a small binary command on the NUS RX characteristic. The SDK owns the byte layout so applications work with typed classes instead of magic numbers. diff --git a/docs/explanation/raw-sensors.md b/docs/explanation/raw-sensors.md new file mode 100644 index 0000000..a96bd3a --- /dev/null +++ b/docs/explanation/raw-sensors.md @@ -0,0 +1,29 @@ +# Raw sensors + +Raw mode exposes the motion sensors behind Tap’s gesture pipeline. That is useful for research, custom gesture models, and XR prototypes — not for everyday typing. + +## What is streamed + +1. **Finger accelerometers** (Tap Strap / Tap Strap 2): one 3-axis sensor per finger, ~200 Hz, configurable ±2/4/8/16 g. +2. **Thumb IMU** (Tap Strap 2 / TapXR): accelerometer + gyro, ~208 Hz, configurable accelerometer and gyro ranges. + +Samples are timestamped in milliseconds on an internal device clock. Timestamps are not synchronized to wall time by the SDK. + +## Scaling + +Firmware sends integer LSB counts. `InputModeRaw(scaled=True)` multiplies by the scale factors that belong to the selected sensitivity enums, yielding **mg** (accelerometer) and **mdps** (gyro). If you scale yourself, keep `scaled=False` and use `RawSensorsSensitivity.get_scale_factors()`. + +You cannot change sensitivity while remaining in raw mode with a different command; leave raw mode, then re-enter with new enums. + +## Reference frames + +Axes are defined relative to the hardware. See the diagrams in the repository root: + +- `TAP-axis-alpha.png` — Tap Strap +- `TAPXR-axis.png` — TapXR + +Additional protocol notes: [Tap Strap Raw Sensors Mode](https://tapwithus.atlassian.net/wiki/spaces/TD/pages/792002574/Tap+Strap+Raw+Sensors+Mode) (internal Confluence). + +## Developer mode + +Raw streaming expects Developer mode enabled in Tap Manager. Without it, characteristics may be present but the stream may not behave as documented. diff --git a/docs/how-to/connect-and-listen.md b/docs/how-to/connect-and-listen.md new file mode 100644 index 0000000..e9ebbaa --- /dev/null +++ b/docs/how-to/connect-and-listen.md @@ -0,0 +1,66 @@ +# Connect and listen for events + +## Connect + +Pair the Tap with the OS first. Then: + +```python +import asyncio +from tapsdk import TapSDK + +async def main(): + tap = TapSDK() + await tap.run() + +asyncio.run(main()) +``` + +`run()` attaches to an already-connected Tap when possible. If none is found, it scans (and on Windows also polls for paired devices that reconnect without advertising). + +## Connection and disconnection callbacks + +Register callbacks before `await run()`: + +```python +def on_connect(sdk): + print("connected", sdk) + +def on_disconnect(client): + print("disconnected", client) + +tap = TapSDK() +tap.register_connection_events(on_connect) +tap.register_disconnection_events(on_disconnect) +``` + +`on_connect` receives the `TapSDK` instance. `on_disconnect` receives the underlying Bleak client (platform-dependent). + +## Subscribe to input events + +```python +from tapsdk import AirGestures +from tapsdk.enumerations import MouseModes + +tap.register_tap_events(lambda id, tapcode: print("tap", id, tapcode)) +tap.register_mouse_events(lambda id, vx, vy, prox: print("mouse", vx, vy, prox)) +tap.register_air_gesture_events( + lambda id, gesture: print("gesture", AirGestures(gesture)) +) +tap.register_air_gesture_state_events( + lambda id, mode: print("mouse mode", MouseModes(mode)) +) +tap.register_raw_data_events(lambda id, packets: print("raw", packets)) +``` + +Tap and mouse events are only delivered when the device is in a controller-capable mode. See [Switch input modes](switch-input-modes.md). + +## Keep the process alive + +`run()` returns after notifications are set up. Keep the event loop running, for example: + +```python +await tap.run() +await asyncio.Event().wait() +``` + +Or follow the pattern in [`examples/basic.py`](../../examples/basic.py), which sleeps between mode changes. diff --git a/docs/how-to/index.md b/docs/how-to/index.md new file mode 100644 index 0000000..99b3778 --- /dev/null +++ b/docs/how-to/index.md @@ -0,0 +1,13 @@ +# How-to guides + +Problem-oriented recipes for common Tap Python SDK tasks. + +| Task | Guide | +|------|-------| +| Install on macOS, Windows, or Linux | [Install the SDK](install.md) | +| Connect and handle connection lifecycle | [Connect and listen](connect-and-listen.md) | +| Choose Text / Controller / Combined / Raw | [Switch input modes](switch-input-modes.md) | +| Stream accelerometer and IMU samples | [Stream raw sensors](stream-raw-sensors.md) | +| Play a haptic pattern | [Send haptics](send-haptics.md) | +| Force mouse or keyboard on TapXR | [Use Spatial Control](use-spatial-control.md) | +| Upgrade an app from 0.6.x | [Migrate from 0.6](migrate-from-0.6.md) | diff --git a/docs/how-to/install.md b/docs/how-to/install.md new file mode 100644 index 0000000..f8ee78e --- /dev/null +++ b/docs/how-to/install.md @@ -0,0 +1,49 @@ +# Install the SDK + +## From PyPI + +```bash +pip install tap-python-sdk +``` + +## From source + +```bash +git clone https://github.com/TapWithUs/tap-python-sdk +cd tap-python-sdk +pip install . +``` + +For development (tests and flake8): + +```bash +pip install .[dev] +``` + +## Platform prerequisites + +### macOS + +Uses Apple CoreBluetooth via Bleak. If you use a non-system Python, install PyObjC for that interpreter. The SDK pins `bleak==0.12.1` on Darwin. + +### Windows 10+ + +Uses Bleak with WinRT (`bleak==0.22.3` and `bleak-winrt==1.2.0`). No external DLL is required. + +### Linux + +Install BlueZ tools and grant Bluetooth access: + +```bash +sudo apt-get install bluez-tools libbluetooth-dev +sudo usermod -G bluetooth -a +su - $USER +``` + +The device’s Bluetooth name must start with `Tap` for the Linux discovery path. + +## Verify the import + +```bash +python -c "from tapsdk import TapSDK; print('ok')" +``` diff --git a/docs/how-to/migrate-from-0.6.md b/docs/how-to/migrate-from-0.6.md new file mode 100644 index 0000000..a79b385 --- /dev/null +++ b/docs/how-to/migrate-from-0.6.md @@ -0,0 +1,42 @@ +# Migrate from 0.6.x to 0.7.x + +## Input modes + +```python +# 0.6 +TapInputMode("controller") +TapInputMode("raw", sensitivity=[2, 1, 4]) + +# 0.7 +from tapsdk import InputModeController, InputModeRaw +from tapsdk.enumerations import FingerAcclSensitivity, ImuGyroSensitivity, ImuAcclSensitivity + +InputModeController() +InputModeRaw( + finger_accl_sens=FingerAcclSensitivity.G4, + imu_gyro_sens=ImuGyroSensitivity.DPS125, + imu_accl_sens=ImuAcclSensitivity.G8, +) +``` + +## Imports + +```python +# 0.6 +from tapsdk.models import AirGestures + +# 0.7 +from tapsdk import AirGestures +``` + +## Async API + +- Removed: `loop=` constructor argument. +- `register_*` remains synchronous — call before `await run()`. +- `set_input_mode`, `set_input_type`, and `send_vibration_sequence` are **async** and must be awaited. + +## Examples and backends + +- Use [`examples/basic.py`](../../examples/basic.py) instead of `example_unix.py` / `example_win.py`. +- Windows no longer uses `TAPWin.dll`; Bleak/WinRT is required. +- Python 3.9+ is required. diff --git a/docs/how-to/send-haptics.md b/docs/how-to/send-haptics.md new file mode 100644 index 0000000..e816e4d --- /dev/null +++ b/docs/how-to/send-haptics.md @@ -0,0 +1,21 @@ +# Send haptic (vibration) sequences + +```python +await tap.send_vibration_sequence([1000, 300, 200]) +``` + +Periods are in milliseconds, clamped to **10–2550** in **10 ms** steps. Values are stored as `period // 10` on the wire. + +The list alternates **on** and **off** durations. The example above vibrates for 1 s, pauses 300 ms, then vibrates 200 ms. + +## Limits + +- At most **18** period values (up to 9 on/off pairs). Longer lists are truncated. +- Requires an active BLE connection (`await tap.run()` first). + +## Example pattern + +```python +# short buzz, pause, short buzz, pause, long buzz +await tap.send_vibration_sequence([100, 200, 100, 200, 500]) +``` diff --git a/docs/how-to/stream-raw-sensors.md b/docs/how-to/stream-raw-sensors.md new file mode 100644 index 0000000..b4cbf87 --- /dev/null +++ b/docs/how-to/stream-raw-sensors.md @@ -0,0 +1,45 @@ +# Stream raw sensor data + +Enable Developer mode in the Tap Manager app first. Raw mode is available on Tap Strap / Tap Strap 2 (finger accelerometers) and Tap Strap 2 / TapXR (thumb IMU). + +## Enter raw mode + +```python +from tapsdk import InputModeRaw +from tapsdk.enumerations import ( + FingerAcclSensitivity, + ImuGyroSensitivity, + ImuAcclSensitivity, +) + +tap.register_raw_data_events(on_raw) + +await tap.set_input_mode(InputModeRaw( + scaled=True, + finger_accl_sens=FingerAcclSensitivity.G4, + imu_gyro_sens=ImuGyroSensitivity.DPS250, + imu_accl_sens=ImuAcclSensitivity.G4, +)) +``` + +With `scaled=True`, accelerometer values are in mg and gyro values in mdps. With `scaled=False`, payloads are raw LSB counts. + +## Handle packets + +```python +def on_raw(identifier, packets): + for packet in packets: + # packet["type"]: "imu" or "accl" + # packet["ts"]: ms timestamp from the device clock + # packet["payload"]: list of samples + print(identifier, packet["type"], packet["ts"], packet["payload"]) +``` + +- **`imu`:** 6 values — gyro x/y/z then accelerometer x/y/z on the thumb. +- **`accl`:** 15 values — 3-axis accelerometer for thumb, index, middle, ring, pinky (Tap Strap family). + +## Sensitivity options + +See [`FingerAcclSensitivity`](../reference/enumerations.md), [`ImuGyroSensitivity`](../reference/enumerations.md), and [`ImuAcclSensitivity`](../reference/enumerations.md). + +For coordinate frames and sampling rates, see [Raw sensors explained](../explanation/raw-sensors.md). diff --git a/docs/how-to/switch-input-modes.md b/docs/how-to/switch-input-modes.md new file mode 100644 index 0000000..720570c --- /dev/null +++ b/docs/how-to/switch-input-modes.md @@ -0,0 +1,36 @@ +# Switch input modes + +Input mode controls whether the Tap talks to the OS as a keyboard/mouse, streams events to your app, or both. + +## Choose a mode + +```python +from tapsdk import ( + InputModeText, + InputModeController, + InputModeControllerText, + InputModeRaw, +) + +await tap.set_input_mode(InputModeText()) # OS typing only; no SDK tap events +await tap.set_input_mode(InputModeController()) # SDK events only +await tap.set_input_mode(InputModeControllerText()) # both +await tap.set_input_mode(InputModeRaw(...)) # raw sensor stream +``` + +## When to use each + +| Mode | Use when | +|------|----------| +| Text | You want normal Tap typing; your app does not need tap events | +| Controller | Your app is the sole consumer (games, custom UI) | +| Controller + Text | Users still type while your app also listens | +| Raw | You need accelerometer / IMU samples | + +## Refresh behavior + +After the first `set_input_mode` / `set_input_type`, the SDK periodically rewrites the mode so the device stays in sync if the link hiccups. You do not need to call refresh yourself. + +## Changing raw sensitivities + +You cannot change raw sensitivity enums while already in raw mode with a different command payload. Leave raw mode first (for example switch to Controller), then enter raw again with the new settings. See [Stream raw sensors](stream-raw-sensors.md). diff --git a/docs/how-to/use-spatial-control.md b/docs/how-to/use-spatial-control.md new file mode 100644 index 0000000..cdf3001 --- /dev/null +++ b/docs/how-to/use-spatial-control.md @@ -0,0 +1,33 @@ +# Use Spatial Control (TapXR) + +Spatial Control lets authorized apps force input type (air mouse vs tapping) and receive extended air-gesture state. It requires TapXR with experimental Spatial Control firmware and developer access. Request access via [Tap contact](https://www.tapwithus.com/contact-us/). + +## Force input type + +```python +from tapsdk import InputType + +await tap.set_input_type(InputType.MOUSE) # air / optical mouse +await tap.set_input_type(InputType.KEYBOARD) # tapping / keyboard +await tap.set_input_type(InputType.AUTO) # posture-based selection +``` + +Combine with a controller-capable [input mode](switch-input-modes.md) so your app receives events. + +## Extended air gestures + +Register both gesture and state callbacks: + +```python +from tapsdk import AirGestures +from tapsdk.enumerations import MouseModes + +tap.register_air_gesture_events( + lambda id, g: print(AirGestures(g)) +) +tap.register_air_gesture_state_events( + lambda id, mode: print(MouseModes(mode)) +) +``` + +State events report mouse-mode changes (`STDBY`, `AIR_MOUSE`, `OPTICAL1`, `OPTICAL2`). Gesture values include directional swipes, pinches, thumb contacts, and fist/open states — see [AirGestures](../reference/enumerations.md). diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..d121fcb --- /dev/null +++ b/docs/index.md @@ -0,0 +1,21 @@ +# Tap Python SDK documentation + +This documentation follows the [Diátaxis](https://diataxis.fr/) structure. Pick the section that matches what you need: + +| Goal | Section | +|------|---------| +| Learn by doing — first working connection | [Tutorial](tutorial/getting-started.md) | +| Solve a specific task | [How-to guides](how-to/index.md) | +| Look up an API, type, or event | [Reference](reference/index.md) | +| Understand how modes and sensors work | [Explanation](explanation/index.md) | + +## Package + +- **PyPI:** [`tap-python-sdk`](https://pypi.org/project/tap-python-sdk/) +- **Import name:** `tapsdk` +- **Python:** 3.9+ +- **Status:** beta + +## Platforms + +macOS (CoreBluetooth), Windows 10+ (Bleak/WinRT), and Linux (BlueZ). Pair the Tap with the OS before running your app for the most reliable connection path. diff --git a/docs/reference/enumerations.md b/docs/reference/enumerations.md new file mode 100644 index 0000000..097ebde --- /dev/null +++ b/docs/reference/enumerations.md @@ -0,0 +1,76 @@ +# Enumerations + +All live in `tapsdk.enumerations`. `InputType` and `AirGestures` are also re-exported from `tapsdk`. + +## `InputType` + +Spatial Control input selection. + +| Member | Value | +|--------|-------| +| `MOUSE` | 1 | +| `KEYBOARD` | 2 | +| `AUTO` | 3 | + +## `MouseModes` + +Reported by air-gesture state events (`0x14` notifications). + +| Member | Value | +|--------|-------| +| `STDBY` | 0 | +| `AIR_MOUSE` | 1 | +| `OPTICAL1` | 2 | +| `OPTICAL2` | 3 | + +## `AirGestures` + +| Member | Value | +|--------|-------| +| `NONE` | 0 | +| `GENERAL` | 1 | +| `UP_ONE_FINGER` | 2 | +| `UP_TWO_FINGERS` | 3 | +| `DOWN_ONE_FINGER` | 4 | +| `DOWN_TWO_FINGERS` | 5 | +| `LEFT_ONE_FINGER` | 6 | +| `LEFT_TWO_FINGERS` | 7 | +| `RIGHT_ONE_FINGER` | 8 | +| `RIGHT_TWO_FINGERS` | 9 | +| `PINCH` | 10 | +| `THUMB_FINGER` | 12 | +| `THUMB_MIDDLE` | 14 | +| `STATE_OPEN` | 100 | +| `STATE_THUMB_FINGER` | 101 | +| `STATE_THUMB_MIDDLE` | 102 | +| `STATE_THUMB_RING` | 103 | +| `STATE_THUMB_PINKY` | 104 | +| `STATE_FIST` | 105 | + +## `FingerAcclSensitivity` + +| Member | Approx. range | +|--------|----------------| +| `G2` | ±2 g | +| `G4` | ±4 g | +| `G8` | ±8 g | +| `G16` | ±16 g | + +## `ImuGyroSensitivity` + +| Member | Approx. range | +|--------|----------------| +| `DPS125` | ±125 °/s | +| `DPS250` | ±250 °/s | +| `DPS500` | ±500 °/s | +| `DPS1000` | ±1000 °/s | +| `DPS2000` | ±2000 °/s | + +## `ImuAcclSensitivity` + +| Member | Approx. range | +|--------|----------------| +| `G2` | ±2 g | +| `G4` | ±4 g | +| `G8` | ±8 g | +| `G16` | ±16 g | diff --git a/docs/reference/events.md b/docs/reference/events.md new file mode 100644 index 0000000..8159254 --- /dev/null +++ b/docs/reference/events.md @@ -0,0 +1,70 @@ +# Events + +Callbacks are registered with `TapSDK.register_*` methods. They run on the asyncio / Bleak notification path — keep them short or schedule work onto another task. + +## Connection + +```text +register_connection_events(cb) +cb(tap_sdk: TapSDK) -> None +``` + +Called after GATT notifications are started successfully. + +```text +register_disconnection_events(cb) +cb(client) -> None +``` + +Passed through to Bleak’s disconnected callback. + +## Tap + +```text +register_tap_events(cb) +cb(identifier, tapcode: int) -> None +``` + +`tapcode` is an 8-bit value in **1–31**. Bit 0 (LSb) is the thumb; bit 4 is the pinky. Example: `5` (`0b00101`) = thumb + middle. + +While air-mouse mode is active, tapcodes `2` and `4` are remapped into air-gesture handling instead of the tap callback. + +## Mouse + +```text +register_mouse_events(cb) +cb(identifier, vx: int, vy: int, proximity: bool) -> None +``` + +`vx` / `vy` are signed velocities. `proximity` is `True` when a surface is detected. + +## Air gesture + +```text +register_air_gesture_events(cb) +cb(identifier, gesture: int) -> None +``` + +`gesture` matches [`AirGestures`](enumerations.md). + +```text +register_air_gesture_state_events(cb) +cb(identifier, mouse_mode: MouseModes) -> None +``` + +Fired when the device reports mouse-mode changes (`0x14` payload). + +## Raw sensors + +```text +register_raw_data_events(cb) +cb(identifier, packets: list[dict]) -> None +``` + +Each dict: + +| Key | Type | Description | +|-----|------|-------------| +| `type` | `str` | `"imu"` or `"accl"` | +| `ts` | `int` | Device timestamp (ms) | +| `payload` | `list` | Sample values (scaled or raw LSB) | diff --git a/docs/reference/index.md b/docs/reference/index.md new file mode 100644 index 0000000..c1cd0bc --- /dev/null +++ b/docs/reference/index.md @@ -0,0 +1,11 @@ +# Reference + +Information-oriented descriptions of the public API. For recipes, see [How-to guides](../how-to/index.md). For concepts, see [Explanation](../explanation/index.md). + +| Topic | Page | +|-------|------| +| `TapSDK` class | [TapSDK](tapsdk.md) | +| Input mode classes | [Input modes](input-modes.md) | +| Enums | [Enumerations](enumerations.md) | +| Event callbacks | [Events](events.md) | +| Package exports | [Package](package.md) | diff --git a/docs/reference/input-modes.md b/docs/reference/input-modes.md new file mode 100644 index 0000000..f73530f --- /dev/null +++ b/docs/reference/input-modes.md @@ -0,0 +1,56 @@ +# Input modes + +Defined in `tapsdk.inputmodes`. Prefer importing the concrete classes from `tapsdk`. + +## Base: `InputMode` + +| Attribute / method | Description | +|--------------------|-------------| +| `COMMAND_PREFIX` | `bytearray([0x3, 0xc, 0x0])` | +| `get_command()` | Full GATT write payload: prefix + mode `code` | +| `name` | Human-readable label | + +## `InputModeText` + +Normal Tap operation for the OS. Mode code `0x00`. SDK tap events are not produced. + +## `InputModeController` + +Controller-only. Mode code `0x01`. Device sends tap / mouse / gesture events to the SDK. + +## `InputModeControllerText` + +Combined Text + Controller. Mode code `0x05`. + +## `InputModeRaw` + +```python +InputModeRaw( + scaled=False, + finger_accl_sens=None, + imu_gyro_sens=None, + imu_accl_sens=None, +) +``` + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `scaled` | `False` | If `True`, raw payloads are multiplied by sensitivity scale factors (mg / mdps) | +| `finger_accl_sens` | `FingerAcclSensitivity.G2` | Finger accelerometer range | +| `imu_gyro_sens` | `ImuGyroSensitivity.DPS125` | IMU gyro range | +| `imu_accl_sens` | `ImuAcclSensitivity.G2` | IMU accelerometer range | + +Mode code: `0x0a` followed by the three sensitivity enum values. + +### `RawSensorsSensitivity` + +Internal helper used by `InputModeRaw`. + +| Method | Returns | +|--------|---------| +| `tolist()` | `[finger, gyro, imu_accl]` integer values for the command | +| `get_scale_factors()` | `[finger_mg_per_lsb, gyro_mdps_per_lsb, imu_mg_per_lsb]` | + +## `input_type_command(input_type)` + +Builds the Spatial Control write: `bytearray([0x3, 0xd, 0x0, input_type.value])`. Used by `TapSDK.set_input_type`. diff --git a/docs/reference/package.md b/docs/reference/package.md new file mode 100644 index 0000000..314fe11 --- /dev/null +++ b/docs/reference/package.md @@ -0,0 +1,38 @@ +# Package layout + +## Public imports (`tapsdk`) + +| Name | Kind | +|------|------| +| `TapSDK` | Class (lazy import from `tapsdk.tap`) | +| `InputModeText` | Class | +| `InputModeController` | Class | +| `InputModeControllerText` | Class | +| `InputModeRaw` | Class | +| `InputType` | Enum | +| `AirGestures` | Enum | + +Version string: `tapsdk.__version__`. + +## Modules + +| Module | Role | +|--------|------| +| `tapsdk.tap` | BLE client, `TapSDK`, GATT UUIDs | +| `tapsdk.inputmodes` | Mode command builders | +| `tapsdk.enumerations` | Public enums | +| `tapsdk.parsers` | Notification payload parsers | + +## GATT characteristics (SDK-owned) + +| Constant | UUID | Use | +|----------|------|-----| +| `tap_service` | `c3ff0001-…` | Tap proprietary service | +| `tap_data_characteristic` | `c3ff0005-…` | Tap events (notify) | +| `mouse_data_characteristic` | `c3ff0006-…` | Mouse events (notify) | +| `ui_cmd_characteristic` | `c3ff0009-…` | Haptics (write) | +| `air_gesture_data_characteristic` | `c3ff000a-…` | Air gestures / mouse mode (notify) | +| `tap_mode_characteristic` | `6e400002-…` | NUS RX — mode / input-type commands (write) | +| `raw_sensors_characteristic` | `6e400003-…` | NUS TX — raw stream (notify) | + +Lower-level BLE protocol details: [Tap BLE API Documentation](https://tapwithus.atlassian.net/wiki/spaces/FIR/pages/426803201/Tap+BLE+API+Documentation) (internal). diff --git a/docs/reference/tapsdk.md b/docs/reference/tapsdk.md new file mode 100644 index 0000000..5d58f0d --- /dev/null +++ b/docs/reference/tapsdk.md @@ -0,0 +1,82 @@ +# TapSDK + +Primary entry point. Import with `from tapsdk import TapSDK`. + +Construction imports a platform BLE backend (macOS, Windows, or Linux). Creating `TapSDK` on an unsupported platform, or with the wrong Bleak pin, raises `ImportError`. + +## Constructor + +```python +TapSDK(address=None) +``` + +| Parameter | Description | +|-----------|-------------| +| `address` | Optional BLE address / platform device id. On Linux, if omitted, the SDK picks a connected device whose name starts with `Tap`. | + +## Connection + +### `async run()` + +Connect to a Tap and start GATT notifications for tap, mouse, air-gesture, and raw characteristics. + +- Prefer an already OS-connected / paired device. +- Otherwise scan until a Tap advertising the Tap service UUID is found. +- On Windows, also polls for paired devices that reconnect without advertising. +- Invokes the connection callback when notifications are armed. + +Returns when setup finishes; it does not block forever. Keep the asyncio loop alive yourself. + +## Commands + +### `async set_input_mode(input_mode, identifier=None)` + +Write an [input mode](input-modes.md) command to the device. + +| Parameter | Description | +|-----------|-------------| +| `input_mode` | Instance of `InputModeText`, `InputModeController`, `InputModeControllerText`, or `InputModeRaw` | +| `identifier` | Reserved for multi-device use; currently unused | + +Starts periodic mode refresh on first call. Changing raw sensitivities while already in a different raw configuration is rejected with a warning. + +### `async set_input_type(input_type, identifier=None)` + +TapXR Spatial Control only. Force mouse, keyboard, or automatic input selection. + +| Parameter | Description | +|-----------|-------------| +| `input_type` | `InputType.MOUSE`, `InputType.KEYBOARD`, or `InputType.AUTO` | +| `identifier` | Reserved; currently unused | + +### `async send_vibration_sequence(sequence, identifier=None)` + +Send haptic on/off periods. + +| Parameter | Description | +|-----------|-------------| +| `sequence` | List of integers (ms). Each value is clamped to 0–2550 and stored as `value // 10`. Max length 18. | +| `identifier` | Reserved; currently unused | + +## Event registration + +All `register_*` methods are synchronous. Pass a callable; pass `None` is not required to clear (re-assign by registering again). See [Events](events.md). + +| Method | Callback signature | +|--------|-------------------| +| `register_connection_events` | `(tap_sdk)` | +| `register_disconnection_events` | `(client)` — Bleak disconnected callback | +| `register_tap_events` | `(identifier, tapcode)` | +| `register_mouse_events` | `(identifier, vx, vy, proximity)` | +| `register_air_gesture_events` | `(identifier, gesture)` | +| `register_air_gesture_state_events` | `(identifier, mouse_mode)` | +| `register_raw_data_events` | `(identifier, packets)` | + +## Attributes (runtime) + +| Attribute | Meaning | +|-----------|---------| +| `client` | Underlying `TapClient` / `BleakClient` | +| `input_mode` | Last requested `InputMode` instance | +| `input_type` | Last requested `InputType` | +| `mouse_mode` | Current `MouseModes` from air-gesture state notifications | diff --git a/docs/tutorial/getting-started.md b/docs/tutorial/getting-started.md new file mode 100644 index 0000000..65e7645 --- /dev/null +++ b/docs/tutorial/getting-started.md @@ -0,0 +1,88 @@ +# Getting started + +This tutorial walks you through installing the SDK, connecting to a Tap, and printing tap events. By the end you will have a small asyncio program that talks to a real device. + +## What you need + +- Python 3.9 or newer +- A Tap Strap or TapXR, updated with Tap Manager +- The Tap already paired with your computer over Bluetooth + +## 1. Install the SDK + +```bash +pip install tap-python-sdk +``` + +On Linux, also install BlueZ tooling and add your user to the `bluetooth` group: + +```bash +sudo apt-get install bluez-tools libbluetooth-dev +sudo usermod -G bluetooth -a "$USER" +su - "$USER" +``` + +## 2. Create a project file + +Create `hello_tap.py`: + +```python +import asyncio +from tapsdk import TapSDK, InputModeController + + +def on_tap(identifier, tapcode): + print(f"{identifier} tapped {tapcode}") + + +def on_connect(sdk): + print("Connected to Tap") + + +async def main(): + tap = TapSDK() + tap.register_connection_events(on_connect) + tap.register_tap_events(on_tap) + + await tap.run() + await tap.set_input_mode(InputModeController()) + + # Keep receiving events + await asyncio.Event().wait() + + +asyncio.run(main()) +``` + +## 3. Run it + +1. Turn the Tap on and confirm it is connected in the OS Bluetooth settings. +2. Run: + +```bash +python hello_tap.py +``` + +3. When you see `Connected to Tap`, switch to Controller mode is already requested — tap with one or more fingers. You should see lines like: + +```text +XX:XX:XX:XX:XX:XX tapped 5 +``` + +`tapcode` is a bitmask of fingers (bit 0 = thumb … bit 4 = pinky). `5` means thumb + middle. + +## 4. What just happened + +1. `TapSDK()` creates a BLE client for your platform. +2. `register_*` attaches callbacks (sync; call these before `run()`). +3. `await tap.run()` connects to an already-paired Tap, or scans until one appears. +4. `set_input_mode(InputModeController())` tells the device to send controller events to your app. + +In Text mode (the default), the Tap behaves like a normal keyboard/mouse for the OS and does not emit tap events to the SDK. + +## Next steps + +- Switch modes, stream sensors, or send haptics: [How-to guides](../how-to/index.md) +- Full callback and command signatures: [API reference](../reference/index.md) +- Why modes and sensors are designed this way: [Explanation](../explanation/index.md) +- Runnable sample covering more events: [`examples/basic.py`](../../examples/basic.py) diff --git a/tapsdk/__init__.py b/tapsdk/__init__.py index 41603a0..152b6f4 100644 --- a/tapsdk/__init__.py +++ b/tapsdk/__init__.py @@ -1,3 +1,9 @@ +"""Tap Strap / TapXR Python BLE SDK. + +Public exports: ``TapSDK``, input-mode classes, ``InputType``, and ``AirGestures``. +See the ``docs/`` directory for tutorials, how-to guides, reference, and explanation. +""" + from tapsdk.enumerations import InputType, AirGestures # noqa: F401 from tapsdk.inputmodes import InputModeRaw, InputModeController, InputModeText, InputModeControllerText # noqa: F401 diff --git a/tapsdk/enumerations.py b/tapsdk/enumerations.py index 9ce68f9..9848363 100644 --- a/tapsdk/enumerations.py +++ b/tapsdk/enumerations.py @@ -2,6 +2,8 @@ class MouseModes(Enum): + """Mouse / air-mouse state reported by air-gesture state events.""" + STDBY = 0 AIR_MOUSE = 1 OPTICAL1 = 2 @@ -9,12 +11,16 @@ class MouseModes(Enum): class InputType(Enum): + """Spatial Control input modality (TapXR experimental firmware).""" + MOUSE = 1 KEYBOARD = 2 AUTO = 3 class AirGestures(Enum): + """Air-gesture and spatial-state codes from gesture notifications.""" + NONE = 0 GENERAL = 1 UP_ONE_FINGER = 2 @@ -37,6 +43,8 @@ class AirGestures(Enum): class FingerAcclSensitivity(Enum): + """Dynamic range for per-finger accelerometers in raw mode.""" + G2 = 1 G4 = 2 G8 = 3 @@ -44,6 +52,8 @@ class FingerAcclSensitivity(Enum): class ImuGyroSensitivity(Enum): + """Dynamic range for the thumb IMU gyroscope in raw mode.""" + DPS125 = 1 DPS250 = 2 DPS500 = 3 @@ -52,6 +62,8 @@ class ImuGyroSensitivity(Enum): class ImuAcclSensitivity(Enum): + """Dynamic range for the thumb IMU accelerometer in raw mode.""" + G2 = 1 G4 = 2 G8 = 3 diff --git a/tapsdk/inputmodes.py b/tapsdk/inputmodes.py index 02947e1..8a67af9 100644 --- a/tapsdk/inputmodes.py +++ b/tapsdk/inputmodes.py @@ -6,6 +6,8 @@ class RawSensorsSensitivity(): + """Maps sensitivity enums to command bytes and physical scale factors.""" + finger_acc_scales = [None, 3.91, 7.81, 15.62, 31.25] # mg/lsb imu_gyro_scales = [None, 4.375, 8.75, 17.5, 35, 70] # mdps/lsb imu_acc_scales = [None, 0.061, 0.122, 0.244, 0.488] # mg/lsb @@ -21,16 +23,21 @@ def __init__(self, finger_accl_sens, imu_gyro_sens, imu_accl_sens): ] def tolist(self): + """Return ``[finger, gyro, imu_accl]`` enum values for the mode command.""" return self.sens_values def get_scale_factors(self): + """Return ``[finger_mg/lsb, gyro_mdps/lsb, imu_mg/lsb]``.""" return self.scale_factors class InputMode: + """Base class for Tap input-mode GATT commands.""" + COMMAND_PREFIX = bytearray([0x3, 0xc, 0x0]) def get_command(self): + """Return the full write payload for this mode.""" return self.COMMAND_PREFIX + self.code def __repr__(self): @@ -38,26 +45,41 @@ def __repr__(self): class InputModeController(InputMode): + """Controller-only mode: SDK receives tap/mouse/gesture events.""" + def __init__(self): self.name = "Controller Mode" self.code = bytearray([0x1]) class InputModeText(InputMode): + """Text mode: normal OS keyboard/mouse behavior; no SDK tap events.""" + def __init__(self): self.name = "Text Mode" self.code = bytearray([0x0]) class InputModeControllerText(InputMode): + """Combined Text and Controller mode.""" + def __init__(self): self.name = "Controller and Text Mode" self.code = bytearray([0x5]) class InputModeRaw(InputMode): + """Raw sensor streaming mode with optional physical-unit scaling.""" + def __init__(self, scaled=False, finger_accl_sens=None, imu_gyro_sens=None, imu_accl_sens=None): + """ + Args: + scaled: If True, parse payloads into mg / mdps using scale factors. + finger_accl_sens: ``FingerAcclSensitivity`` (default ``G2``). + imu_gyro_sens: ``ImuGyroSensitivity`` (default ``DPS125``). + imu_accl_sens: ``ImuAcclSensitivity`` (default ``G2``). + """ self.name = "Raw sensors Mode" self.scaled = scaled self.sensitivity = RawSensorsSensitivity(finger_accl_sens or FingerAcclSensitivity.G2, @@ -67,5 +89,6 @@ def __init__(self, scaled=False, finger_accl_sens=None, def input_type_command(input_type): + """Build the Spatial Control input-type write payload.""" assert isinstance(input_type, InputType), "input_type must be of type InputType" return bytearray([0x3, 0xd, 0x0, input_type.value]) diff --git a/tapsdk/parsers.py b/tapsdk/parsers.py index e883e5a..6345f7b 100644 --- a/tapsdk/parsers.py +++ b/tapsdk/parsers.py @@ -3,6 +3,7 @@ def tapcode_to_fingers(tapcode: int): def mouse_data_msg(data: bytearray): + """Parse a mouse notification into ``(vx, vy, proximity)``.""" vx = int.from_bytes(data[1:3], "little", signed=True) vy = int.from_bytes(data[3:5], "little", signed=True) prox = data[9] == 1 @@ -10,31 +11,40 @@ def mouse_data_msg(data: bytearray): def air_gesture_data_msg(data: bytearray): + """Parse an air-gesture notification into ``[gesture_code]``.""" return [data[0]] def tap_data_msg(data: bytearray): + """Parse a tap notification into ``[tapcode]``.""" return [data[0]] def raw_data_msg(data: bytearray, scale_factors=None): - ''' - Parses raw data messages into structured data with optional scaling. - Raw data is packed into messages with the following structure: + """Parse raw sensor notifications into structured packets. + + Raw data is packed into messages with the following structure:: + [msg_type (1 bit)][timestamp (31 bit)][payload (12 - 30 bytes)] * msg type - '0' for imu message - - '1' for accelerometers message - * timestamp - unsigned int, given in milliseconds - * payload - for imu message is 12 bytes - composed by a series of 6 uint16 numbers - representing [g_x, g_y, g_z, xl_x, xl_y, xl_z] - - for accelerometers message is 30 bytes - composed by a series of 15 uint16 numbers - representing [xl_x_thumb , xl_y_thumb, xl_z_thumb, - xl_x_finger, xl_y_finger, xl_z_finger, - ...] - - ''' + - '1' for accelerometers message + * timestamp - unsigned int, given in milliseconds + * payload - for imu message is 12 bytes + composed by a series of 6 uint16 numbers + representing [g_x, g_y, g_z, xl_x, xl_y, xl_z] + - for accelerometers message is 30 bytes + composed by a series of 15 uint16 numbers + representing [xl_x_thumb , xl_y_thumb, xl_z_thumb, + xl_x_finger, xl_y_finger, xl_z_finger, + ...] + + Args: + data: GATT notification payload. + scale_factors: Optional ``[finger_mg, gyro_mdps, imu_mg]`` multipliers. + + Returns: + List of dicts with keys ``type``, ``ts``, and ``payload``. + """ L = len(data) ptr = 0 messages = [] diff --git a/tapsdk/tap.py b/tapsdk/tap.py index 255d6c6..768be50 100644 --- a/tapsdk/tap.py +++ b/tapsdk/tap.py @@ -237,7 +237,21 @@ def get_mac_addr() -> str: class TapSDK(): + """High-level async API for one Tap Strap / TapXR over BLE. + + Register event callbacks, then ``await run()`` to connect and subscribe to + notifications. Issue commands with ``set_input_mode``, ``set_input_type``, + and ``send_vibration_sequence``. + """ + def __init__(self, **kwargs): + """Create an SDK instance. + + Args: + address: Optional BLE address or platform device id. On Linux, if + omitted, a connected device whose name starts with ``Tap`` is + selected. + """ self.client = TapClient(address=kwargs.get("address")) self.mouse_event_cb = None self.tap_event_cb = None @@ -256,24 +270,31 @@ def _client_connected(client) -> bool: return is_connected() if callable(is_connected) else is_connected def register_tap_events(self, cb: Callable): + """Register ``cb(identifier, tapcode)`` for tap events.""" self.tap_event_cb = cb def register_mouse_events(self, cb: Callable): + """Register ``cb(identifier, vx, vy, proximity)`` for mouse motion.""" self.mouse_event_cb = cb def register_air_gesture_events(self, cb: Callable): + """Register ``cb(identifier, gesture)`` for air-gesture codes.""" self.air_gesture_event_cb = cb def register_air_gesture_state_events(self, cb: Callable): + """Register ``cb(identifier, mouse_mode)`` for mouse-mode changes.""" self.air_gesture_state_event_cb = cb def register_raw_data_events(self, cb: Callable): + """Register ``cb(identifier, packets)`` for raw sensor batches.""" self.raw_data_event_cb = cb def register_connection_events(self, cb: Callable): + """Register ``cb(tap_sdk)`` called after notifications are started.""" self.connection_cb = cb def register_disconnection_events(self, cb: Callable): + """Register Bleak's disconnected callback ``cb(client)``.""" self.client.set_disconnected_callback(cb) def on_moused(self, identifier, data): @@ -309,6 +330,13 @@ def on_air_gesture(self, identifier, data): self.air_gesture_event_cb(identifier, *args) async def send_vibration_sequence(self, sequence, identifier=None): + """Send a haptic on/off sequence. + + Args: + sequence: Periods in milliseconds (10–2550, 10 ms steps). Alternating + on/off durations. At most 18 values; longer lists are truncated. + identifier: Reserved for multi-device use; currently unused. + """ if len(sequence) > 18: sequence = sequence[:18] for i, d in enumerate(sequence): @@ -318,6 +346,12 @@ async def send_vibration_sequence(self, sequence, identifier=None): await self.client.write_gatt_char(ui_cmd_characteristic, write_value) async def set_input_mode(self, input_mode: InputMode, identifier=None): + """Set Text, Controller, Controller+Text, or Raw input mode. + + Args: + input_mode: An ``InputMode`` instance from ``tapsdk``. + identifier: Reserved for multi-device use; currently unused. + """ if (isinstance(input_mode, InputModeRaw) and isinstance(self.input_mode, InputModeRaw) and self.input_mode.get_command() != input_mode.get_command()): logger.warning("Can't change \"raw\" sensitivities while in \"raw\"") @@ -332,6 +366,12 @@ async def set_input_mode(self, input_mode: InputMode, identifier=None): await self._write_input_mode(write_value) async def set_input_type(self, input_type: InputType, identifier=None): + """Force Spatial Control input type on TapXR (experimental firmware). + + Args: + input_type: ``InputType.MOUSE``, ``KEYBOARD``, or ``AUTO``. + identifier: Reserved for multi-device use; currently unused. + """ assert isinstance(input_type, InputType), "input_type must be of type InputType" self.input_type = input_type write_value = input_type_command(self.input_type) @@ -351,6 +391,13 @@ async def _write_input_mode(self, value): await self.client.write_gatt_char(tap_mode_characteristic, value) async def run(self): + """Connect to a Tap and start GATT notifications. + + Attaches to an already-connected device when possible; otherwise scans + (and on Windows polls for paired reconnects). Invokes the connection + callback when notifications are armed. Returns after setup — keep the + asyncio event loop alive to continue receiving events. + """ stop_event = asyncio.Event() devices = [] connected = False From 00c119fd04bf474fadb202f28084ad17826efa3c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 21:10:12 +0000 Subject: [PATCH 3/9] =?UTF-8?q?Deploy=20Di=C3=A1taxis=20docs=20to=20GitHub?= =?UTF-8?q?=20Pages=20with=20MkDocs=20Material?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add mkdocs.yml, requirements-docs.txt, and a Pages workflow that builds on PRs and deploys on master. Sync axis diagrams into docs/assets and point example links at GitHub so mkdocs --strict builds cleanly. Co-authored-by: Liron Ilouz --- .github/workflows/docs.yml | 77 +++++++++++++++++++++++++ Readme.md | 6 +- docs/assets/TAP-axis-alpha.png | Bin 0 -> 61195 bytes docs/assets/TAPXR-axis.png | Bin 0 -> 141844 bytes docs/explanation/raw-sensors.md | 7 ++- docs/how-to/connect-and-listen.md | 2 +- docs/how-to/migrate-from-0.6.md | 2 +- docs/index.md | 1 + docs/tutorial/getting-started.md | 2 +- mkdocs.yml | 91 ++++++++++++++++++++++++++++++ requirements-docs.txt | 2 + 11 files changed, 182 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/docs.yml create mode 100644 docs/assets/TAP-axis-alpha.png create mode 100644 docs/assets/TAPXR-axis.png create mode 100644 mkdocs.yml create mode 100644 requirements-docs.txt diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..5e1e6e3 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,77 @@ +name: Deploy docs + +on: + push: + branches: [master] + paths: + - "docs/**" + - "mkdocs.yml" + - "requirements-docs.txt" + - ".github/workflows/docs.yml" + - "TAP-axis-alpha.png" + - "TAPXR-axis.png" + pull_request: + paths: + - "docs/**" + - "mkdocs.yml" + - "requirements-docs.txt" + - ".github/workflows/docs.yml" + - "TAP-axis-alpha.png" + - "TAPXR-axis.png" + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Cache MkDocs + uses: actions/cache@v4 + with: + path: ~/.cache + key: mkdocs-material-${{ hashFiles('requirements-docs.txt') }} + restore-keys: | + mkdocs-material- + + - name: Install docs dependencies + run: pip install -r requirements-docs.txt + + - name: Sync reference images into docs + run: | + mkdir -p docs/assets + cp -f TAP-axis-alpha.png TAPXR-axis.png docs/assets/ + + - name: Build site + run: mkdocs build --strict --clean + + - name: Upload Pages artifact + if: github.event_name != 'pull_request' + uses: actions/upload-pages-artifact@v3 + with: + path: site + + deploy: + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/Readme.md b/Readme.md index c7f113a..c446bdd 100644 --- a/Readme.md +++ b/Readme.md @@ -8,7 +8,9 @@ BLE SDK for building Python apps that connect to **Tap Strap** and **TapXR**, se ### Documentation -Docs follow [Diátaxis](https://diataxis.fr/) — pick the path that matches your goal: +Published docs (MkDocs Material): [https://tapwithus.github.io/tap-python-sdk/](https://tapwithus.github.io/tap-python-sdk/) + +Source follows [Diátaxis](https://diataxis.fr/) — pick the path that matches your goal: | I want to… | Go to | |------------|--------| @@ -17,7 +19,7 @@ Docs follow [Diátaxis](https://diataxis.fr/) — pick the path that matches you | Look up APIs and types | [Reference](docs/reference/index.md) | | Understand modes and sensors | [Explanation](docs/explanation/index.md) | -Full index: [docs/index.md](docs/index.md) +Full index: [docs/index.md](docs/index.md). Local preview: `pip install -r requirements-docs.txt && mkdocs serve`. ### Install diff --git a/docs/assets/TAP-axis-alpha.png b/docs/assets/TAP-axis-alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..948f79786a9deb3b84826067474521c1daaec9de GIT binary patch literal 61195 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 literal 0 HcmV?d00001 diff --git a/docs/assets/TAPXR-axis.png b/docs/assets/TAPXR-axis.png new file mode 100644 index 0000000000000000000000000000000000000000..f413d0d4ae664d07667d6ccb0ad15de4daed0145 GIT binary patch literal 141844 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%0A#) z67(Tat~8D*;A=3q-;)SqGwH<#3i1^g*j*6(>d}*0G^_1d#JnqlUp_%ARuml)Mb$x} z=+RTKIvv({VB)u3$kE4ilsjnI!k8(WtOylK@Fq{$G6bidMPHRcTQCJ4v6^S0qrQH^ zzrtKbH-VJTi3j`2hRPk}&;>2X=&f4uM;^HibD`yk0XN$p-HwA!>1mv}hCS%1Pugzn zEuV73Tb2-J;Cq*LaF0KaE9MMl78T!&Qs02%0SHD=XgI?`PN$=rzJ=jtsxcqJ8n*~( zCipEUfSbZj$l_@W7l9|ThmAZl9P1CZ@kstYYIczXUk!}!L+J;ZKeGok$$BlVNq55> zFX|j=_JYE0$BVPJias^xYZVCS(X7es8**5ewKy}Wy(nl_vyj!DsG{p!g}y@;Iaj$D`hM!QLNkKcTw9i##z zJIL=u&m$+V^ja;h!LY~>w7Hg3r(A2XC|jzrb6J?Pkl*jC#_jq3OKyFFEOaZMncGTsjBBz??BIXl zU&|Gwru<`IB)Ao>WFd!OSMug5Q#!t3LYhW=6JIir&2xCrddC=99TaQ4l^pA{tky54 z)t1;@GMi_$b@1YoI*`CUksBMjG48Vja{E9wS;y+oN0u2Uj71KDW&H)Wz&){)HyR#N z#+WM~zJ5{(#4>!g`sTBl6EO8?PE0d zIJ_jf0}?sbbW4x}L<#f}Aw@N1*P1|AKMy^NjFb<+>JEfsA#w4`jvG zlNw{S@PObMD(KlU)eSF2gRC+U0l@0{$FV>P^8B@KP0{r?e(?CE0wg=ZkAGkX_?su+ z>#+|4-*?(2zW(AH?yvCca+u-DAz91L6U2K4w7|LZeL;& z4NL0cj~%=X4!Zs9{$U|kdiJ_+(owlVD&Q~bwe00U!Z3F*2P1?;h}d0ru%Iqq>Q{-J zvZDddl}z}t*}=oRuBsPxF-di&QP9E3F(Hpc#>atK1Nu(Cnr76d;1 z>A+!m)lLKlMqaYfJ^6hnbLb?KeWKHnQG~-G4Lhj|NSlr8GJMq0g&aQqYhp50M>pgr97x(wJ!~sLLZ@vL!aWp_>W#ZN!K*~xYW~{wd!wB+8$U(;w%{^$$-g*oV;Ya=GQtHYN z_ywNg4!?ti{#s7I{TwN_(w9y$<7#01ISl-u^XP$e*b(~vYO6lR2n*r};;Prg&KzWM z0ERtGz>6ihz@SN@^J1z~sXl!qW_FRUp6e8=?k0WlqZS379_7J)g4_>!yy5kapDXZv zr@K0Nzbd=LA6z#~Wp-G3ON&!IhM8L?+|{D<@lRg<#;05f zj0C(NvO}ay03G$hvy1eNI_4+P{$PGzlhh8CBX7#sO(3RTzpGca(gtiE@v0i%9-4vC zzLm{xs`F|`7T)p^K4`ewDrX8@Oo3}(D}7Sf33!tI-}TxB7j4nw=gAitK=_nh=xzWo zoQwswNkwY5iGtef>!pj$fU%ogJQZjYX(rc{(!_07N~9bvZE z@G%*7O3YQ9MSS|+8M}}$UD!xi!imDp2u|Kk(Pw$*MX*!FQ%A*uD5f z56lzneDh81E`NMUouF60-ti-+Xhq8d_70{BpcNSP9HL|c?9Uq5mK?ckX_}`FxIcRR92X3~UuFiq<@8liLIT(!K-`^0fDyW2o)B$R(?7 zid~gY9Rw-!qPNViLd(L}{!qs*(IlY4=b+fM2OBJ}wA(YZFEG)Q>f6O(!|bJkQ#W5# z@BeNcw-`#7`dNKE8!rx385iiSpy*LjqHJ_oUi@OEVB!=Yon>gzDB-+z}X8@(<-V^#GGH1J8@zn+p1g`LLULS&I#$R15YxSQn6g#h`D1sfkBG zB^cCcR^*UagbP;Fn>#&UXphDsPf#MjzGRW3-hq+3SwB%QeEEu?_M=d>^ZQXZ;SdN3 ziqNu)Bu54T+}AM^1kF=?*446~y#C(09oXTMULWV#9_lt*wqf^7(3LZ$LkcFi{|R35 zp97uR)nv9$ywK)@)U?&S!ZA+V2DR-YT{Gg5nUyy-dW~zd#4)O63xT@EUhNq1KZXd# zm{if@lAItE_!1}}D%zQ&?q)DVgZR#YsdO7T_>pDbK#wl#hS%0uj?60Cz_mRIiX22m zuE*ApQ}!lMlKYHB@GZwXNt;wVMaz#K+aleIEjcj2?l(#Fi*Lq}><{Ue>4E1y;%nPj zlzvI67SN+bEQm>&3{07%ECw3$N(EneLbuD!+iP7Gk(G``>Yfz4OdX$QRg{2St76x5 znFMS2s;}B}rtXO)9aB;*C@UpFqY?|neUtI^Yi>xWpy*ZJuB?TgH{K+1%`U#ef7%=?qt zQL-bn{t@iz*E)RK6#o$LWVC}{*Byja4lfbVG~`!4*hETzQuLD04r1{17#aMgE!z-I z8*K|bwy6TOaSHJ02hQiI4l4NRA%fyd`Pn~oD}r1rr5B<{MVGJjZh{E(PB`AqCu3YN zTl_WZ&}DsK*o;6$A8I_qXS_vKP(je(LGB1FwIf4j=_`KM>EqVzASM%S52i|Xp{&Hb z352}GCN@Jl^umJ7kLs0&4*0{y8pCU_e4_D%Ld&wUv`b9%sc^W>?Z+@GHgIqV#Eocj z5_0m94Z8%Ml;-Vd3dT5ujxVUmDyJMdl?U0_LTjzK|XLe4bjXp9FoGJB8`#+CNg}62gAY9i1|q9~ zgkE@-Pk!NoiC^$Zi$24YJE$#u!1?9&$OL3CC^IAHtw|iXLZWd_a1%rpMFamz-T0A<6>C3|+ME~@nCsubCbosD2KvKLFC)r!cjyklt~|_J+(oyej`S55*s75Q zje0F?o;bZw7+T1cVJS=AcDL6gts1Rkqqv&0O4^tfQq9ea)FvO{516BstLf9`Bm1t# zA~4cYG)zXYKszlsf&mNsN4hpR_~lbJ`6aH1S-1!cgT{SOG%QLbo4Zz7r0V1#Faip^ z4i4tW4t)gUx@67_Bq;e*WZMc)$!*)aPAjsDMA&&389wstEJJUcc5)S*P*k!V{D7lF zf9rFWPjx*NeBE>eefh!dDvu7|;2-=%av4WjP3gj3+D^_w?{>G0HJg4eIguylnhZOk z37yLb^( zF#uWUF7Xk);xcGgY8C?qP|?Y73SnLeH|1((8hc5=VwjWxx5Cc2)X9sp`FHlL4I7NI z<+?f5Hq$bJi>caQ<@jfXjj~LM?V%fLRajx{^ghwgEWrVs(|;TpL?=cfmxB-o0+%^; zh@94<;D?EptHq6lAD%iLj4=c+f)1x&d1-hDGYRP!A|7NZi0ZVfFAs<&bl6UrPZGh$ zzv@v)an4hvrbRY-tfNkIrp!;eClF_+=)fTxps`-jjNqt1|3r_9RS>HeABf29?Qby{X%Qw6ySY_;n%PV}+YGB6uh?+T*>HG&SE z(Bd`lq>|s|h6!mN_lfjFkL5)LS0&46+VBh*dSQsnFeL}yb_MjNIb$DNr-eYu=7UVr z0Ko@PC=FPuz#CVf(U)C)eAaD!kWp%57rx>Dr%3qj9R|jq!sK_WqZViup?53y*B~tm z6}Il0?`tsN*cqR;y*0OMQ9E)g7$LBCsH|tc*};L#!YWWfqhvV}&stdFPz%2o#=_S( z)@hOSU7*54uYku}Xc)lWB`TQ0=U@3yIlDeDWbDZF2dsi$1rskE-SJ#UA;4tbnU)36 z@=FJ#=o$g8gQRzhO~-DKfahy~$nz;&@>*EaDh?nBqP{yRK zhPEMR*irPr(d7VY9R1z_GcwmYJ*~bh8fYtsQqPCJ_SlXt;TW&_E?uFOUZaF_fCg^Z zlogpY=bXZGhJUC(&I62ZC;IhqtZzmA%L|MQz>6mJq`!b)2QVp;ya>877YzorW`sTy z7W&HT===z~wCsqlTFI_*bg!@-&!DqS^Le>5t&i>QGGqFT-PmQC{>fr`w6OvRuv~!8 zsY<(SC)0gb#`(0T>h>am6?zsR1q4zp;_ZF&p|7k|)ya!LIMo%C#9w|PfUrna(7-yuP!x;245;6oZty%`FQE3I62lT-gbiK5m@pyIe6In{*S< zM+9!w$+?4;M3dNS;7>HZc&%6B>5VJC!6pHhMoQHy-S||eXKS&xF3IB_kDaG<&OAG}38@l%`2bnvaO2BJqFV#O%43=no({D?Ts>}#mvUCNj36_6x3 z_8B<_Y*Kiy;WsP;BY38sw0XASmlqhf&3;!v zdZ;>tj-M&83Hdoot7T_9ekx0u1PtnZkEGcC)M84M&=?F$(;^lh2blr7 z#t`90JWwDGatI>IdXaJFs7P?kktI8%3W#-=rl`Eov%FQ=S=&^>%I|4qhbWQ+4IcH# zZc9J~6c(*%8&>ef9n+(88P&uU-wdOI7f;n0DJcvIlz)u&x{b$geff z!0MhRa=5JaBnd>{5frv50V8n)6&_nGM}6tG#y0o`6BZ?w=QbR^j6Fc!f8|~2 zq<0usw7<&NB^Ta~f`<{=Al&!<)4Ngfa9~_olS%nd<1)Zjx`%it4~xLcNtwZRhVAP+ zJ@?8ky`?-nJJ?S1O1I*NoMnKl_{Wwb?;781|KhWa^Hv}4WacOlc^p}@Ga(SII}~il z5k8}T#rddS{T4a47g@5!9wtzz?wf8DD3F7$=g*frT1DyLjQ#LcWh|)X_eur21_(EA z5ga`w(MJi`a(WdD=}T+`Qs|LK@NsI{&p&!GgRboL?o+hT@rV60s!`0N;I7ys0YS2UO|+gCdGn}CB) z^lNf0ux{Uqk3X-&DlkH~(&BmgeogrL0tO#M^5Y0-Eh{oJh7xoPUjyGlZyBjWWBHw{ zOd4`S$EkgA)MW=$p(%R4D_H~t&^14p@_n~O_0ps~?TT!2@CeEW0ZA)fuvJIOgTL`% zCC`|3S>wg0S7n0}{fy2l$ux zHEo|7DbihWH|yT$*cDDqFc6HH)!%oV#s>Yu#Z^X zjAEg6arqK1j=a_Ah2v0c*(+?eVTJaQqd?Q%3u8bIb7%}VSa9cLwX0;*BC*QW;_F3t z?Kc`#^401(%3fH|!k;)q#y1N;yEF`}YjT#LItvOmlWSil0tGGiBg8p!jT0@-a$jrL zmbQ{RkZ_t#<=RoAt880$Ro1I^gR(uf=PX&$8%?WhNpj*;(<=pIKT|1P&(Wn%^s~cz zrg}ZhPn&DUNbb|BIqj;k_nZJHW$=1u*mA;S{lMfm|3NP+tgC4OfJ2b}T{a)qHq3^< z<(G9x20h96yBLFXGk*?1luSGVrRf#W3?>jR!Hr{^LvRyLAnk}+j^(P{dMkJp&q0qW z1m-Dw8PD+YR~_ygTB^vi^{UuJ>{;oX2V(Tu4(v0RzDPJfbktLZhcY?vN2b-@(XW!_ zAbb*t8mCcsNZDc&YXAvTmG#Uu=xx8!hDXVXJu6cm1h1fb%jKFlsJM=S@c~I;rPF`8 zDOPSQ#Cdlae@(`Yc?0XgcUE_nx^kXz8|yDXD}RuCIR)L(hi{*Y??T`OKqOfjBL$k) zCSMfCQM;zED7eN)f(E>5{IddSF)^p+B#Xay3*I2k;FL+lx^qYtGl9@?QWYx+UQapb zu{sfw93&7Lt3Ub{9`9Rw$iPN>Bn8058+gV%u%sS3h8)@hmWgA1MIH4Xuy zw>IF8|c+(iwJd`0?l5Iv7n8;l4hvJFZ)e{W*XxpF; z;trJ%*ATK4|e8D`-o zDq24VvM|kn1F-ZUgMF6lGCvMX)S^tK?S@6Q{|ja#cocyI^cC+Bv4zY zmDES3M0IJ74Q#oRvK#y6h0Bbx*qjix1p}_8qvS_;77wa3AuY#shB@7~OGg z-`z)+@2EZKu0&oFauuD4y~1XB4%(b51s9nsZ=FJ!oNI}NN2`EA;XUAEmQ38@`)FR) zh@d!E-K(r!*>^7rk;%QISz(cl>%tQlrl!2|q+ISUBSYs}_X9956!J-(QVnP2!;c)k zix$7*Kl~Eiz_LgJ^WCNd3+rG36cnW(oys2WkbB0BDyA(=Y_w}v8)2cY0L9}LB~F&8 zFVM$hdD!J(BsXctZaD3+j1;J{*sN}HBxUGZu2wYOanfFQwIz9SaAH6vgsrTz2=pb;l&x~AmIa8 z&Aen3u_y4+e(~{_RAU-}?IRU|B^W@rmJ@g^0b2PFyO7VAs89J6I~h;eU0PQAGUX8@ zB}cDKu$+2Jy8d z+{9)K;=^kU56D~C-Y76G{2z)xg9jM={2t)F>DJ(43ZZ|`Q*jih=roC0?50GBE>8;<@BAK?wK;QoDTopL6j+wE-s*Uv zH-%>oTrhTGA&S6Wl)&f;X9dyFkz=c9@I?iu3PPOPeXT7s?7kK%(#l(g5Eb}nbL}MA zK|Xt-MN~Lo99-a!QMZ2Jf(72~qJ6ZP1sFVK2R&%{gI<45%Ipu!FGzt!>$CuoL)!{d z?S#gQbbPd_4;lgl0|A?q)3>m}j}4K7d;;h(kO?L_`0|1K5Dbxxyoelu@#F zu(oy4hq2KuY?l|CklgeM;N}S}?KdF2%G(D8E;!bZpp886=LC+lL7hoI)K4CG>%iE) zKZwnoIRH169q&r^keu+ZbUWB8Gvy4L)SdTScezK?Dm%36a2pFqkay&LX2_H~`B{@R z>Mx|R0M>5i5_ds7087JCTx1VPDiD~~RMq-sB6`VOXcjSID@iMC?jm7gB3B+ATDlt6 z5Q*^HV5A9Y><%~$$--Tac5tn*k{1_>ENTF8=HguVNys1oKm?4sZGox&0SHHsA;%_z zR56EN>qeP?)i2;NLF7`YG6nvz*CflApqQbQ@n;@_qF|J(4mWiLHU%l#{_HjHg(c7_ zP$?)Tc$>#G9R!ilfh|E48V6$WA~}K5aLFV+g$LpAv-8Dx%2;BsOA}_U)0f$nz=*f~ zUpdrX%(d79A9Zw5S8lMYDldVt`h@WVat52o;D82P`IUeuy0#}lZxEF ztDs8lo>tj{+WrM^(-+<1^rDDtwAXqzSG18-B;umAxi44OpS0yxJB! z2IYq5?E~Ycu|0)`QP&GcbI)`S%c-U@wB!2O=oNOBOntazA`Ob94Sr}5F6fX?De9XV zxC>}oWX#Wp&r47}L|f!hu`<`dT_F#b(Q{5a*=HK+MOWX5xsHi1v>7GU7vmQeC$b?5y$&w^Kdy5NT{Zb%)!db(zV?Qd;_L{$?4U+;}ze7d)+th zsN$dr%)3T*j{HIAa{XpyIW}$K60;J+u&XL$ohpS&}OW}Z$ujU5FvYy}oRVE8Ay zz}TdgFErKfljm56$M!XkgW}*9jz4yFVq;F@rP4WVw%yR)uTc(J&H^$xQ2x%*G;r%J%Aqx-3x#XAQx zb)?V14a*>ljlW&?ef^XWE(BL^LuUfPXuECk4uU{YMy$SVkj2#KH+OxB{34i~V7664 zkW8TS!4foOtmS|upn36y)!GC-hPK3RuboB5=aj z0Oy4d!XM*;if2J*D_0v}=AM9aY+4x-xFSt5CL{fZJ+ffJT(ZSoyw5Y4^t7 zt)LBX#~ZsZ$WLyu=TEvn>=-Y+_MZ=sLB)XO-{~|^fQ7CI>U#%U@hm>)v=Qya*K|yf zp6=@!64<&DL^459%iURxPYWVrHK7*AGigae2C_)C&>iX4V7bF*=Xw08u9D$}ay3L? z2Z#lh8+-U&Motr#ZwX9kX|?6G&NFjOkVMP9^P?;}(<&!$SG{+O;1%@r&OPUFQxA^= zJ$fY9upw74gLQ3{j-v`)r?tHL=dzFG+Xk*r%fO#N6Pe+4pLZoRwaco$wmjj%aSEJ; z5YvFemOzYLFTw(HFc3RxH_5K9Y?$y0UL^-X;@|AZFs4;%V4$ zK4Ok^W^M8{)6!d2WnI!FUyqs_(Rv*%T90qGk!~+`VVOd-(aSD|WhRKJJ&?t08BuMG z{ZJ>M;a9_9Y?m0%m(pROYJx#8JU13P||1PU$1UoIU^=RN{9ZcWw#}P+AB2 zNd!r&(ihm!fwL`=9T>Tw4xTWT`~?O!aFu=FM!n(q*0snKE{QhyZ-oVUE1x1RsTNt- zdo7iPN9=A67R6bPxCdwyG-#IcQ8X^ROor_cm!tm&g&7stv&?f1vuwiRdf`IJ zHqSIi{Hk<))eYZc5|%7t%}O8X%3PH*k!WO(6$g}|q_~Srd>K!|C-BrRza0ylkLjl7 z@OjKjSnX7i(UyobJ55wu8gvR$_!0dMrQwB$cBsy4>`0yy5GwJF4bBCNtw!prf^g9S z!^gHwWshOxQjWZq0c~KElXkG+$fL=0sjLJkx4u-JAL!%L1F*?x=V{%nMjXVg6}NQ- zsJw%nNG_`DD7(df2#gm}J^+3(9+(3u18#5HqyvAOb}!-mK$&Q}x#Y#P7mU)(B2%SW zuxnyvK-c14N6~3(?JSQIkmZ8i!9}vrBQ!ftCW`fVp=#f8Fp=Htk4IucW z-nz4J!40GzNQ|LEo7yOvQ4$&^!a zv9WZlx=YHH?>1@0ZUdv}G#X5{F6imj6;?q{r1Y=H+O!`ZGgdqXqqJcJticuaqIZX1NWaA!6%J2u60vhip^F>+^$69reCiHv=VsKS78Mc ze5dP1C+dzoWlf!~tn&2F?8CzFJz-gpg5yA7-KDOsuqk?(Lw3=Y1OYEZSMq61?CycR z+6XKGlc2~8%>BnMQUQnEAGS=MY2y>E3}urR`yL*p;?jS$i%eh8Ql+&KR5vg{3D%a{ zeotE%FH?8xRTfRFAM4a}3qY_EH#0qdt~;m|wD@%r&Nj>-SmO@5?Bpm9-IV#91EZ7! zOJBo7g0JRG1zLQHUiA5oPR^Vvmf?Hr#JTvaoLm&hOp}shRRaOV-sDEx@>bH>z%St0 z?-MxY{RB-NtL|agLO6Pcrp91fxe^`9JG)kb9exK}d2W^0vvH%XJ`jz)#r;Ns@s{Eb zI1Sd#zVQ+>8#C3$l^2hFUA$Ys^_&XuA0`?i5t;f9$gN2 z72Znf8BMc9ZKS9t^w+^;%n1pMi329i3XE84<(BpA89qmf7Ha*@r-R~P7EgCvc5)CF zwb_d|fvx2ri+~qiC=p{AW!sD13XFxLF3Vu<1by@kS&RYnKpZ+-59taE_6_oujkHzI z8%X-~vRur~42s#LznZ|9VRPBU+1Q6lk+ITkvp=Spi=Zm5cC###nCzMGSxAezzE@aI336C4 z*4I&3xvE@rJA+!bc%eBYg3QIFnG}0XjF7{HU;wAF>dOH|AQOaO7I9ZHaZaO|b_C;NHnfa2OIVKA_b}ecjyGvf9_w;$oQ=3M!QxMy#$78l} zF2kc%)Q<5u$E{1WkQ4N1|IiN~0d~;?VI8EUQK4PcyEW*1RFv2ZReU$`^< z5b&aR*kn7;gkgBI{BCJ?6TX=p7wtcY!9g|VE*({bnD<@+<6!_CjJjUg@$6ukG^?bQ zZiioKZ7v3pvEzME0wrh6gq&?y%{GL*7s90%PkZBKpL-x}6 z0TYw>hSi>(hTyA7)vh!T zlSj?_$NmDR)$Plx;r{NBcUsC40-+&K7szAL;M;0(Ye+M-UoWw zf=$TepA;J@Ti?M~K#Rsfx7*UJg?!-qp#K5d3$(`7EnWA@zL)MoKLGmRmJwWBuoF$( zA|?YR^uL$D*xG&-Ssa0}!(YD&%YS+!$3o*3K8xGpwcUtZ(8J;lY#t>KszYJ9hhzkp zjhMkx$Kls0z(8|Iv@0uG5Ib0KS8~EjWXB~QXJ>Ox>LYFqG7}bJY%J(lQ~^~)P>V#@ zq=BWUBCEOO$GQUPfF~d}U+h*Tdpw@89QZ_bR-wpPb#R6ur%HkADrcd0a#qG}OSL2I zUI{MCwV1YJ+5x)-HfO1ky2ArATsC;8Ouf~4Xf!^&YJ9|G9!m- zkxqOK#TvBv^&H%p6Dsl}-KC_J)@2sCUisFxq`calvMoG|UgTWp5Fqka z9Q_A;ea|OiBYNtyfM#76qoS-f7ksOyonq=64vZgAG zTgsPIbWdzseIK5~snnKCd`(m16Ep<2ni4q&SXT4}m^(_{kQOvftwI;!YD-!ZcI?g$ zKl-4#2#kWw;I>HVVrBX!$i`JvTVu{lm<~Ja*SWLE&NFs7Z{L^f1LjbPI)M1}Oh53# zrOb^s@mu=AxoEP>f|#EQGmpOFA8osK#+VMw@X-{ohal7(P z-VV0%uI*<$LSJfYq*VKXP0OqNj(3bx{Aym6Z{aSfuS0fn)(Nr0@1%t%`Htp3*h3nl z;UT)#rdj5|`v*BMGlkgB&X)t399M|a#4?%h)&)4GI;~v?y_@UFGS=!8x_bRG7CR?&p*gq zV$PNqlyAqd4rGDa{=gD78d-POCTz&G(1qDDw;ot1_Qh*fuKj_}d?)TA0=`-_=gx{= zjeoLm9u6ABL?A8RDa>*N9aAqtTF0cU(mHx#!%7p~D{PjR7I$%hOtQ5U0(Z6$sSg?u z051?taS6YK3}O4iqZ#&M480|5#i?24>$DGU%4um4r$64=j?o%Ee7&^?+%dhlWx={8 zblk44#U)4Rp+(Mi;cSAOnhZVpOF!GTLXPEebAx2(8so4*q`5gKbVu%4+pL8Xxs-}- z9o-93#q|+}V9tIBoZQo3*YK4n<%f)H{9)l5FoYcKrj{77_UmRNxa`nk3~im|QCfcg zYRFvF26nKqnQc#(<43Od9Txx4E{prn9bP-N7MS4dhWIZzNR{g>>eN1Wqv3|^C~sn} zmv*OeL+v@$ZSYwU%`f|;)%Y5$OybmZbf>S75&w-~*MfmNIIiXbTMkal+kFx_v8!a~ zL~KE!37yAs%Uv#2mdTQy--wL1N9<^%IItHiKjZR?o>9|K#6FG(&S(|5CvE{Glhu$Ov)+_9}= zX4So;RmWa{FMD&6(DJx!<-L?LdDha5fmg;^2jX=M&NB~^v{5vAqZe}f=iWYQMdgO0 zaJRGZ=XqoucGQul9w2FpIwLq8saB7i%YFUw3_jHpK-OmRZdxbn?ed~HV}W+HY0JD8 zr}#Zr7oLQ>n!|?uCJ9>1V=+^444F~)|K{K)TKRX4p&y0wi7d<(FSQ`Rub#^>FkH)#%K0Y~=4?o_`^@ z$k}7Q^I@^BAkp|XN@_)qq(|pFa~>^347Zwa3paIjf1SH+5?m?WC*91uMX;s1ulp!q zw~Do$(0~DA+vJ) z`Q&e;?A$yixsYePMQr56q9dwm1W0a7`26$F7E^^g63ZCc8c8!Bu+^9WoOJK1#5g>s zEUITX_40K5J-Ne!wB4!13+L{H1H0K)>5b}Z{CC0UIE$O@g?7c^gRW)|bnThq>I{5$7`bpKM>_{8tK2kXc+VJkk zSDCx=Xp50?(2nw9SY)L?wj5G1)_^8_FfeWf()iYpJ{+TZtNE7;OgqjN?%>BR+EMIa zi{z~{7d%C+2Jz`}z_xZ&jAH3arye93^?*GGh7!x5ex{d6AJVbm2h^yXRE6aTKGp{B zn-;d>qWMxNds1KW(h*HfsA}xd zs^$l3B3a2%6wo+Tje_AtqZ&u{(A0z}yxYf3K~pjGwbS z{4FE$Xwrj$@#i%7Kcj92S&njcN6EWu2n4e+7{~b5FkO564rlIU-@!IXS~qrcVvH0U zXw$H9a@<{toQD`*KXCmaKJ{c??7b!zz1uq{#Zc^)bd7z$39dUigJ3D-Ek6rrUu>t? zjyQK0#rNDBD1G+GL9>x^0Bt(1-F_rPb0c!25lss1&3={12`~qtscgoc`}N#b^u>?i zRUTOFrOQ9rMS{y=R;f#dc4(U1+-1E{jWNZ~Cf0*M;wVzv|2Npz>20|FVIlwqW5| zVQWKzPhPmMGC^qc{47i(_ABTynsda!Ux~DiC=Y z>nAu>qi*1jET!NwtVs^0w48&u+?l!p+iu2X)}ff5-4^qFwL5Li{6E@tySB;+<#8?q zI`bXR#NIAFWaHb&zO9)qh$mOd%r$U{I)SZpm*ro@j?qotHvF$HFT(W6*Fnc4sG%&d~;CE8K5C`9#ssamOXh_>3bgJSk$71`h}S$0{zv+cd!$NzCM~1Q$$Z2BKZ;dBIm%R#@eQ7*g)Sr6*#D96Fa8r ziP&1`t_hc2hP^kxTFQ}Y5&hQ1^ktn!ufDtNL414(UB_0A?I9c8HIDe{uWEz!;Zs?j zake%hKDF#ec4(1b+PTWF^7QAbVnQcJ)-VQmBnK7<^_4et;V~|bo}z^wl#)HmMKU30 z%p&4Y+|uoUJJ>;zD)-R9v$WwX0wF`p_$@LsHR*ki>sZPhRK+W&u099&{H86f@}BH* za@q_rrLp1P^!Y)3=vLsKhXF>5d4{F5SS!R_lWPHGNqtXi7U>~OE>tGmLgixgoZ-~7 zSRHVZdDb~>6yX_X-kk#uLQ|2I)vN&I2Tlhk2ux(`-r6|0ueW<4sp7`Qa$kL)pKZI~ zAH8#lc^J}~l+6~dT!mjDc-n~xGnjUCN3N^2gPes*e&O%h_*s-MOvj@6eL7a9#l+dy zjQ1x`zWeTbkNX!d`sbFqVUzAC_g&PcJu;we%gX}}@`sNnlw*ZvnZT>1qD0>qvs3xt z!dGvaYEBgY(6JRZb*#P}myWhP8=&luq~uUVw*$Wr*M?S@EoBuT8Lq}Z$u}mPL0K2h zaO$^kEB(E67#6>}Kt2gIDPNAR_p^&B;AhU15qh+p&Hz3}mti=B5DAq(oLXt_E&Z?7qR#{saIGXtc7CEPqWhvzEczVhyc1G{J2?vp0p$kYoz zUSq!A{5^+Ow%j>7c9DC^+t5YMj&NN-gD=<}2CMz_JD=w-`h<^Q3AO|n-k179INI=x z^Sg|_?$^*o@4L)19#@$e%Lkb4J+{@gbZk3l?d#pOS=#hUJOq!hu6o|CJnb8E{BD7= zDc2Ymo&*VO9sRKz4B-*oIFP*s6K>b9E3aJs*ORhie2*=9PQPSOrQ-;~J4e4OJBFS` z;CR6S6S&9ZZc$xWM$z(`XB?q2S)k~NV`4Z`IE9>mXSQ_$emuE}F0QENoYcXlGGAr+_T4 z&E1{!xbKpa)JJ9^LEsSn(;3F@w*BR~joJ!>3_b^0i$9ype;=^aov=HPh|L zSd6iv+wG{+AH0h1KmPI;JyP@R$!8yZ_T;&8g3n-oDNpLBsGjQ+yB#dsxIxFRvz(dP7Z{EdeA>_Gh3 ziUiH|Y%+7uTJmLYkK*TjVH*2K8_thQo$MNPQ}nRgZAynGhkv1^_?Witd}14DXU;&K zfe&1}D2ygKZIchyYXD*4gINk4xP(FR~w}1P$X!SzsgBnoXp4}-tqnGxUO|s=; z^;S!1Fe&P)cKzGu_AZ1E`g_F;1`5~39mrC7Bzf4Rr#KJ%Y5$~pv(iQmdhqY?@j>#z ziUa0c*^S2myI;&%?1#EM5cm0UjWG+}XcYg#{F#6lM8Oj?TcIG=T+t&p zOzgL-Ob#}A7{gc+U*nEs11I!^*Roc9X4mr4tJ$ydvB(7=Cq*+fcah;mr9A6>f)|Li>(PT+ylG1*sPD+5meUX`EVN}-+cs9Q+5VUv`g8t}?lXPW zacFhO3z?>sE=bJ zITj%^U2~A%f>#@dF7ZUpfE^06tq1U_Qg4ze+UPD@jxe)DJxnU3-LegPXtyB_Ze>9SNM7k1NT8Hb(ga{koI0gB^4~Fj7`pm(|>uv*K8< of!m)uf)L-riDtETEyMo*17FlzZ1-K3!vFvP07*qoM6N<$g7t%U-v9sr literal 0 HcmV?d00001 diff --git a/docs/explanation/raw-sensors.md b/docs/explanation/raw-sensors.md index a96bd3a..8a3b859 100644 --- a/docs/explanation/raw-sensors.md +++ b/docs/explanation/raw-sensors.md @@ -17,10 +17,11 @@ You cannot change sensitivity while remaining in raw mode with a different comma ## Reference frames -Axes are defined relative to the hardware. See the diagrams in the repository root: +Axes are defined relative to the hardware: -- `TAP-axis-alpha.png` — Tap Strap -- `TAPXR-axis.png` — TapXR +![Tap Strap reference frame](../assets/TAP-axis-alpha.png) + +![TapXR reference frame](../assets/TAPXR-axis.png) Additional protocol notes: [Tap Strap Raw Sensors Mode](https://tapwithus.atlassian.net/wiki/spaces/TD/pages/792002574/Tap+Strap+Raw+Sensors+Mode) (internal Confluence). diff --git a/docs/how-to/connect-and-listen.md b/docs/how-to/connect-and-listen.md index e9ebbaa..9289094 100644 --- a/docs/how-to/connect-and-listen.md +++ b/docs/how-to/connect-and-listen.md @@ -63,4 +63,4 @@ await tap.run() await asyncio.Event().wait() ``` -Or follow the pattern in [`examples/basic.py`](../../examples/basic.py), which sleeps between mode changes. +Or follow the pattern in [`examples/basic.py`](https://github.com/TapWithUs/tap-python-sdk/blob/master/examples/basic.py), which sleeps between mode changes. diff --git a/docs/how-to/migrate-from-0.6.md b/docs/how-to/migrate-from-0.6.md index a79b385..5cb6765 100644 --- a/docs/how-to/migrate-from-0.6.md +++ b/docs/how-to/migrate-from-0.6.md @@ -37,6 +37,6 @@ from tapsdk import AirGestures ## Examples and backends -- Use [`examples/basic.py`](../../examples/basic.py) instead of `example_unix.py` / `example_win.py`. +- Use [`examples/basic.py`](https://github.com/TapWithUs/tap-python-sdk/blob/master/examples/basic.py) instead of `example_unix.py` / `example_win.py`. - Windows no longer uses `TAPWin.dll`; Bleak/WinRT is required. - Python 3.9+ is required. diff --git a/docs/index.md b/docs/index.md index d121fcb..d01cc37 100644 --- a/docs/index.md +++ b/docs/index.md @@ -15,6 +15,7 @@ This documentation follows the [Diátaxis](https://diataxis.fr/) structure. Pick - **Import name:** `tapsdk` - **Python:** 3.9+ - **Status:** beta +- **Source:** [TapWithUs/tap-python-sdk](https://github.com/TapWithUs/tap-python-sdk) ## Platforms diff --git a/docs/tutorial/getting-started.md b/docs/tutorial/getting-started.md index 65e7645..8d99f1e 100644 --- a/docs/tutorial/getting-started.md +++ b/docs/tutorial/getting-started.md @@ -85,4 +85,4 @@ In Text mode (the default), the Tap behaves like a normal keyboard/mouse for the - Switch modes, stream sensors, or send haptics: [How-to guides](../how-to/index.md) - Full callback and command signatures: [API reference](../reference/index.md) - Why modes and sensors are designed this way: [Explanation](../explanation/index.md) -- Runnable sample covering more events: [`examples/basic.py`](../../examples/basic.py) +- Runnable sample covering more events: [`examples/basic.py`](https://github.com/TapWithUs/tap-python-sdk/blob/master/examples/basic.py) diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..4f758ff --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,91 @@ +site_name: Tap Python SDK +site_description: BLE SDK documentation for Tap Strap and TapXR +site_url: https://tapwithus.github.io/tap-python-sdk/ +site_author: Tap Systems Inc. + +repo_name: TapWithUs/tap-python-sdk +repo_url: https://github.com/TapWithUs/tap-python-sdk +edit_uri: edit/master/docs/ + +docs_dir: docs +site_dir: site + +theme: + name: material + palette: + - media: "(prefers-color-scheme: light)" + scheme: default + primary: indigo + accent: indigo + toggle: + icon: material/brightness-7 + name: Switch to dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: indigo + accent: indigo + toggle: + icon: material/brightness-4 + name: Switch to light mode + features: + - navigation.sections + - navigation.expand + - navigation.top + - navigation.footer + - search.suggest + - search.highlight + - content.code.copy + - content.action.edit + - toc.follow + +plugins: + - search + +markdown_extensions: + - admonition + - attr_list + - def_list + - tables + - toc: + permalink: true + - pymdownx.details + - pymdownx.superfences + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.tabbed: + alternate_style: true + +nav: + - Home: index.md + - Tutorial: + - Getting started: tutorial/getting-started.md + - How-to guides: + - Overview: how-to/index.md + - Install the SDK: how-to/install.md + - Connect and listen: how-to/connect-and-listen.md + - Switch input modes: how-to/switch-input-modes.md + - Stream raw sensors: how-to/stream-raw-sensors.md + - Send haptics: how-to/send-haptics.md + - Use Spatial Control: how-to/use-spatial-control.md + - Migrate from 0.6: how-to/migrate-from-0.6.md + - Reference: + - Overview: reference/index.md + - TapSDK: reference/tapsdk.md + - Input modes: reference/input-modes.md + - Enumerations: reference/enumerations.md + - Events: reference/events.md + - Package: reference/package.md + - Explanation: + - Overview: explanation/index.md + - Connection model: explanation/connection-model.md + - Input modes: explanation/input-modes.md + - Raw sensors: explanation/raw-sensors.md + +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/TapWithUs/tap-python-sdk + - icon: fontawesome/brands/python + link: https://pypi.org/project/tap-python-sdk/ diff --git a/requirements-docs.txt b/requirements-docs.txt new file mode 100644 index 0000000..d752c76 --- /dev/null +++ b/requirements-docs.txt @@ -0,0 +1,2 @@ +mkdocs>=1.6,<2 +mkdocs-material>=9.5,<10 From 2f8e36ac2d9386c1c2a7eca42683ae66d0b79d96 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 21:21:43 +0000 Subject: [PATCH 4/9] Add Cursor docs-verify workflow and enable branch testing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a restricted Verify docs Action that runs the Cursor CLI against Diátaxis guidelines on PRs, with sticky PR comments and a failing check when updates are needed. Expand Deploy docs so PRs always build and workflow_dispatch can deploy from this branch before merge. Co-authored-by: Liron Ilouz --- .cursor/cli.json | 24 ++++++ .cursor/rules/diataxis-docs.mdc | 40 +++++++++ .github/workflows/docs-verify.yml | 132 ++++++++++++++++++++++++++++++ .github/workflows/docs.yml | 19 ++++- Readme.md | 2 + 5 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 .cursor/cli.json create mode 100644 .cursor/rules/diataxis-docs.mdc create mode 100644 .github/workflows/docs-verify.yml diff --git a/.cursor/cli.json b/.cursor/cli.json new file mode 100644 index 0000000..a592ce2 --- /dev/null +++ b/.cursor/cli.json @@ -0,0 +1,24 @@ +{ + "permissions": { + "allow": [ + "Read(**/*)", + "Shell(grep)", + "Shell(find)", + "Shell(ls)", + "Shell(git diff)", + "Shell(git log)", + "Shell(git show)", + "Shell(git status)" + ], + "deny": [ + "Write(**/*)", + "Shell(git commit)", + "Shell(git push)", + "Shell(git checkout)", + "Shell(gh)", + "Shell(rm)", + "Shell(curl)", + "Shell(wget)" + ] + } +} diff --git a/.cursor/rules/diataxis-docs.mdc b/.cursor/rules/diataxis-docs.mdc new file mode 100644 index 0000000..fa5bdd7 --- /dev/null +++ b/.cursor/rules/diataxis-docs.mdc @@ -0,0 +1,40 @@ +--- +description: Diátaxis documentation standards for the Tap Python SDK +globs: docs/**/*.md,Readme.md,mkdocs.yml +alwaysApply: false +--- + +# Diátaxis docs guidelines + +This repository's docs follow [Diátaxis](https://diataxis.fr/). Keep them consistent with that model. + +## Quadrants + +| Quadrant | Path | Purpose | +|----------|------|---------| +| Tutorial | `docs/tutorial/` | Learning-oriented; one successful first path | +| How-to | `docs/how-to/` | Problem-oriented recipes for a specific goal | +| Reference | `docs/reference/` | Information-oriented API / type / event facts | +| Explanation | `docs/explanation/` | Understanding-oriented background | + +`Readme.md` stays a short overview that links into `docs/` and the published MkDocs site. Do not re-inflate it into a full API manual. + +## When a code change requires doc updates + +- Public API, callbacks, command semantics, or example behavior → **Reference** (and How-to / Tutorial if the happy path changed) +- New supported task or platform install step → **How-to** +- Conceptual behavior (modes, connection, sensors) → **Explanation** +- First-run experience changes → **Tutorial** +- Docs-only PRs that already match the change → no further edits + +## Style + +- Prefer clear, unambiguous language; one job per page +- Do not invent features or UUIDs not present in the code +- Keep MkDocs links valid (`mkdocs build --strict` must pass) +- Example file links should point at GitHub `blob` URLs, not `../../examples/...` +- Axis diagrams live under `docs/assets/` + +## Published site + +Configured by `mkdocs.yml` (Material). GitHub Pages workflow: `.github/workflows/docs.yml`. diff --git a/.github/workflows/docs-verify.yml b/.github/workflows/docs-verify.yml new file mode 100644 index 0000000..68a078b --- /dev/null +++ b/.github/workflows/docs-verify.yml @@ -0,0 +1,132 @@ +name: Verify docs + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + paths: + - "tapsdk/**" + - "examples/**" + - "docs/**" + - "Readme.md" + - "mkdocs.yml" + - "requirements-docs.txt" + - ".cursor/**" + - ".github/workflows/docs-verify.yml" + workflow_dispatch: + inputs: + pr_number: + description: "PR number to verify (required for manual runs)" + required: true + type: string + +permissions: + contents: read + pull-requests: write + +concurrency: + group: docs-verify-${{ github.event.pull_request.number || inputs.pr_number || github.run_id }} + cancel-in-progress: true + +jobs: + verify-docs: + if: ${{ github.event_name != 'pull_request' || !startsWith(github.head_ref, 'docs/') }} + runs-on: ubuntu-latest + steps: + - name: Resolve PR number + id: pr + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + echo "number=${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT" + echo "base_ref=${{ github.base_ref }}" >> "$GITHUB_OUTPUT" + echo "head_ref=${{ github.head_ref }}" >> "$GITHUB_OUTPUT" + echo "sha=${{ github.event.pull_request.head.sha }}" >> "$GITHUB_OUTPUT" + else + echo "number=${{ inputs.pr_number }}" >> "$GITHUB_OUTPUT" + data=$(gh api "repos/${{ github.repository }}/pulls/${{ inputs.pr_number }}") + echo "base_ref=$(echo "$data" | jq -r .base.ref)" >> "$GITHUB_OUTPUT" + echo "head_ref=$(echo "$data" | jq -r .head.ref)" >> "$GITHUB_OUTPUT" + echo "sha=$(echo "$data" | jq -r .head.sha)" >> "$GITHUB_OUTPUT" + fi + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ steps.pr.outputs.sha }} + + - name: Require CURSOR_API_KEY + env: + CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} + run: | + if [ -z "$CURSOR_API_KEY" ]; then + echo "::error::Set repository secret CURSOR_API_KEY (Cursor Dashboard → API Keys) to run docs verification." + exit 1 + fi + + - name: Install Cursor CLI + run: | + curl https://cursor.com/install -fsS | bash + echo "$HOME/.cursor/bin" >> "$GITHUB_PATH" + + - name: Verify Diátaxis docs + id: verify + env: + CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} + run: | + set -euo pipefail + agent -p --mode ask --output-format text \ + "You are verifying documentation for TapWithUs/tap-python-sdk PR #${{ steps.pr.outputs.number }}. + + Context: + - Base branch: ${{ steps.pr.outputs.base_ref }} + - Head branch: ${{ steps.pr.outputs.head_ref }} + - Guidelines: read .cursor/rules/diataxis-docs.mdc and docs/index.md + - Site config: mkdocs.yml + + Steps: + 1. Inspect the PR diff (git diff origin/${{ steps.pr.outputs.base_ref }}...HEAD). + 2. Decide which Diátaxis quadrants (if any) are affected. + 3. Check that docs/, Readme.md, and mkdocs.yml still match the guidelines and the code change. + 4. Do not invent features. If the PR is docs-only and consistent, status is OK. + + Output markdown ONLY (no preamble), using exactly this template: + + ## Docs check + - Status: OK + - Affected quadrants: none | tutorial | how-to | reference | explanation (comma-separated) + - Gaps: none + - Suggested edits: none + + If updates are required, use Status: NEEDS UPDATES and replace Gaps / Suggested edits + with concrete file paths and what to change. + + Do NOT modify files, commit, push, or call gh." \ + | tee /tmp/docs-check.md + + - name: Comment on PR + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + MARKER="" + BODY="${MARKER}"$'\n'"$(cat /tmp/docs-check.md)" + PR="${{ steps.pr.outputs.number }}" + existing=$(gh api "repos/${{ github.repository }}/issues/${PR}/comments" \ + --jq ".[] | select(.body | contains(\"${MARKER}\")) | .id" | head -n1) + if [ -n "${existing}" ]; then + gh api -X PATCH "repos/${{ github.repository }}/issues/comments/${existing}" -f body="$BODY" + else + gh pr comment "$PR" --body "$BODY" + fi + + - name: Fail when docs need updates + run: | + if grep -qiE 'Status:[[:space:]]*NEEDS UPDATES' /tmp/docs-check.md; then + echo "::error::Documentation updates required (see PR comment)." + exit 1 + fi + if ! grep -qiE 'Status:[[:space:]]*OK' /tmp/docs-check.md; then + echo "::error::Docs check output missing Status: OK or NEEDS UPDATES" + exit 1 + fi diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 5e1e6e3..4c28b39 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,24 +1,35 @@ name: Deploy docs +# Test on this PR: the build job runs automatically on pull_request. +# Test full Pages deploy before merge: Actions → Deploy docs → Run workflow +# (select this branch). Requires Pages source = GitHub Actions in repo settings. on: push: branches: [master] paths: - "docs/**" + - "docs/assets/**" - "mkdocs.yml" - "requirements-docs.txt" - ".github/workflows/docs.yml" - "TAP-axis-alpha.png" - "TAPXR-axis.png" pull_request: + types: [opened, synchronize, reopened, ready_for_review] paths: - "docs/**" + - "docs/assets/**" - "mkdocs.yml" - "requirements-docs.txt" - ".github/workflows/docs.yml" - "TAP-axis-alpha.png" - "TAPXR-axis.png" workflow_dispatch: + inputs: + deploy: + description: "Upload artifact and deploy to GitHub Pages" + type: boolean + default: true permissions: contents: read @@ -59,13 +70,17 @@ jobs: run: mkdocs build --strict --clean - name: Upload Pages artifact - if: github.event_name != 'pull_request' + if: > + github.event_name == 'push' || + (github.event_name == 'workflow_dispatch' && inputs.deploy) uses: actions/upload-pages-artifact@v3 with: path: site deploy: - if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + if: > + github.event_name == 'push' || + (github.event_name == 'workflow_dispatch' && inputs.deploy) needs: build runs-on: ubuntu-latest environment: diff --git a/Readme.md b/Readme.md index c446bdd..4cd0768 100644 --- a/Readme.md +++ b/Readme.md @@ -21,6 +21,8 @@ Source follows [Diátaxis](https://diataxis.fr/) — pick the path that matches Full index: [docs/index.md](docs/index.md). Local preview: `pip install -r requirements-docs.txt && mkdocs serve`. +CI: `Deploy docs` builds MkDocs on PRs and deploys on `master` (or manual `workflow_dispatch`). `Verify docs` runs a Cursor agent Diátaxis check on relevant PRs (requires `CURSOR_API_KEY` repository secret). + ### Install ```console From 0d9169ee2113e0adadc2e93450641d4794a1a7ac Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 21 Jul 2026 21:22:26 +0000 Subject: [PATCH 5/9] Skip docs verify when CURSOR_API_KEY is unset Allow the Verify docs workflow to succeed on this branch with a PR notice when the secret is missing, so Deploy docs and Verify docs can both be exercised before the key is configured. Co-authored-by: Liron Ilouz --- .github/workflows/docs-verify.yml | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docs-verify.yml b/.github/workflows/docs-verify.yml index 68a078b..04786ba 100644 --- a/.github/workflows/docs-verify.yml +++ b/.github/workflows/docs-verify.yml @@ -55,21 +55,43 @@ jobs: fetch-depth: 0 ref: ${{ steps.pr.outputs.sha }} - - name: Require CURSOR_API_KEY + - name: Check CURSOR_API_KEY + id: cursor_key env: CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} run: | if [ -z "$CURSOR_API_KEY" ]; then - echo "::error::Set repository secret CURSOR_API_KEY (Cursor Dashboard → API Keys) to run docs verification." - exit 1 + echo "present=false" >> "$GITHUB_OUTPUT" + echo "::warning::CURSOR_API_KEY is not set. Skipping agent verification. Add it under Settings → Secrets → Actions to enable this check." + else + echo "present=true" >> "$GITHUB_OUTPUT" + fi + + - name: Notice when verification is skipped + if: steps.cursor_key.outputs.present != 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + MARKER="" + BODY="${MARKER}"$'\n'"## Docs check"$'\n'$'\n'"Verification skipped: repository secret \`CURSOR_API_KEY\` is not configured."$'\n'$'\n'"Add it from [Cursor API Keys](https://cursor.com/dashboard/api), then re-run **Verify docs**." + PR="${{ steps.pr.outputs.number }}" + existing=$(gh api "repos/${{ github.repository }}/issues/${PR}/comments" \ + --jq ".[] | select(.body | contains(\"${MARKER}\")) | .id" | head -n1) + if [ -n "${existing}" ]; then + gh api -X PATCH "repos/${{ github.repository }}/issues/comments/${existing}" -f body="$BODY" + else + gh pr comment "$PR" --body "$BODY" fi - name: Install Cursor CLI + if: steps.cursor_key.outputs.present == 'true' run: | curl https://cursor.com/install -fsS | bash echo "$HOME/.cursor/bin" >> "$GITHUB_PATH" - name: Verify Diátaxis docs + if: steps.cursor_key.outputs.present == 'true' id: verify env: CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} @@ -105,6 +127,7 @@ jobs: | tee /tmp/docs-check.md - name: Comment on PR + if: steps.cursor_key.outputs.present == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | @@ -121,6 +144,7 @@ jobs: fi - name: Fail when docs need updates + if: steps.cursor_key.outputs.present == 'true' run: | if grep -qiE 'Status:[[:space:]]*NEEDS UPDATES' /tmp/docs-check.md; then echo "::error::Documentation updates required (see PR comment)." From 187bb46f846bf8ce834fffdff9e15eb1df9c083a Mon Sep 17 00:00:00 2001 From: Liron Date: Wed, 22 Jul 2026 12:00:12 +0300 Subject: [PATCH 6/9] Fix Verify docs CI: pass --trust to Cursor agent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Headless agent exits on workspace trust prompt in GitHub Actions. Also drop Diátaxis/CI mentions from published docs per review. Co-authored-by: Cursor --- .github/workflows/docs-verify.yml | 4 ++-- Readme.md | 4 +--- docs/index.md | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docs-verify.yml b/.github/workflows/docs-verify.yml index 04786ba..c8d2378 100644 --- a/.github/workflows/docs-verify.yml +++ b/.github/workflows/docs-verify.yml @@ -90,14 +90,14 @@ jobs: curl https://cursor.com/install -fsS | bash echo "$HOME/.cursor/bin" >> "$GITHUB_PATH" - - name: Verify Diátaxis docs + - name: Verify docs if: steps.cursor_key.outputs.present == 'true' id: verify env: CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} run: | set -euo pipefail - agent -p --mode ask --output-format text \ + agent -p --mode ask --trust --output-format text \ "You are verifying documentation for TapWithUs/tap-python-sdk PR #${{ steps.pr.outputs.number }}. Context: diff --git a/Readme.md b/Readme.md index 4cd0768..8561afe 100644 --- a/Readme.md +++ b/Readme.md @@ -10,7 +10,7 @@ BLE SDK for building Python apps that connect to **Tap Strap** and **TapXR**, se Published docs (MkDocs Material): [https://tapwithus.github.io/tap-python-sdk/](https://tapwithus.github.io/tap-python-sdk/) -Source follows [Diátaxis](https://diataxis.fr/) — pick the path that matches your goal: +Pick the path that matches your goal: | I want to… | Go to | |------------|--------| @@ -21,8 +21,6 @@ Source follows [Diátaxis](https://diataxis.fr/) — pick the path that matches Full index: [docs/index.md](docs/index.md). Local preview: `pip install -r requirements-docs.txt && mkdocs serve`. -CI: `Deploy docs` builds MkDocs on PRs and deploys on `master` (or manual `workflow_dispatch`). `Verify docs` runs a Cursor agent Diátaxis check on relevant PRs (requires `CURSOR_API_KEY` repository secret). - ### Install ```console diff --git a/docs/index.md b/docs/index.md index d01cc37..9dc8248 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ # Tap Python SDK documentation -This documentation follows the [Diátaxis](https://diataxis.fr/) structure. Pick the section that matches what you need: +Pick the section that matches what you need: | Goal | Section | |------|---------| From 314152f268b870f1cc051f7842738ced716a6781 Mon Sep 17 00:00:00 2001 From: Liron Date: Wed, 22 Jul 2026 12:05:53 +0300 Subject: [PATCH 7/9] Scope CLI permissions to Verify docs workflow only Move restrictive agent permissions to .github/docs-verify-cli.json and copy into .cursor/cli.json only during the CI job so local agent CLI runs in this repo are unaffected. Co-authored-by: Cursor --- .cursor/cli.json => .github/docs-verify-cli.json | 0 .github/workflows/docs-verify.yml | 8 +++++++- 2 files changed, 7 insertions(+), 1 deletion(-) rename .cursor/cli.json => .github/docs-verify-cli.json (100%) diff --git a/.cursor/cli.json b/.github/docs-verify-cli.json similarity index 100% rename from .cursor/cli.json rename to .github/docs-verify-cli.json diff --git a/.github/workflows/docs-verify.yml b/.github/workflows/docs-verify.yml index c8d2378..28efbd0 100644 --- a/.github/workflows/docs-verify.yml +++ b/.github/workflows/docs-verify.yml @@ -10,7 +10,7 @@ on: - "Readme.md" - "mkdocs.yml" - "requirements-docs.txt" - - ".cursor/**" + - ".github/docs-verify-cli.json" - ".github/workflows/docs-verify.yml" workflow_dispatch: inputs: @@ -90,6 +90,12 @@ jobs: curl https://cursor.com/install -fsS | bash echo "$HOME/.cursor/bin" >> "$GITHUB_PATH" + - name: Apply verify-only CLI permissions + if: steps.cursor_key.outputs.present == 'true' + run: | + mkdir -p .cursor + cp .github/docs-verify-cli.json .cursor/cli.json + - name: Verify docs if: steps.cursor_key.outputs.present == 'true' id: verify From 148f1aceea17d10ebac9a4be72d45aa70d378fbb Mon Sep 17 00:00:00 2001 From: Liron Date: Wed, 22 Jul 2026 12:22:01 +0300 Subject: [PATCH 8/9] Fix docs CI workflows from Bugbot review Stop overwriting committed docs/assets images, post agent comments via body files to avoid shell injection, and run verify-docs on docs/* branches. Co-authored-by: Cursor --- .github/workflows/docs-verify.yml | 11 +++++++---- .github/workflows/docs.yml | 9 --------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/.github/workflows/docs-verify.yml b/.github/workflows/docs-verify.yml index 28efbd0..aaf2778 100644 --- a/.github/workflows/docs-verify.yml +++ b/.github/workflows/docs-verify.yml @@ -29,7 +29,6 @@ concurrency: jobs: verify-docs: - if: ${{ github.event_name != 'pull_request' || !startsWith(github.head_ref, 'docs/') }} runs-on: ubuntu-latest steps: - name: Resolve PR number @@ -139,14 +138,18 @@ jobs: run: | set -euo pipefail MARKER="" - BODY="${MARKER}"$'\n'"$(cat /tmp/docs-check.md)" + { + printf '%s\n' "$MARKER" + cat /tmp/docs-check.md + } > /tmp/docs-comment.md PR="${{ steps.pr.outputs.number }}" existing=$(gh api "repos/${{ github.repository }}/issues/${PR}/comments" \ --jq ".[] | select(.body | contains(\"${MARKER}\")) | .id" | head -n1) if [ -n "${existing}" ]; then - gh api -X PATCH "repos/${{ github.repository }}/issues/comments/${existing}" -f body="$BODY" + gh api -X PATCH "repos/${{ github.repository }}/issues/comments/${existing}" \ + -F "body=@/tmp/docs-comment.md" else - gh pr comment "$PR" --body "$BODY" + gh pr comment "$PR" --body-file /tmp/docs-comment.md fi - name: Fail when docs need updates diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 4c28b39..ff610fc 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -12,8 +12,6 @@ on: - "mkdocs.yml" - "requirements-docs.txt" - ".github/workflows/docs.yml" - - "TAP-axis-alpha.png" - - "TAPXR-axis.png" pull_request: types: [opened, synchronize, reopened, ready_for_review] paths: @@ -22,8 +20,6 @@ on: - "mkdocs.yml" - "requirements-docs.txt" - ".github/workflows/docs.yml" - - "TAP-axis-alpha.png" - - "TAPXR-axis.png" workflow_dispatch: inputs: deploy: @@ -61,11 +57,6 @@ jobs: - name: Install docs dependencies run: pip install -r requirements-docs.txt - - name: Sync reference images into docs - run: | - mkdir -p docs/assets - cp -f TAP-axis-alpha.png TAPXR-axis.png docs/assets/ - - name: Build site run: mkdocs build --strict --clean From 1a851fcae5759802c416a012d6ca862d356da934 Mon Sep 17 00:00:00 2001 From: Liron Date: Wed, 22 Jul 2026 12:32:34 +0300 Subject: [PATCH 9/9] Improve docs-verify failure visibility and asset checks Post a new PR comment on each failed run (with workflow link) instead of silently updating the old one. Tighten the agent prompt and CLI permissions so missing files are reported only after git ls-files/test verification. Co-authored-by: Cursor --- .github/docs-verify-cli.json | 4 ++- .github/workflows/docs-verify.yml | 44 ++++++++++++++++++++++--------- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/.github/docs-verify-cli.json b/.github/docs-verify-cli.json index a592ce2..976b64a 100644 --- a/.github/docs-verify-cli.json +++ b/.github/docs-verify-cli.json @@ -7,8 +7,10 @@ "Shell(ls)", "Shell(git diff)", "Shell(git log)", + "Shell(git ls-files)", "Shell(git show)", - "Shell(git status)" + "Shell(git status)", + "Shell(test)" ], "deny": [ "Write(**/*)", diff --git a/.github/workflows/docs-verify.yml b/.github/workflows/docs-verify.yml index aaf2778..4261507 100644 --- a/.github/workflows/docs-verify.yml +++ b/.github/workflows/docs-verify.yml @@ -115,7 +115,12 @@ jobs: 1. Inspect the PR diff (git diff origin/${{ steps.pr.outputs.base_ref }}...HEAD). 2. Decide which Diátaxis quadrants (if any) are affected. 3. Check that docs/, Readme.md, and mkdocs.yml still match the guidelines and the code change. - 4. Do not invent features. If the PR is docs-only and consistent, status is OK. + 4. Before claiming any file or asset is missing, verify in the checked-out tree: + - git ls-files -- (required for tracked files, including binaries under docs/assets/) + - test -f + Report a path as missing only when both checks show it is absent. + 5. Do not infer absence from the diff alone; binary assets may be added without appearing in text diffs. + 6. Do not invent features. If the PR is docs-only and consistent, status is OK. Output markdown ONLY (no preamble), using exactly this template: @@ -138,28 +143,41 @@ jobs: run: | set -euo pipefail MARKER="" - { - printf '%s\n' "$MARKER" - cat /tmp/docs-check.md - } > /tmp/docs-comment.md + RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" PR="${{ steps.pr.outputs.number }}" - existing=$(gh api "repos/${{ github.repository }}/issues/${PR}/comments" \ - --jq ".[] | select(.body | contains(\"${MARKER}\")) | .id" | head -n1) - if [ -n "${existing}" ]; then - gh api -X PATCH "repos/${{ github.repository }}/issues/comments/${existing}" \ - -F "body=@/tmp/docs-comment.md" - else + + if grep -qiE 'Status:[[:space:]]*NEEDS UPDATES' /tmp/docs-check.md || \ + ! grep -qiE 'Status:[[:space:]]*OK' /tmp/docs-check.md; then + { + printf '%s\n' "$MARKER" + printf 'Workflow run: %s\n\n' "$RUN_URL" + cat /tmp/docs-check.md + } > /tmp/docs-comment.md gh pr comment "$PR" --body-file /tmp/docs-comment.md + else + { + printf '%s\n' "$MARKER" + cat /tmp/docs-check.md + } > /tmp/docs-comment.md + existing=$(gh api "repos/${{ github.repository }}/issues/${PR}/comments" \ + --jq ".[] | select(.body | contains(\"${MARKER}\")) | .id" | head -n1) + if [ -n "${existing}" ]; then + gh api -X PATCH "repos/${{ github.repository }}/issues/comments/${existing}" \ + -F "body=@/tmp/docs-comment.md" + else + gh pr comment "$PR" --body-file /tmp/docs-comment.md + fi fi - name: Fail when docs need updates if: steps.cursor_key.outputs.present == 'true' run: | if grep -qiE 'Status:[[:space:]]*NEEDS UPDATES' /tmp/docs-check.md; then - echo "::error::Documentation updates required (see PR comment)." + gaps=$(sed -n 's/^- Gaps:[[:space:]]*//p' /tmp/docs-check.md | head -n1) + echo "::error::Documentation updates required (see latest PR comment). ${gaps}" exit 1 fi if ! grep -qiE 'Status:[[:space:]]*OK' /tmp/docs-check.md; then - echo "::error::Docs check output missing Status: OK or NEEDS UPDATES" + echo "::error::Docs check output missing Status: OK or NEEDS UPDATES (see latest PR comment)." exit 1 fi