Translation of everything into English, optimization (up to 5x less CPU-intensive), restructuring, deletion of useless judged files

This commit is contained in:
Augustin ROUX 2025-10-14 12:29:33 +02:00
parent 5a8f103be3
commit 134d39b747
8 changed files with 71 additions and 570 deletions

View File

@ -1,35 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.0.0] - 2025-01-13
### Added
- Initial release
- GPIO-based volume button detection for Lenovo IdeaPad Flex 5i Chromebook Gen 8
- Support for Volume Up and Volume Down buttons via GPIO pins 3 and 4
- Key repeat functionality (1 second hold delay, 200ms repeat interval)
- Systemd service for automatic startup
- Installation script for easy deployment
- Comprehensive README documentation
- MIT License
### Technical Details
- Python 3 implementation using gpiod and evdev libraries
- 10ms GPIO polling interval for responsive button detection
- Open Drain Low (ODL) logic handling
- Proper state machine for button press/hold/release detection
- Graceful shutdown handling with SIGINT/SIGTERM
- Virtual input device creation via uinput
### Compatibility
- Tested on Lenovo IdeaPad Flex 5i Chromebook Gen 8 (Taeko)
- Intel Core i3-1215U processor
- MrChromebox custom BIOS (version 2408.1)
- Arch Linux kernel 6.17.1
- Python 3.13.7
- libgpiod 2.2.2
- python-evdev 1.9.2

View File

@ -1,137 +0,0 @@
# Contributing to Chromebook Volume Buttons Driver
Thank you for considering contributing to this project. This document provides guidelines for contributions.
## Code of Conduct
- Be respectful and constructive
- Focus on technical merit
- Help maintain a welcoming environment
## How to Contribute
### Reporting Bugs
When reporting bugs, please include:
1. **Hardware Information:**
- Chromebook model and codename
- Processor model
- BIOS version
- Linux kernel version
2. **Software Environment:**
- Python version
- libgpiod version
- python-evdev version
3. **Issue Description:**
- Expected behavior
- Actual behavior
- Steps to reproduce
- Relevant log output
4. **GPIO Information:**
```bash
sudo gpioinfo | grep -E "VOLDN|VOLUP"
```
### Suggesting Enhancements
Enhancement suggestions should include:
- Clear description of the feature
- Use case and motivation
- Implementation considerations
- Potential impact on existing functionality
### Pull Requests
1. **Before Starting:**
- Check existing issues and pull requests
- Discuss major changes in an issue first
- Ensure you have test hardware available
2. **Code Standards:**
- Follow PEP 8 style guide
- Use meaningful variable and function names
- Add docstrings for functions and classes
- Keep lines under 100 characters where practical
3. **Commit Guidelines:**
- Write clear, descriptive commit messages
- Use present tense ("Add feature" not "Added feature")
- Reference issues when applicable
- Keep commits focused and atomic
4. **Testing:**
- Test on actual hardware
- Verify service starts/stops correctly
- Check for resource leaks during extended operation
- Ensure CPU usage remains low
5. **Documentation:**
- Update README.md for feature changes
- Update CHANGELOG.md following Keep a Changelog format
- Add inline comments for complex logic
- Update hardware compatibility list if applicable
### Development Setup
```bash
# Clone repository
git clone https://gitea.legion-muyue.fr/Muyue/chromebook-volume-buttons.git
cd chromebook-volume-buttons
# Install dependencies
sudo pacman -S python-evdev libgpiod
# Test script directly
sudo python3 volume_buttons.py
```
### GPIO Mapping for New Hardware
If porting to different Chromebook models:
1. Identify GPIO chip and pins:
```bash
sudo gpioinfo
```
2. Look for volume button GPIO lines
3. Update constants in `volume_buttons.py`:
```python
CHIP_PATH = "/dev/gpiochipX" # Update chip number
VOLUME_DOWN_PIN = X # Update pin number
VOLUME_UP_PIN = Y # Update pin number
```
4. Test and document hardware in README.md
### Code Review Process
1. Maintainer reviews code for:
- Correctness
- Style compliance
- Documentation completeness
- Hardware compatibility impact
2. Changes may be requested before merge
3. Once approved, changes are merged to main branch
### Release Process
1. Version numbers follow Semantic Versioning
2. CHANGELOG.md updated with all changes
3. Git tag created for release
4. Release notes generated from CHANGELOG.md
## Questions
For questions about contributing, open an issue with the "question" label.
## License
By contributing, you agree that your contributions will be licensed under the MIT License.

