You are using staging server - a separate instance of the ESP Component Registry that allows you to try distribution tools and processes without affecting the real registry.
# Heliot Basic Usage Example - Timer Demo
This example demonstrates how to build a complete IoT application using the Heliot framework. It implements a simple countdown timer with a web-based UI, showcasing the full application architecture pattern used in production projects.
## What This Example Demonstrates
- **Custom Domain Implementation**: Complete MyTimer domain with proper separation of concerns
- **Domain-Based Architecture**: How to structure custom domains following best practices
- **WebSocket Communication**: Real-time bidirectional communication between firmware and web UI
- **State Management**: NVS persistence for configuration
- **Modular Web UI**: ES6 modules with bundling and minification
- **Event System**: Broadcasting timer events to connected clients
- **Production-Ready Structure**: Same architecture as complex production applications
## Project Structure
```
main/
├── main.c # Application entry point
├── CMakeLists.txt # Build configuration with web asset processing
├── Kconfig.projbuild # Project configuration options
├── domains/ # Application-specific domains
│ ├── domains.c/h # Domain registration
│ └── mytimer/ # MyTimer custom domain
│ ├── mytimer_domain.c/h # Domain registration
│ ├── mytimer_types.h # Common type definitions
│ ├── mytimer_state.c/h # State management with NVS
│ ├── mytimer_events.c/h # Event system
│ ├── mytimer_manager.c/h # Business logic and timer control
│ ├── mytimer_ws_handler.c/h # WebSocket coordinator
│ ├── ws_ops/ # WebSocket operation handlers
│ │ ├── mytimer_ws_op_configure.c
│ │ ├── mytimer_ws_op_start.c
│ │ └── mytimer_ws_op_stop.c
│ └── ui/ # Web UI for mytimer domain
│ ├── mytimer.html # UI template
│ ├── mytimer.css # Styles
│ └── mytimer.js # Frontend logic (ES6 module)
├── http_server/ # HTTP server configuration
│ └── http_server_static.c # Static file registration
└── ui/ # Application UI
└── app.js # Main application entry point
```
## Architecture Overview
### Domain Layer Structure
The MyTimer domain follows a professional layered architecture:
1. **Domain Registration** (`mytimer_domain.c/h`) - Entry point, registers with Heliot
2. **Type Definitions** (`mytimer_types.h`) - Shared data structures
3. **State Management** (`mytimer_state.c/h`) - NVS persistence, thread-safe state
4. **Event System** (`mytimer_events.c/h`) - Event publishing and logging
5. **Business Logic** (`mytimer_manager.c/h`) - Core functionality, ESP Timer integration
6. **WebSocket Handler** (`mytimer_ws_handler.c/h`) - Operation registration, broadcasting
7. **Operation Handlers** (`ws_ops/`) - Individual request handlers
### Web UI Architecture
- **Modular JavaScript**: ES6 modules with proper imports
- **Component-Based**: Each domain has its own UI component
- **Build System**: Automatic bundling and minification
- **Asset Optimization**: Gzip compression for embedded files
## Features
### Timer Functionality
- Configurable duration (1-3600 seconds)
- Start/Stop control
- Auto-restart option
- Real-time countdown display
### Built-in Heliot Features
- **WiFi Management**: AP and station modes
- **Device Information**: System stats
- **Firmware Updates**: Secure OTA
- **WebSocket Protocol**: Real-time communication
## Building and Running
### Prerequisites
- ESP-IDF v5.0 or later
- Node.js (for web asset processing)
### Build Steps
```bash
# Set up environment
. $IDF_PATH/export.sh
# Set target chip
idf.py set-target esp32s3
# Build
idf.py build
# Flash and monitor
idf.py flash monitor
```
## Usage
1. **Connect to WiFi**: ESP32 creates AP "ESP32-Heliot" (password: "heliot123")
2. **Open browser**: Navigate to http://192.168.4.1
3. **Configure timer**: Set duration and options
4. **Control**: Start/stop the countdown
## WebSocket API
### Configure Timer
```json
{
"domain": "mytimer",
"operation": "configure",
"payload": {
"duration": 60,
"auto_restart": false
}
}
```
### Start Timer
```json
{
"domain": "mytimer",
"operation": "start"
}
```
### Events
- `started`: Timer began
- `tick`: Every second update
- `expired`: Timer finished
- `stopped`: Timer halted
## Extending This Example
### Add New WebSocket Operation
1. Create handler in `ws_ops/mytimer_ws_op_<operation>.c`
2. Declare in `mytimer_ws_handler.c`
3. Register in `mytimer_ws_handler_init()`
### Add Another Domain
1. Create `domains/newdomain/`
2. Implement domain structure (see MyTimer)
3. Add to `domains/domains.c`
4. Update CMakeLists.txt
5. Add UI component to `ui/app.js`
## Configuration
- `WEB_COMPRESS_FILES`: Gzip compression (menuconfig)
- `WEB_MINIFY`: JavaScript minification (build flag)
## Memory Usage
- **Flash**: ~800 KB (compressed)
- **RAM**: ~60 KB runtime
## Troubleshooting
**Build fails**: Check Node.js installation
**Can't connect**: Verify AP name/password in logs
**Timer issues**: Check ESP32 logs for errors
## License
MIT License - Part of Heliot framework
To create a project from this example, run:
idf.py create-project-from-example "luckyp70/heliot=1.0.4:basic_usage"