# PyBookLid - MacBook Lid Angle Sensor
A Python library for reading MacBook lid angle sensor data on macOS. This library provides real-time access to the built-in lid angle sensor available on modern MacBooks.
## Features
- **One-shot readings** - Get the current lid angle instantly
- **Continuous monitoring** - Stream angle changes in real-time
- **Adaptive audio synthesis** - Generate door creak sounds that respond to movement
- **Context manager support** - Clean resource management
- **Type hints** - Full typing support for better IDE integration
- **Error handling** - Graceful handling of sensor unavailability
## Requirements
- macOS (tested on Apple Silicon)
- Python 3.7+
- Modern MacBook with lid angle sensor (most 2016+ models)
## Installation
Install from PyPI:
```bash
pip install pybooklid
```
Or install with audio features for creak sound generation:
```bash
pip install pybooklid[audio]
```
The library automatically handles the required `DYLD_LIBRARY_PATH` setup for hidapi on macOS.
### Development Installation
1. Clone this repository:
```bash
git clone <repository-url>
cd pybooklid
```
2. Install in development mode:
```bash
pip install -e .
# Or with audio features
pip install -e .[audio]
```
## Quick Start
### One-shot reading
```python
from pybooklid import read_lid_angle
angle = read_lid_angle()
if angle is not None:
print(f"Current lid angle: {angle:.1f}°")
else:
print("Sensor not available")
```
### Continuous monitoring
```python
from pybooklid import LidSensor
with LidSensor() as sensor:
for angle in sensor.monitor(interval=0.1):
print(f"Angle: {angle:.1f}°")
if angle < 10: # Nearly closed
break
```
### Advanced usage
```python
from pybooklid import LidSensor
# Manual connection management
sensor = LidSensor(auto_connect=False)
try:
sensor.connect()
# Wait for significant movement
new_angle = sensor.wait_for_change(threshold=5.0, timeout=10.0)
if new_angle:
print(f"Lid moved to {new_angle:.1f}°")
# Monitor with callback
def on_angle_change(angle):
print(f"Callback: {angle:.1f}°")
for angle in sensor.monitor(callback=on_angle_change, max_duration=30):
# Process angle data
pass
finally:
sensor.disconnect()
```
## API Reference
### `LidSensor` Class
The main sensor interface class.
#### Methods:
- `__init__(auto_connect=True)` - Initialize sensor, optionally auto-connecting
- `connect()` - Connect to the lid angle sensor
- `disconnect()` - Disconnect from the sensor
- `is_connected()` - Check connection status
- `read_angle()` - Get current angle in degrees (0-180°)
- `monitor(interval=0.1, callback=None, max_duration=None)` - Continuous monitoring iterator
- `wait_for_change(threshold=1.0, timeout=None)` - Wait for angle to change
### Convenience Functions
- `read_lid_angle()` - Quick one-shot reading
- `is_sensor_available()` - Check if sensor is available
### Command Line Tools
After installation, you can use the command line tools:
```bash
# Run basic sensor demo
pybooklid-demo
# Run advanced monitoring app
pybooklid-monitor
```
## Sensor Details
The lid angle sensor reports values in degrees:
- **0°** - Lid fully closed
- **90°** - Lid at right angle
- **~180°** - Lid fully open (varies by MacBook model)
The sensor uses Apple's HID interface:
- **Vendor ID**: 0x05AC (Apple)
- **Product ID**: 0x8104 (Sensor Hub)
- **Usage Page**: 0x0020 (Sensor)
- **Usage**: 0x008A (Orientation)
## Error Handling
The library includes comprehensive error handling:
- `LidSensorError` - Base exception for sensor-related errors
- Graceful degradation when sensor is unavailable
- Automatic reconnection attempts
- Safe cleanup on exit
## Compatibility
Tested on:
- MacBook Pro (Apple Silicon)
- macOS Sonoma/Sequoia
- Python 3.12
Should work on most modern MacBooks with lid angle sensors.
## Example Scripts
### Simple Usage (`examples/simple_usage.py`)
Demonstrates basic sensor usage patterns and gesture detection.
### Advanced Monitor (`examples/monitor_app.py`)
Full-featured monitoring application with statistics, logging, and CSV export.
### Creaky Door Effect (`examples/creaky_door.py`)
Fun demonstration that plays adaptive door creak sounds based on lid movement.
### Real-time Audio Synthesis (`creak_synthesizer.py`)
Advanced audio synthesis that generates realistic door sounds adapting to:
- Movement speed (faster = louder, more intense)
- Lid angle (different positions make different sounds)
- Direction (opening vs closing has different characteristics)
## Troubleshooting
### "Sensor not found" error
- Ensure you're on a supported MacBook model
- Try running with `sudo` if permission issues occur
- Check that no other applications are using the sensor
### Library import errors
- Verify hidapi installation: `pip show hidapi`
- On older macOS, install Homebrew and run `brew install hidapi`
### Inconsistent readings
- The sensor may have noise - use averaging for stable readings
- Some MacBook models may have different angle ranges
## Development
Based on reverse engineering of the IOKit HID interface used by Apple's internal sensor framework.
### Credits
This library was made possible by the reverse engineering work done by Sam Henri Gold in the [LidAngleSensor project](https://github.com/samhenrigold/LidAngleSensor). The key insights about the HID Feature Reports and data format were discovered through that original research.
### Key insights:
- Uses HID Feature Reports (not Input Reports)
- Report ID 1 contains angle data
- Data format: `[report_id, angle_low_byte, angle_high_byte]`
- 16-bit little-endian angle value in degrees
## License
MIT License - see LICENSE file for details.
## Contributing
Contributions welcome! Please test on different MacBook models and report compatibility.
Raw data
{
"_id": null,
"home_page": "https://github.com/tcsenpai/pybooklid",
"name": "pybooklid",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "macbook, lid, angle, sensor, hid, macos, hardware",
"author": "tcsenpai",
"author_email": "tcsenpai <tcsenpai@discus.sh>",
"download_url": "https://files.pythonhosted.org/packages/97/51/4656662f400fce57077fdcec8fa27d5bbcad5dc1adb1b6ce2ab673308e8d/pybooklid-1.0.0.tar.gz",
"platform": null,
"description": "# PyBookLid - MacBook Lid Angle Sensor\n\nA Python library for reading MacBook lid angle sensor data on macOS. This library provides real-time access to the built-in lid angle sensor available on modern MacBooks.\n\n## Features\n\n- **One-shot readings** - Get the current lid angle instantly\n- **Continuous monitoring** - Stream angle changes in real-time\n- **Adaptive audio synthesis** - Generate door creak sounds that respond to movement\n- **Context manager support** - Clean resource management\n- **Type hints** - Full typing support for better IDE integration\n- **Error handling** - Graceful handling of sensor unavailability\n\n## Requirements\n\n- macOS (tested on Apple Silicon)\n- Python 3.7+\n- Modern MacBook with lid angle sensor (most 2016+ models)\n\n## Installation\n\nInstall from PyPI:\n```bash\npip install pybooklid\n```\n\nOr install with audio features for creak sound generation:\n```bash\npip install pybooklid[audio]\n```\n\nThe library automatically handles the required `DYLD_LIBRARY_PATH` setup for hidapi on macOS.\n\n### Development Installation\n\n1. Clone this repository:\n```bash\ngit clone <repository-url>\ncd pybooklid\n```\n\n2. Install in development mode:\n```bash\npip install -e .\n# Or with audio features\npip install -e .[audio]\n```\n\n## Quick Start\n\n### One-shot reading\n```python\nfrom pybooklid import read_lid_angle\n\nangle = read_lid_angle()\nif angle is not None:\n print(f\"Current lid angle: {angle:.1f}\u00b0\")\nelse:\n print(\"Sensor not available\")\n```\n\n### Continuous monitoring\n```python\nfrom pybooklid import LidSensor\n\nwith LidSensor() as sensor:\n for angle in sensor.monitor(interval=0.1):\n print(f\"Angle: {angle:.1f}\u00b0\")\n if angle < 10: # Nearly closed\n break\n```\n\n### Advanced usage\n```python\nfrom pybooklid import LidSensor\n\n# Manual connection management\nsensor = LidSensor(auto_connect=False)\ntry:\n sensor.connect()\n \n # Wait for significant movement\n new_angle = sensor.wait_for_change(threshold=5.0, timeout=10.0)\n if new_angle:\n print(f\"Lid moved to {new_angle:.1f}\u00b0\")\n \n # Monitor with callback\n def on_angle_change(angle):\n print(f\"Callback: {angle:.1f}\u00b0\")\n \n for angle in sensor.monitor(callback=on_angle_change, max_duration=30):\n # Process angle data\n pass\n \nfinally:\n sensor.disconnect()\n```\n\n## API Reference\n\n### `LidSensor` Class\n\nThe main sensor interface class.\n\n#### Methods:\n\n- `__init__(auto_connect=True)` - Initialize sensor, optionally auto-connecting\n- `connect()` - Connect to the lid angle sensor\n- `disconnect()` - Disconnect from the sensor\n- `is_connected()` - Check connection status\n- `read_angle()` - Get current angle in degrees (0-180\u00b0)\n- `monitor(interval=0.1, callback=None, max_duration=None)` - Continuous monitoring iterator\n- `wait_for_change(threshold=1.0, timeout=None)` - Wait for angle to change\n\n### Convenience Functions\n\n- `read_lid_angle()` - Quick one-shot reading\n- `is_sensor_available()` - Check if sensor is available\n\n### Command Line Tools\n\nAfter installation, you can use the command line tools:\n\n```bash\n# Run basic sensor demo\npybooklid-demo\n\n# Run advanced monitoring app\npybooklid-monitor\n```\n\n## Sensor Details\n\nThe lid angle sensor reports values in degrees:\n- **0\u00b0** - Lid fully closed\n- **90\u00b0** - Lid at right angle\n- **~180\u00b0** - Lid fully open (varies by MacBook model)\n\nThe sensor uses Apple's HID interface:\n- **Vendor ID**: 0x05AC (Apple)\n- **Product ID**: 0x8104 (Sensor Hub)\n- **Usage Page**: 0x0020 (Sensor)\n- **Usage**: 0x008A (Orientation)\n\n## Error Handling\n\nThe library includes comprehensive error handling:\n\n- `LidSensorError` - Base exception for sensor-related errors\n- Graceful degradation when sensor is unavailable\n- Automatic reconnection attempts\n- Safe cleanup on exit\n\n## Compatibility\n\nTested on:\n- MacBook Pro (Apple Silicon)\n- macOS Sonoma/Sequoia\n- Python 3.12\n\nShould work on most modern MacBooks with lid angle sensors.\n\n## Example Scripts\n\n### Simple Usage (`examples/simple_usage.py`)\nDemonstrates basic sensor usage patterns and gesture detection.\n\n### Advanced Monitor (`examples/monitor_app.py`)\nFull-featured monitoring application with statistics, logging, and CSV export.\n\n### Creaky Door Effect (`examples/creaky_door.py`)\nFun demonstration that plays adaptive door creak sounds based on lid movement.\n\n### Real-time Audio Synthesis (`creak_synthesizer.py`)\nAdvanced audio synthesis that generates realistic door sounds adapting to:\n- Movement speed (faster = louder, more intense)\n- Lid angle (different positions make different sounds)\n- Direction (opening vs closing has different characteristics)\n\n## Troubleshooting\n\n### \"Sensor not found\" error\n- Ensure you're on a supported MacBook model\n- Try running with `sudo` if permission issues occur\n- Check that no other applications are using the sensor\n\n### Library import errors\n- Verify hidapi installation: `pip show hidapi`\n- On older macOS, install Homebrew and run `brew install hidapi`\n\n### Inconsistent readings\n- The sensor may have noise - use averaging for stable readings\n- Some MacBook models may have different angle ranges\n\n## Development\n\nBased on reverse engineering of the IOKit HID interface used by Apple's internal sensor framework.\n\n### Credits\n\nThis library was made possible by the reverse engineering work done by Sam Henri Gold in the [LidAngleSensor project](https://github.com/samhenrigold/LidAngleSensor). The key insights about the HID Feature Reports and data format were discovered through that original research.\n\n### Key insights:\n- Uses HID Feature Reports (not Input Reports)\n- Report ID 1 contains angle data\n- Data format: `[report_id, angle_low_byte, angle_high_byte]`\n- 16-bit little-endian angle value in degrees\n\n## License\n\nMIT License - see LICENSE file for details.\n\n## Contributing\n\nContributions welcome! Please test on different MacBook models and report compatibility.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "MacBook lid angle sensor library for Python",
"version": "1.0.0",
"project_urls": {
"Bug Reports": "https://github.com/tcsenpai/pybooklid/issues",
"Homepage": "https://github.com/tcsenpai/pybooklid",
"Source Code": "https://github.com/tcsenpai/pybooklid"
},
"split_keywords": [
"macbook",
" lid",
" angle",
" sensor",
" hid",
" macos",
" hardware"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "448bdf8adcb18c92c8d15999b1b4131b4528014305ebd20cee10b823b45b9d5a",
"md5": "23d5da51b7d21dfb3e6fab2138cc536c",
"sha256": "9dd651a237cd70b3543f73c22b3d6c013f66799c95cf4bf1569a729332eaea70"
},
"downloads": -1,
"filename": "pybooklid-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "23d5da51b7d21dfb3e6fab2138cc536c",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 21693,
"upload_time": "2025-09-07T18:10:42",
"upload_time_iso_8601": "2025-09-07T18:10:42.202690Z",
"url": "https://files.pythonhosted.org/packages/44/8b/df8adcb18c92c8d15999b1b4131b4528014305ebd20cee10b823b45b9d5a/pybooklid-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "97514656662f400fce57077fdcec8fa27d5bbcad5dc1adb1b6ce2ab673308e8d",
"md5": "2f836f22bd8dd22349ac0193ef5dc97d",
"sha256": "909d2b64defa71f4806e1edfabaadbd55a4c84e510007859dc9888567e9b2151"
},
"downloads": -1,
"filename": "pybooklid-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "2f836f22bd8dd22349ac0193ef5dc97d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 20049,
"upload_time": "2025-09-07T18:10:44",
"upload_time_iso_8601": "2025-09-07T18:10:44.201727Z",
"url": "https://files.pythonhosted.org/packages/97/51/4656662f400fce57077fdcec8fa27d5bbcad5dc1adb1b6ce2ab673308e8d/pybooklid-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-07 18:10:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "tcsenpai",
"github_project": "pybooklid",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "hidapi",
"specs": [
[
">=",
"0.14.0"
]
]
},
{
"name": "numpy",
"specs": [
[
">=",
"1.20.0"
]
]
},
{
"name": "sounddevice",
"specs": [
[
">=",
"0.4.0"
]
]
}
],
"lcname": "pybooklid"
}