View File

@ -1,175 +0,0 @@
# Credits and Acknowledgments
This project would not exist without the work of numerous individuals and communities in the open source ecosystem.
## Primary Author
**Muyue** - Original implementation and maintenance
## Firmware and Hardware Support
**MrChromebox (Matt DeVillier)**
- Custom UEFI firmware for Chromebooks
- Enabling Linux compatibility on ChromeOS hardware
- Website: https://mrchromebox.tech/
- GitHub: https://github.com/MrChromebox
**Google ChromiumOS Team**
- Embedded Controller (EC) firmware
- GPIO infrastructure and documentation
- Coreboot integration
- Project: https://www.chromium.org/chromium-os/
**Coreboot Project**
- Open source firmware replacement
- ACPI table implementation
- Hardware initialization
- Project: https://www.coreboot.org/
## Linux Kernel Contributors
**Linux GPIO Subsystem Maintainers**
- Bartosz Golaszewski - libgpiod maintainer
- Linus Walleij - GPIO subsystem maintainer
- Kent Gibson - GPIO userspace API v2
- All contributors to drivers/gpio/
**Linux Input Subsystem**
- Dmitry Torokhov - Input subsystem maintainer
- All contributors to drivers/input/
**Intel Platform Drivers**
- Contributors to intel-vbtn driver
- ChromeOS EC kernel driver developers
## Software Libraries
**libgpiod Project**
- Bartosz Golaszewski - Lead developer
- Project: https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/
- Providing clean userspace GPIO access
**python-evdev**
- Georgi Valkov - Original author and maintainer
- Project: https://github.com/gvalkov/python-evdev
- Python bindings for Linux input subsystem
**Python Core Team**
- Guido van Rossum - Python creator
- Python Software Foundation
- All Python core developers and contributors
## Linux Distributions
**Arch Linux**
- Package maintainers for python-evdev and libgpiod
- Documentation and wiki contributors
- Community support
**All Linux Distributions**
- Debian, Ubuntu, Fedora, Gentoo, and others
- For packaging and maintaining open source software
## Hardware Vendors
**Lenovo**
- Manufacturing IdeaPad Flex 5i Chromebook Gen 8
- Hardware design and engineering
**Intel**
- Core i3-1215U processor design
- Platform specifications and documentation
- Open source driver support
**Google**
- ChromeOS hardware reference designs (Brya family)
- Embedded Controller specifications
- Open source commitment
## Standards Organizations
**USB Implementers Forum**
- HID (Human Interface Device) specifications
**ACPI Specification**
- Advanced Configuration and Power Interface standards
**Linux Foundation**
- Hosting kernel development
- Supporting open source infrastructure
## Documentation and Education
**ArchWiki Contributors**
- Comprehensive Linux documentation
- Chromebook-specific guides
**Stack Overflow Community**
- Technical Q&A and problem solving
**GitHub/GitLab/Gitea**
- Hosting open source projects
- Collaboration infrastructure
## Testing and Feedback
Special thanks to the Chromebook Linux community for:
- Hardware compatibility testing
- Bug reports and feature requests
- Documentation improvements
- Use case validation
## Tools and Infrastructure
**Git Version Control**
- Linus Torvalds - Git creator
- Git development community
**systemd**
- Lennart Poettering and systemd team
- Service management infrastructure
**GNU Project**
- bash, coreutils, and essential utilities
- Free Software Foundation
## Inspiration and References
**ChromiumOS EC GPIO Documentation**
- Technical specifications for EC GPIO pins
- Board-specific configuration details
**Linux Kernel Documentation**
- GPIO userspace API documentation
- Input subsystem documentation
- Character device interface specifications
**Academic Research**
- Computer hardware interfacing research
- Operating systems research
- Human-computer interaction studies
## Free and Open Source Software Philosophy
This project stands on the shoulders of giants. The open source philosophy of:
- **Free Software Foundation** - Richard Stallman
- **Open Source Initiative** - Bruce Perens, Eric S. Raymond
- Countless developers who choose to share their work freely
## Legal Acknowledgments
All trademarks mentioned herein are property of their respective owners:
- Lenovo, IdeaPad, and Flex are trademarks of Lenovo
- Intel and Core are trademarks of Intel Corporation
- Chromebook and ChromeOS are trademarks of Google LLC
- Linux is a registered trademark of Linus Torvalds
## Contributing
If your work contributed to this project and you're not listed here, please submit a pull request to add yourself. Every contribution matters.
## Final Note
Open source is a collaborative effort. This project is freely available because countless individuals and organizations chose to share their knowledge and code. We honor that tradition by releasing this work under the MIT License, ensuring it remains free for all.
Thank you to everyone who makes open source software possible.

