Real-time electricity spot price display using the Ostrom API, running on the ThingPulse ESP32 Color Kit Grande.
Project status: This system has been under continuous testing for approximately three months. I am satisfied with the results and consider the build stable and reliable for daily use.
Disclaimer: I am not affiliated with Ostrom in any way — I am simply a happy customer who appreciates that they offer an API that helps me manage my energy costs. All trademarks and copyrights belong to their respective owners. My copyright applies only to the code in this repository.
- Demo Videos
- Features
- Hardware Requirements
- Software Requirements
- Development Environment
- Installation
- Project Structure
- Usage
- Display Layout
- Price Color Coding
- Configuration Options
- Security
- Hardware Pin Configuration
- Troubleshooting
- API Information
- License
- Disclaimer
- Credits
- Support This Project
- Getting Help
The following videos walk you through the full experience — from initial setup to daily use.
On first boot the device creates a WiFi hotspot. Connect to it to begin configuration.
https://github.com/robintel/ostrom-live-pricing/raw/main/docs/1.%20First%20Boot.mp4
Use the web-based captive portal to enter your WiFi credentials, Ostrom API keys, ZIP code, and display preferences.
Once configured, the device displays live electricity prices. Swipe and tap to navigate the forecast.
- 🔌 Real-time electricity price display (gross or net)
- 📊 8-hour price forecast bar chart
- 🎨 Color-coded prices (green/yellow/orange/red) with configurable thresholds
- 🔄 Automatic hourly updates
- 🌐 WiFi status indicator with auto-reconnect
- ⏰ Time-synchronized display with automatic DST handling
- 📱 Web-based configuration portal (no code changes needed)
- 🌍 Bilingual interface (German/English)
- 👆 Touch gestures: swipe to view future prices, tap to wake from standby
- 🔧 Automatic recovery mode after failed boots
- 🔐 AES-256 encrypted configuration storage (device-bound)
- 📡 Serial debug output (optional, configurable)
- ThingPulse ESP32 Color Kit Grande (ESP32-WROVER with ILI9488 480x320 TFT display) — some soldering required
- USB-C cable for programming
- 2.4GHz WiFi network (ESP32 does not support 5GHz)
Tip: Consider also purchasing the optional case from ThingPulse. While the build quality is modest, it protects your device nicely, avoids separate shipping costs, and saves you the rather long delivery times (2+ weeks in my experience). Disclaimer: I am not affiliated with ThingPulse — I purchased my own hardware.
- Visual Studio Code
- PlatformIO IDE extension
- Git (optional - for cloning the repository, or download ZIP from GitHub)
- Ostrom API credentials (free account at developer.ostrom-api.io)
This project was developed and tested on Windows 11 with:
- Visual Studio Code 1.85+
- PlatformIO Core 6.1.15
- Espressif 32 platform 6.9.0
⚠️ Note: The PlatformIO toolchain had issues on Zorin OS / Ubuntu Linux during development. Windows 11 is the recommended development environment.
- Download and install Visual Studio Code
- Open VSCode and install the PlatformIO extension:
- Press
Ctrl+Shift+X(orCmd+Shift+Xon Mac) - Search for "PlatformIO IDE"
- Click Install
- Restart VSCode when prompted
- Press
git clone https://github.com/robintel/ostrom-live-pricing.git
cd ostrom-live-pricingOr download the ZIP file from GitHub and extract it.
- Visit developer.ostrom-api.io
- Create a free account
- Generate OAuth2 credentials (client_id and client_secret)
- Use Production environment for real prices (Sandbox is for testing only)
- Open the project folder in VSCode
- PlatformIO should auto-detect the project
- Connect your ESP32 via USB
- Click the PlatformIO icon in the sidebar
- Under "Project Tasks" → "thingpulse-color-kit-grande":
- Click Build to compile (or press
Ctrl+Alt+B) - Click Upload to flash to device (or press
Ctrl+Alt+U)
- Click Build to compile (or press
When no configuration exists, the device automatically starts a WiFi access point for setup.
How it works:
- Device creates WiFi hotspot: On first boot, the device starts in Web Setup mode and creates its own WiFi network
- Connect to the hotspot from your phone or PC:
- Network name (SSID):
oekostrom - Password:
oekostrom
- Network name (SSID):
- Configure via web interface: A captive portal opens automatically (or browse to
192.168.4.1) - Enter your settings:
- Select your home WiFi network (or enter manually)
- Enter WiFi password
- Enter Ostrom API credentials (client_id and client_secret)
- Enter your German ZIP code
- Adjust price thresholds and preferences
- Validation: When you click "Save & Restart", the device:
- Tests the WiFi connection
- Tests the API credentials
- Shows progress on the device screen
- Success or retry:
- ✅ If successful: Device restarts and displays live prices
- ❌ If failed: Device returns to setup mode so you can correct the settings
Why this is secure:
- Credentials are stored with AES-256 encryption in the ESP32's flash memory
- Encryption key is derived from the chip's unique hardware ID (device-bound)
- No credentials in source code that could be accidentally committed to git
- See Security for more details
ostrom-energy-display/
├── platformio.ini # PlatformIO configuration
├── src/
│ ├── main.cpp # Main application code
│ ├── config_portal.h # Web configuration portal
│ ├── debug.h # Debug logging macros
│ ├── nvs_crypto.h # AES-256 encryption for stored credentials
│ └── tests.h # Hardware test functions
├── docs/ # Demo videos
└── README.md
Once configured and running:
- The device connects to your WiFi
- Syncs time via NTP (automatic DST for Germany)
- Fetches current electricity prices from Ostrom
- Displays current price and 8-hour forecast
- Updates prices automatically every hour
- Tap: Wake from standby mode
- Swipe left (→): View prices +3 hours into the future
- Swipe down (↓): Enter standby mode (dims screen)
- Tap "NOW" button: Return to current time view
If the device gets stuck (e.g., WiFi network no longer exists):
- Automatic: After 5 failed boot attempts, enters recovery mode
- Manual: Turn device off during POST screen 5 times in a row
- Recovery mode clears saved WiFi credentials and starts the web configuration portal
┌─────────────────────────┐
│ 14:23 ● │ ← Time + WiFi status (green=connected)
│ 28.45 │ ← Current price (color-coded)
│ ct/kWh│ (gross or net based on settings)
│ │
│ ▂▂▂▄▄▄▄▆▆███▅▅▅▃▃▃▂▂▂▄▄ │ ← 8-hour forecast chart
│ 14 15 16 17 18 19 20 21│ ← Hour labels
└─────────────────────────┘
Using the touchscreen, and swiping right to left, will increase the hour by 3, and also show the prices atop the bars, allowing for scrolling for as long as there are prices that were fetched. This will also show a button, on the top left, that scrolls back to the current hour. Prices on top of the bars will be shown for one minute.
At this point, the screen looks like this:
┌──────────────────────────┐
│ [NOW] 14:23●│ ← Time + WiFi status (green=connected) + NOW button
│ 28.45 │ ← Current price (color-coded)
│ ct/kWh│ (gross or net based on settings)
│ 16 14 13 12 13 12 11 14│ ← Hourly prices
│ ███▅▅▅▃▃▃▂▂▂▄▄▄▄▃▃▃▂▂▂▄▄▄│ ← 8-hour forecast chart
│ 17 18 19 20 21 22 23 00│ ← Hour labels
└──────────────────────────┘
Default thresholds (configurable via web portal):
- 🟢 Green: ≤ 28 ct/kWh (low price - good time to use energy)
- 🟡 Yellow: ≤ 40 ct/kWh (medium price)
- 🟠 Orange: ≤ 45 ct/kWh (higher price)
- 🔴 Red: > 45 ct/kWh (high price - avoid heavy usage)
All settings can be changed via the web portal (accessible in recovery mode):
| Setting | Description | Default |
|---|---|---|
| Language | Interface language English/ Deutsch | German |
| Show Gross Price | Include taxes/levies in displayed price | Yes |
| Price Thresholds | Color coding breakpoints | 28/40/45 ct/kWh |
| Daily Restart | Automatic restart time (prevents memory leaks) | 01:23 |
| Serial Debug | Enable USB serial logging | Disabled |
The displayed price is calculated from data provided by the Ostrom API:
- Gross price (default):
spotPrice + taxesAndLevies(both including VAT) - Net price:
spotPrice + taxesAndLevies(both excluding VAT)
The taxes and levies component (~21 ct/kWh) includes grid fees, renewable energy surcharges, and other regulatory costs for your ZIP code. This is why the ZIP code is required during setup.
Note: Negative spot prices can occur during periods of renewable energy oversupply (windy/sunny days with low demand). When this happens, the total price may still be positive due to the fixed taxes and levies. Negative prices are displayed in cyan.
When using the web portal, all sensitive data is encrypted at rest using AES-256-CBC:
- WiFi credentials (SSID and password)
- API credentials (client_id and client_secret)
- All other settings (ZIP code, thresholds, preferences)
How it works:
- The encryption key is derived from the ESP32's unique eFuse MAC address combined with a salt
- This means encrypted data is device-bound — it can only be decrypted on the original ESP32 chip
- If you move the flash chip to another ESP32, the configuration cannot be read
- Legacy plaintext configurations are automatically migrated to encrypted format on first boot
Benefits:
- Credentials are protected if someone extracts the flash memory
- No hardcoded encryption keys in the source code
- Each device has a unique encryption key
The platformio.ini is pre-configured for ThingPulse ESP32 Color Kit Grande:
| Function | GPIO Pin |
|---|---|
| TFT MISO | 19 |
| TFT MOSI | 18 |
| TFT SCLK | 5 |
| TFT CS | 15 |
| TFT DC | 2 |
| TFT RST | 4 |
| TFT Backlight | 32 |
| Touch CS | 21 |
- Verify SSID and password are correct
- Ensure your WiFi is 2.4GHz (ESP32 doesn't support 5GHz)
- Check WiFi signal strength at device location
- Try the "Scan Networks" feature in the web portal
- The display should show boot messages immediately
- If blank, check USB connection provides enough power
- Try a different USB cable or power source
- Verify client_id and client_secret are correct
- Ensure you're using Production environment (not Sandbox) for real prices
- Check your Ostrom account is active
- Enable serial debug in web portal to see detailed logs
- Verify your ZIP code is a valid 5-digit German postal code
- Check if Ostrom API is accessible from your network
- This project was developed on Windows 11
- Linux (Ubuntu/Zorin OS) had toolchain compatibility issues
- Consider using Windows or a Windows VM
- Baud rate: 115200
- Enable serial debug in web portal for detailed output
- In VSCode: PlatformIO → Monitor (or
Ctrl+Alt+S)
The Ostrom API provides:
- Day-ahead spot prices (EPEX)
- Hourly price data
- Net and gross prices
- Tax and levy breakdown
- Grid fees information
- And much more
Price data is typically available from 14:00 for the next day.
This project is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License (CC BY-NC 4.0).
You are free to share and adapt this work for non-commercial purposes, with appropriate attribution. For commercial licensing inquiries, please contact the copyright holder.
This application is an independent project by Robin Molnar and is not affiliated with, endorsed by, or connected to Ostrom GmbH in any way. I am simply a satisfied Ostrom customer who built this for personal use.
This tool displays energy price estimates based on publicly available API data and is intended for personal informational purposes only. It is not a replacement for the official Ostrom app. Prices shown are estimates; official prices communicated by Ostrom take precedence.
This software is provided "as is" without warranty of any kind. Use at your own risk.
Ostrom is a registered trademark of Ostrom GmbH.
Made in the 🇪🇺 with ❤️ for people, environment, and diversity.
© 2025–2026 Robin Molnar
- Ostrom API - Energy price data
- TFT_eSPI Library by Bodmer
- ArduinoJson by Benoît Blanchon
- ThingPulse - Hardware and libraries
- PlatformIO - Build system
If you find this project useful and haven't signed up for Ostrom yet, please consider using my referral code:
ROBIKR9XEZ
This helps support the continued development of this application.
- This code: Check serial monitor output, enable debug logging
- Ostrom API: Visit developer.ostrom-api.io
- PlatformIO: Visit docs.platformio.org
- ThingPulse Hardware: Visit thingpulse.com