- Fix form parameter handling for recipe_id (empty string vs None) - Remove interfering hx-on attributes from HTMX forms - Add explicit hx-swap="innerHTML" for proper content replacement - Implement global exception handler with detailed DEBUG logging - Add request middleware for comprehensive request/response logging - Enhanced modal closing logic with fallbacks - Add debug logging to recipe/button creation endpoints - Create error template for better error display - Update CLI to support --log-level per subcommand - Add CLAUDE.md with development guidelines and conventions 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
313 lines
7.2 KiB
Markdown
313 lines
7.2 KiB
Markdown
# ECM Control
|
||
|
||
A comprehensive system for controlling espresso coffee machines with GPIO relays, scale integration, and web-based recipe management.
|
||
|
||
## Features
|
||
|
||
- **Web Interface**: Modern HTMX-based web application for recipe management
|
||
- **GPIO Control**: Hardware integration for controlling espresso machines via relays
|
||
- **Scale Integration**: Support for Acaia scales via Bluetooth (with mock implementation for development)
|
||
- **Recipe Management**: Create and manage extraction recipes with target weight and timeout
|
||
- **Button Mapping**: Map physical buttons to specific recipes
|
||
- **Shot Logging**: Comprehensive logging of all extraction attempts with detailed metrics
|
||
- **Real-time Monitoring**: Live monitoring of extractions with automatic stopping
|
||
- **Systemd Integration**: Production-ready service configuration
|
||
|
||
## System Requirements
|
||
|
||
### Hardware
|
||
- Raspberry Pi (or compatible GPIO-enabled device)
|
||
- Relay module connected to GPIO (default: GPIO 2)
|
||
- Physical buttons connected to GPIO pins
|
||
- Acaia scale (optional, mock implementation available)
|
||
|
||
### Software
|
||
- Python 3.10+
|
||
- UV package manager
|
||
- SQLite 3
|
||
|
||
## Installation
|
||
|
||
### 1. Clone and Setup
|
||
|
||
```bash
|
||
git clone <repository-url>
|
||
cd ecm-control
|
||
```
|
||
|
||
### 2. Install Dependencies
|
||
|
||
```bash
|
||
# Install UV if not already installed
|
||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||
|
||
# Install project dependencies
|
||
uv sync
|
||
```
|
||
|
||
### 3. Initialize Database
|
||
|
||
```bash
|
||
uv run python run.py db init
|
||
```
|
||
|
||
## Usage
|
||
|
||
### Web Application
|
||
|
||
Start the web server:
|
||
|
||
```bash
|
||
uv run python run.py web --host 0.0.0.0 --port 8000
|
||
```
|
||
|
||
Access the web interface at `http://localhost:8000`
|
||
|
||
#### Web Interface Features:
|
||
- **Dashboard**: Overview of system status and recent shots
|
||
- **Recipes**: Create, edit, and delete extraction recipes
|
||
- **Buttons**: Configure physical button to recipe mappings
|
||
- **Shot History**: View detailed history of all extractions
|
||
- **Settings**: Configure scale address, thresholds, and logging levels
|
||
|
||
### GPIO Control Service
|
||
|
||
Start the GPIO control service:
|
||
|
||
```bash
|
||
# For Raspberry Pi with actual GPIO
|
||
uv run python run.py gpio
|
||
|
||
# For development/testing with mock GPIO
|
||
uv run python run.py gpio --mock
|
||
```
|
||
|
||
### Database Management
|
||
|
||
```bash
|
||
# Initialize database
|
||
uv run python run.py db init
|
||
|
||
# Reset database (WARNING: deletes all data)
|
||
uv run python run.py db reset
|
||
```
|
||
|
||
## Configuration
|
||
|
||
### Scale Configuration
|
||
|
||
1. Access the web interface
|
||
2. Go to Settings
|
||
3. Set the `scale_address` to your Acaia scale's Bluetooth MAC address
|
||
4. Configure other parameters as needed:
|
||
- `shot_completion_threshold`: Weight change rate (g/s) to detect completion
|
||
- `weight_stabilize_time`: Seconds to wait for weight stabilization
|
||
- `log_level`: Logging verbosity (DEBUG, INFO, WARNING, ERROR)
|
||
|
||
### Button Configuration
|
||
|
||
1. Access the web interface
|
||
2. Go to Buttons
|
||
3. Add buttons with their GPIO pin assignments
|
||
4. Map buttons to recipes
|
||
|
||
### Recipe Creation
|
||
|
||
1. Access the web interface
|
||
2. Go to Recipes
|
||
3. Create recipes with:
|
||
- Name
|
||
- Target grams out
|
||
- Timeout in seconds
|
||
|
||
## Hardware Setup
|
||
|
||
### Relay Connection
|
||
|
||
Connect a relay module to GPIO 2 (configurable). The relay should be wired to simulate the coffee machine's brew button press.
|
||
|
||
**Wiring:**
|
||
- GPIO 2 <20> Relay Signal
|
||
- 5V <20> Relay VCC
|
||
- GND <20> Relay GND
|
||
- Relay NO/COM <20> Coffee machine button circuit
|
||
|
||
### Button Connections
|
||
|
||
Connect momentary buttons between GPIO pins and ground. Use internal pull-up resistors.
|
||
|
||
**Example for 4 buttons:**
|
||
- Button 1: GPIO 17 <20> GND
|
||
- Button 2: GPIO 18 <20> GND
|
||
- Button 3: GPIO 19 <20> GND
|
||
- Button 4: GPIO 20 <20> GND
|
||
|
||
## Production Deployment
|
||
|
||
### Systemd Service
|
||
|
||
1. Copy the service file:
|
||
```bash
|
||
sudo cp ecm-control.service /etc/systemd/system/
|
||
```
|
||
|
||
2. Update the paths in the service file to match your installation
|
||
|
||
3. Enable and start the service:
|
||
```bash
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable ecm-control
|
||
sudo systemctl start ecm-control
|
||
```
|
||
|
||
4. Check service status:
|
||
```bash
|
||
sudo systemctl status ecm-control
|
||
```
|
||
|
||
### Web Server (Optional)
|
||
|
||
For production web deployment, consider using a reverse proxy like nginx:
|
||
|
||
```nginx
|
||
server {
|
||
listen 80;
|
||
server_name your-domain.com;
|
||
|
||
location / {
|
||
proxy_pass http://localhost:8000;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
}
|
||
}
|
||
```
|
||
|
||
## Development
|
||
|
||
### Mock Mode
|
||
|
||
For development on non-Raspberry Pi systems, use mock mode:
|
||
|
||
```bash
|
||
# Start GPIO service with mock hardware
|
||
uv run python -m ecm_control gpio --mock
|
||
|
||
# This enables:
|
||
# - Mock GPIO buttons (can be triggered via web interface)
|
||
# - Mock relay (logs actions instead of controlling hardware)
|
||
# - Mock scale (simulates weight readings)
|
||
```
|
||
|
||
### Debug Logging
|
||
|
||
Enable debug logging for detailed troubleshooting:
|
||
|
||
```bash
|
||
uv run python -m ecm_control gpio --log-level DEBUG
|
||
```
|
||
|
||
This creates detailed logs in `logs/debug.log` with:
|
||
- GPIO event timing
|
||
- Scale reading details
|
||
- Shot phase progression
|
||
- System state changes
|
||
|
||
### Project Structure
|
||
|
||
```
|
||
ecm-control/
|
||
|