21
LICENSE
View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2025 Muyue
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

117
README.md
View File

@ -4,32 +4,16 @@ Hardware volume button driver for Chromebook devices with non-functional side-mo
## Free and Open Source Software ## Free and Open Source Software
This project is **completely free and open source** under the MIT License. This project is **completely free and open source**.
**You are free to:** ## My Hardware
- Use this software for any purpose (personal, commercial, educational)
- Study and modify the source code
- Redistribute original or modified versions
- Integrate into your own projects
- Create derivative works
**No restrictions except:**
- Include the original MIT License and copyright notice
- Provide attribution to the original author
**Philosophy:**
This software is released in the spirit of collaboration and knowledge sharing. It builds upon the work of countless open source contributors (see CREDITS.md) and continues that tradition by remaining completely free for everyone.
**Contributions Welcome:**
Pull requests, bug reports, documentation improvements, and hardware compatibility reports are encouraged and appreciated. See CONTRIBUTING.md for guidelines.
## Hardware Compatibility
**Primary Target:** **Primary Target:**
- Lenovo IdeaPad Flex 5i Chromebook Gen 8 - Lenovo IdeaPad Flex 5i Chromebook Gen 8
- Codename: Taeko (Google Brya family) - Codename: Taeko (Google Brya family)
- Processor: Intel Core i3-1215U - Processor: Intel Core i3-1215U
- BIOS: MrChromebox custom firmware - BIOS: MrChromebox custom firmware
- OS: Nyarch Linux
**GPIO Configuration:** **GPIO Configuration:**
- Volume Down: GPIO 3 (EC:EC_VOLDN_BTN_ODL) - Volume Down: GPIO 3 (EC:EC_VOLDN_BTN_ODL)
@ -39,10 +23,10 @@ Pull requests, bug reports, documentation improvements, and hardware compatibili
## Features ## Features
- Real-time volume button detection via GPIO polling - Real-time volume button detection via GPIO polling
- Automatic key repeat after 1 second hold - Automatic key repeat after 0.8 second hold
- Repeat interval: 200ms - Repeat interval: 100ms
- Systemd service for automatic startup - Systemd service for automatic startup
- Low CPU overhead (10ms polling interval) - Low CPU overhead (80ms polling interval)
## Prerequisites ## Prerequisites
@ -102,66 +86,6 @@ sudo systemctl stop chromebook-volume-buttons.service
sudo systemctl disable chromebook-volume-buttons.service sudo systemctl disable chromebook-volume-buttons.service
``` ```
## Technical Details
### Architecture
The driver operates in userspace by:
1. Reading GPIO states via libgpiod (cros-ec-gpio chip)
2. Detecting button state transitions (pressed/released)
3. Emulating keyboard events via uinput (/dev/input/eventX)
4. Implementing key repeat logic for held buttons
### GPIO Signaling
The buttons use Open Drain Low (ODL) logic:
- `Value.INACTIVE` = Button pressed (LOW)
- `Value.ACTIVE` = Button released (HIGH)
### Timing Specifications
| Parameter | Value | Description |
|-----------|-------|-------------|
| Poll Interval | 10ms | GPIO sampling rate |
| Hold Delay | 1000ms | Time before repeat starts |
| Repeat Interval | 200ms | Time between repeated events |
## Troubleshooting
### Buttons Not Detected
1. Verify GPIO accessibility:
```bash
sudo gpioinfo | grep -E "VOLDN|VOLUP"
```
Expected output:
```
line 3: "EC:EC_VOLDN_BTN_ODL" input
line 4: "EC:EC_VOLUP_BTN_ODL" input
```
2. Check permissions:
```bash
ls -l /dev/gpiochip1
```
3. Verify service status:
```bash
sudo systemctl status chromebook-volume-buttons.service
```
### High CPU Usage
Check polling interval in source code (default: 10ms = 0.01s). Adjust `POLL_INTERVAL` if needed.
### Volume Not Changing
Ensure no conflicting volume control services are running. Check with:
```bash
ps aux | grep -i volume
```
## Development ## Development
### Testing Without Service ### Testing Without Service
@ -180,21 +104,9 @@ Edit the following constants in `volume_buttons.py`:
```python ```python
self.HOLD_DELAY = 1.0 # Seconds before repeat self.HOLD_DELAY = 1.0 # Seconds before repeat
self.REPEAT_INTERVAL = 0.2 # Seconds between repeats self.REPEAT_INTERVAL = 0.2 # Seconds between repeats
POLL_INTERVAL = 0.01 # GPIO polling interval POLL_INTERVAL = 0.05 # GPIO polling interval
``` ```
## License
MIT License - See LICENSE file for details.
## Contributing
Contributions are welcome. Please:
1. Test on compatible hardware
2. Follow existing code style
3. Update documentation for changes
4. Submit pull requests with clear descriptions
## Hardware Variations ## Hardware Variations
If your Chromebook model differs, check GPIO mappings: If your Chromebook model differs, check GPIO mappings:
@ -219,18 +131,3 @@ VOLUME_UP_PIN = 4 # Update if different
## Author ## Author
Muyue Muyue
## Acknowledgments
This project is possible thanks to the work of many individuals and organizations:
- **MrChromebox** - Custom UEFI firmware for Chromebooks
- **ChromiumOS Team** - Embedded controller firmware and documentation
- **Linux Kernel Contributors** - GPIO subsystem and input subsystem
- **libgpiod Project** - Bartosz Golaszewski and contributors
- **python-evdev** - Georgi Valkov and contributors
- **Open Source Community** - All contributors to tools, libraries, and documentation used
For a complete list of acknowledgments, see [CREDITS.md](CREDITS.md).
This project stands on the shoulders of giants. Thank you to everyone who makes open source possible.

View File

@ -1,6 +1,6 @@
[Unit] [Unit]
Description=Chromebook Volume Buttons Handler Description=Chromebook Volume Buttons Handler
Documentation=https://github.com/chromebook-volume-buttons Documentation=https://gitea.legion-muyue.fr/Muyue/chromebook-volume-buttons.git
After=multi-user.target After=multi-user.target
Wants=multi-user.target Wants=multi-user.target

View File

@ -39,6 +39,7 @@ echo " Service enabled (will start on boot)"
# Start service immediately # Start service immediately
echo "[5/5] Starting service..." echo "[5/5] Starting service..."
systemctl start chromebook-volume-buttons.service systemctl start chromebook-volume-buttons.service
systemctl restart chromebook-volume-buttons.service
echo " Service started" echo " Service started"
echo "" echo ""

View File

@ -15,35 +15,9 @@ Target Hardware:
- GPIO 4 (EC:EC_VOLUP_BTN_ODL) - Volume Up - GPIO 4 (EC:EC_VOLUP_BTN_ODL) - Volume Up
- Chip: /dev/gpiochip1 (cros-ec-gpio) - Chip: /dev/gpiochip1 (cros-ec-gpio)
License:
MIT License
Copyright (c) 2025 Muyue
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Author: Author:
Muyue Muyue
Contributors:
See CREDITS.md for acknowledgments of all contributors to this project
and the open source libraries and tools it depends upon.
Repository: Repository:
https://gitea.legion-muyue.fr/Muyue/chromebook-volume-buttons https://gitea.legion-muyue.fr/Muyue/chromebook-volume-buttons
""" """
@ -58,10 +32,7 @@ import signal
CHIP_PATH = "/dev/gpiochip1" # cros-ec-gpio CHIP_PATH = "/dev/gpiochip1" # cros-ec-gpio
VOLUME_DOWN_PIN = 3 # EC:EC_VOLDN_BTN_ODL VOLUME_DOWN_PIN = 3 # EC:EC_VOLDN_BTN_ODL
VOLUME_UP_PIN = 4 # EC:EC_VOLUP_BTN_ODL VOLUME_UP_PIN = 4 # EC:EC_VOLUP_BTN_ODL
POLL_INTERVAL = 0.08
# Les GPIO sont actifs à LOW (ODL = Open Drain Low)
# Note: gpiod retourne des Value.ACTIVE/INACTIVE, pas des entiers
POLL_INTERVAL = 0.01 # 10ms
class VolumeButtonMapper: class VolumeButtonMapper:
def __init__(self): def __init__(self):
@ -69,32 +40,32 @@ class VolumeButtonMapper:
self.request = None self.request = None
self.running = True self.running = True
# États des boutons (1 = relâché, 0 = appuyé) # Button states (1 = released, 0 = pressed)
self.voldown_state = 1 self.voldown_state = 1
self.volup_state = 1 self.volup_state = 1
# Timestamps pour la répétition automatique # Timestamps for automatic repetition
self.voldown_press_time = None self.voldown_press_time = None
self.voldown_last_repeat = None self.voldown_last_repeat = None
self.volup_press_time = None self.volup_press_time = None
self.volup_last_repeat = None self.volup_last_repeat = None
# Paramètres de répétition # Repetition parameters
self.HOLD_DELAY = 1.0 # Délai avant répétition (1 seconde) self.HOLD_DELAY = 0.8 # Delay before repetition (0.8 seconds)
self.REPEAT_INTERVAL = 0.2 # Intervalle de répétition (0.2 secondes) self.REPEAT_INTERVAL = 0.1 # Repetition interval (0.1 seconds)
def setup(self): def setup(self):
"""Initialise le périphérique virtuel et les GPIO""" """Initialize the virtual device and GPIO"""
print(f"Initialisation du mapper de boutons volume...") print(f"Initializing volume button mapper...")
# Créer un périphérique d'entrée virtuel # Create a virtual input device
cap = { cap = {
e.EV_KEY: [e.KEY_VOLUMEDOWN, e.KEY_VOLUMEUP] e.EV_KEY: [e.KEY_VOLUMEDOWN, e.KEY_VOLUMEUP]
} }
self.ui = UInput(cap, name='chromebook-volume-buttons', version=0x1) self.ui = UInput(cap, name='chromebook-volume-buttons', version=0x1)
print(f"Périphérique virtuel créé: {self.ui.device.path}") print(f"Virtual device created: {self.ui.device.path}")
# Configurer les GPIO en lecture simple (sans edge detection) # Configure GPIO for simple reading (without edge detection)
self.request = gpiod.request_lines( self.request = gpiod.request_lines(
CHIP_PATH, CHIP_PATH,
consumer="volume-buttons", consumer="volume-buttons",
@ -110,133 +81,133 @@ class VolumeButtonMapper:
} }
) )
print(f"GPIO configurés:") print(f"GPIO configured:")
print(f" - Volume Down: GPIO {VOLUME_DOWN_PIN}") print(f" - Volume Down: GPIO {VOLUME_DOWN_PIN}")
print(f" - Volume Up: GPIO {VOLUME_UP_PIN}") print(f" - Volume Up: GPIO {VOLUME_UP_PIN}")
print(f"Appuyez sur les boutons volume pour tester...") print(f"Press volume buttons to test...")
def send_volume_event(self, key_code, button_name): def send_volume_event(self, key_code, button_name):
"""Envoie un événement de volume (appui complet)""" """Send a volume event (complete press)"""
self.ui.write(e.EV_KEY, key_code, 1) # Appuyer self.ui.write(e.EV_KEY, key_code, 1) # Pressed
self.ui.syn() self.ui.syn()
self.ui.write(e.EV_KEY, key_code, 0) # Relâcher self.ui.write(e.EV_KEY, key_code, 0) # Released
self.ui.syn() self.ui.syn()
def check_buttons(self): def check_buttons(self):
"""Vérifie l'état des boutons et gère la répétition automatique""" """Check button states and handle automatic repetition"""
try: try:
# Lire les deux GPIO # Read both GPIOs
values = self.request.get_values([VOLUME_DOWN_PIN, VOLUME_UP_PIN]) values = self.request.get_values([VOLUME_DOWN_PIN, VOLUME_UP_PIN])
voldown_gpio = values[0] voldown_gpio = values[0]
volup_gpio = values[1] volup_gpio = values[1]
current_time = time.time() current_time = time.time()
# === GESTION VOLUME DOWN === # === VOLUME DOWN MANAGEMENT ===
# ODL (Open Drain Low): INACTIVE = bouton appuyé, ACTIVE = bouton relâché # ODL (Open Drain Low): INACTIVE = button pressed, ACTIVE = button released
voldown_pressed = (voldown_gpio == gpiod.line.Value.INACTIVE) voldown_pressed = (voldown_gpio == gpiod.line.Value.INACTIVE)
# Détection du changement d'état # State change detection
if voldown_pressed and self.voldown_state == 1: if voldown_pressed and self.voldown_state == 1:
# Transition relâché -> appuyé # Transition released -> pressed
print("Volume Down appuyé") print("Volume Down pressed")
self.voldown_state = 0 self.voldown_state = 0
self.voldown_press_time = current_time self.voldown_press_time = current_time
self.voldown_last_repeat = None self.voldown_last_repeat = None
# Action immédiate au premier appui # Immediate action on first press
self.send_volume_event(e.KEY_VOLUMEDOWN, "Volume Down") self.send_volume_event(e.KEY_VOLUMEDOWN, "Volume Down")
print(" -> Son baissé") print(" -> Volume decreased")
elif not voldown_pressed and self.voldown_state == 0: elif not voldown_pressed and self.voldown_state == 0:
# Transition appuyé -> relâché # Transition pressed -> released
print("Volume Down relâché") print("Volume Down released")
self.voldown_state = 1 self.voldown_state = 1
self.voldown_press_time = None self.voldown_press_time = None
self.voldown_last_repeat = None self.voldown_last_repeat = None
elif voldown_pressed and self.voldown_state == 0: elif voldown_pressed and self.voldown_state == 0:
# Bouton toujours appuyé - vérifier si répétition nécessaire # Button still pressed - check if repeat needed
time_held = current_time - self.voldown_press_time time_held = current_time - self.voldown_press_time
if time_held >= self.HOLD_DELAY: if time_held >= self.HOLD_DELAY:
# Bouton maintenu assez longtemps # Button held long enough
if self.voldown_last_repeat is None: if self.voldown_last_repeat is None:
# Première répétition # First repetition
self.voldown_last_repeat = current_time self.voldown_last_repeat = current_time
self.send_volume_event(e.KEY_VOLUMEDOWN, "Volume Down") self.send_volume_event(e.KEY_VOLUMEDOWN, "Volume Down")
print(" -> Son baissé (répétition)") print(" -> Volume decreased (repeat)")
elif (current_time - self.voldown_last_repeat) >= self.REPEAT_INTERVAL: elif (current_time - self.voldown_last_repeat) >= self.REPEAT_INTERVAL:
# Répétitions suivantes # Next repetitions
self.voldown_last_repeat = current_time self.voldown_last_repeat = current_time
self.send_volume_event(e.KEY_VOLUMEDOWN, "Volume Down") self.send_volume_event(e.KEY_VOLUMEDOWN, "Volume Down")
print(" -> Son baissé (répétition)") print(" -> Volume decreased (repeat)")
# === GESTION VOLUME UP === # === VOLUME UP MANAGEMENT ===
# ODL (Open Drain Low): INACTIVE = bouton appuyé, ACTIVE = bouton relâché # ODL (Open Drain Low): INACTIVE = button pressed, ACTIVE = button released
volup_pressed = (volup_gpio == gpiod.line.Value.INACTIVE) volup_pressed = (volup_gpio == gpiod.line.Value.INACTIVE)
# Détection du changement d'état # State change detection
if volup_pressed and self.volup_state == 1: if volup_pressed and self.volup_state == 1:
# Transition relâché -> appuyé # Transition released -> pressed
print("Volume Up appuyé") print("Volume Up pressed")
self.volup_state = 0 self.volup_state = 0
self.volup_press_time = current_time self.volup_press_time = current_time
self.volup_last_repeat = None self.volup_last_repeat = None
# Action immédiate au premier appui # Immediate action on first press
self.send_volume_event(e.KEY_VOLUMEUP, "Volume Up") self.send_volume_event(e.KEY_VOLUMEUP, "Volume Up")
print(" -> Son augmenté") print(" -> Volume increased")
elif not volup_pressed and self.volup_state == 0: elif not volup_pressed and self.volup_state == 0:
# Transition appuyé -> relâché # Transition pressed -> released
print("Volume Up relâché") print("Volume Up released")
self.volup_state = 1 self.volup_state = 1
self.volup_press_time = None self.volup_press_time = None
self.volup_last_repeat = None self.volup_last_repeat = None
elif volup_pressed and self.volup_state == 0: elif volup_pressed and self.volup_state == 0:
# Bouton toujours appuyé - vérifier si répétition nécessaire # Button still pressed - check if repeat needed
time_held = current_time - self.volup_press_time time_held = current_time - self.volup_press_time
if time_held >= self.HOLD_DELAY: if time_held >= self.HOLD_DELAY:
# Bouton maintenu assez longtemps # Button held long enough
if self.volup_last_repeat is None: if self.volup_last_repeat is None:
# Première répétition # First repetition
self.volup_last_repeat = current_time self.volup_last_repeat = current_time
self.send_volume_event(e.KEY_VOLUMEUP, "Volume Up") self.send_volume_event(e.KEY_VOLUMEUP, "Volume Up")
print(" -> Son augmenté (répétition)") print(" -> Volume increased (repeat)")
elif (current_time - self.volup_last_repeat) >= self.REPEAT_INTERVAL: elif (current_time - self.volup_last_repeat) >= self.REPEAT_INTERVAL:
# Répétitions suivantes # Next repetitions
self.volup_last_repeat = current_time self.volup_last_repeat = current_time
self.send_volume_event(e.KEY_VOLUMEUP, "Volume Up") self.send_volume_event(e.KEY_VOLUMEUP, "Volume Up")
print(" -> Son augmenté (répétition)") print(" -> Volume increased (repeat)")
except Exception as ex: except Exception as ex:
print(f"Erreur lors de la lecture des GPIO: {ex}") print(f"Error reading GPIO: {ex}")
def run(self): def run(self):
"""Boucle principale de monitoring des GPIO""" """Main GPIO monitoring loop"""
try: try:
self.setup() self.setup()
# Boucle de polling # Polling loop
while self.running: while self.running:
# Vérifier les deux boutons # Check both buttons
self.check_buttons() self.check_buttons()
# Petit délai pour éviter de surcharger le CPU # Small delay to avoid overloading the CPU
time.sleep(POLL_INTERVAL) time.sleep(POLL_INTERVAL)
except PermissionError: except PermissionError:
print("\nErreur: Permission refusée.") print("\nError: Permission denied.")
print("Ce script doit être exécuté avec les privilèges root:") print("This script must be run with root privileges:")
print(f" sudo python3 {sys.argv[0]}") print(f" sudo python3 {sys.argv[0]}")
sys.exit(1) sys.exit(1)
except KeyboardInterrupt: except KeyboardInterrupt:
print("\nArrêt demandé par l'utilisateur...") print("\nStop requested by user...")
except Exception as ex: except Exception as ex:
print(f"\nErreur: {ex}") print(f"\nError: {ex}")
import traceback import traceback
traceback.print_exc() traceback.print_exc()
sys.exit(1) sys.exit(1)
@ -244,22 +215,22 @@ class VolumeButtonMapper:
self.cleanup() self.cleanup()
def cleanup(self): def cleanup(self):
"""Nettoie les ressources""" """Clean up resources"""
print("\nNettoyage...") print("\nCleaning up...")
if self.request: if self.request:
self.request.release() self.request.release()
if self.ui: if self.ui:
self.ui.close() self.ui.close()
print("Arrêté proprement.") print("Stopped cleanly.")
def signal_handler(self, signum, frame): def signal_handler(self, signum, frame):
"""Gère les signaux pour un arrêt propre""" """Handle signals for clean shutdown"""
self.running = False self.running = False
def main(): def main():
mapper = VolumeButtonMapper() mapper = VolumeButtonMapper()
# Configurer les gestionnaires de signaux # Configure signal handlers
signal.signal(signal.SIGINT, mapper.signal_handler) signal.signal(signal.SIGINT, mapper.signal_handler)
signal.signal(signal.SIGTERM, mapper.signal_handler) signal.signal(signal.SIGTERM, mapper.signal_handler)