Skip to content

Commit 668295e

Browse files
committed
feat: add ENTSO-E energy prices custom component for Home Assistant.
0 parents  commit 668295e

24 files changed

Lines changed: 2301 additions & 0 deletions

File tree

.agents/workflows/release.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
description: How to create a new release of the ENTSO-E Ceny Energii HACS integration
3+
---
4+
5+
# Release Workflow — ENTSO-E Ceny Energii
6+
7+
## Prerequisites
8+
- All changes committed and pushed to `main`
9+
- Tests passing (CI auto-validates on push)
10+
- Working directory: `/Users/grzegorzciupek/Downloads/Programowanie/entsoe-e`
11+
12+
## Steps
13+
14+
### 1. Decide version bump type
15+
- `patch` — bugfixes, minor tweaks (1.0.0 → 1.0.1)
16+
- `minor` — new features, sensors, config options (1.0.0 → 1.1.0)
17+
- `major` — breaking changes, config migration needed (1.0.0 → 2.0.0)
18+
19+
### 2. Bump version in manifest.json
20+
// turbo
21+
```bash
22+
python3 scripts/bump_version.py <patch|minor|major|X.Y.Z>
23+
```
24+
25+
The script updates `custom_components/entsoe_prices/manifest.json` automatically.
26+
27+
### 3. Commit the version bump
28+
```bash
29+
git add custom_components/entsoe_prices/manifest.json
30+
git commit -m "Bump version to $(python3 -c "import json; print(json.load(open('custom_components/entsoe_prices/manifest.json'))['version'])")"
31+
```
32+
33+
### 4. Create and push the tag
34+
```bash
35+
VERSION=$(python3 -c "import json; print(json.load(open('custom_components/entsoe_prices/manifest.json'))['version'])")
36+
git tag "v${VERSION}"
37+
git push origin main --tags
38+
```
39+
40+
### 5. Verify release
41+
The GitHub Actions workflow `.github/workflows/release.yml` will automatically:
42+
1. Verify manifest.json version matches the tag
43+
2. Create a zip archive of the integration
44+
3. Create a GitHub Release with release notes
45+
46+
Check: `https://github.com/GregECAT/entsoe-e/releases`
47+
48+
## How HACS detects updates
49+
HACS compares `version` in `manifest.json` (on the default branch) against the latest GitHub release tag. When they differ, HACS shows an update notification to the user.
50+
51+
## Important files
52+
| File | Purpose |
53+
|------|---------|
54+
| `custom_components/entsoe_prices/manifest.json` | Contains `version` — HACS reads this |
55+
| `hacs.json` | HACS metadata (min HA version, country) |
56+
| `.github/workflows/release.yml` | Auto-creates GitHub Release on tag push |
57+
| `.github/workflows/validate.yml` | CI — runs tests on push/PR |
58+
| `scripts/bump_version.py` | Version bump helper script |

.github/workflows/release.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
name: Create GitHub Release
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v4
18+
19+
- name: Get version from tag
20+
id: version
21+
run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
22+
23+
- name: Verify manifest version matches tag
24+
run: |
25+
MANIFEST_VERSION=$(python3 -c "import json; print(json.load(open('custom_components/entsoe_prices/manifest.json'))['version'])")
26+
TAG_VERSION="${{ steps.version.outputs.version }}"
27+
if [ "$MANIFEST_VERSION" != "$TAG_VERSION" ]; then
28+
echo "❌ ERROR: manifest.json version ($MANIFEST_VERSION) does not match tag ($TAG_VERSION)"
29+
echo "Run: python3 scripts/bump_version.py $TAG_VERSION"
30+
exit 1
31+
fi
32+
echo "✅ Version match: $MANIFEST_VERSION"
33+
34+
- name: Create zip archive
35+
run: |
36+
cd custom_components/entsoe_prices
37+
zip -r ../../entsoe_prices.zip . -x '__pycache__/*' '*.pyc'
38+
cd ../..
39+
40+
- name: Create GitHub Release
41+
uses: softprops/action-gh-release@v2
42+
with:
43+
name: "v${{ steps.version.outputs.version }}"
44+
body: |
45+
## ENTSO-E Ceny Energii v${{ steps.version.outputs.version }}
46+
47+
### Instalacja / Aktualizacja
48+
- **HACS**: Settings → Devices & Services → HACS → Aktualizuj
49+
- **Ręcznie**: Pobierz `entsoe_prices.zip` i rozpakuj do `custom_components/entsoe_prices/`
50+
51+
---
52+
*Smarting HOME — [smartinghome.pl](https://smartinghome.pl)*
53+
files: entsoe_prices.zip
54+
generate_release_notes: true

.github/workflows/validate.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Validate
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
validate:
11+
name: Validate Integration
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@v4
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version: "3.14"
21+
22+
- name: Install dependencies
23+
run: pip install pytest aiohttp
24+
25+
- name: Run tests
26+
run: python -m pytest tests/ -v
27+
28+
- name: Validate manifest.json
29+
run: |
30+
python3 -c "
31+
import json, sys
32+
m = json.load(open('custom_components/entsoe_prices/manifest.json'))
33+
required = ['domain', 'name', 'version', 'documentation', 'codeowners', 'config_flow']
34+
missing = [k for k in required if k not in m]
35+
if missing:
36+
print(f'❌ Missing keys: {missing}')
37+
sys.exit(1)
38+
print(f'✅ manifest.json OK — v{m[\"version\"]}')
39+
"
40+
41+
- name: Validate hacs.json
42+
run: |
43+
python3 -c "
44+
import json, sys
45+
h = json.load(open('hacs.json'))
46+
required = ['name', 'homeassistant']
47+
missing = [k for k in required if k not in h]
48+
if missing:
49+
print(f'❌ Missing keys: {missing}')
50+
sys.exit(1)
51+
print(f'✅ hacs.json OK')
52+
"

LICENSE

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

README.md

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# 🇵🇱 ENTSO-E Ceny Energii
2+
3+
<p align="center">
4+
<img src="images/logo.png" alt="ENTSO-E Ceny Energii by Smarting HOME" width="400">
5+
</p>
6+
7+
<p align="center">
8+
<a href="https://github.com/hacs/integration"><img src="https://img.shields.io/badge/HACS-Custom-41BDF5.svg" alt="HACS"></a>
9+
<a href="https://www.home-assistant.io/"><img src="https://img.shields.io/badge/Home%20Assistant-2024.1+-blue.svg" alt="HA"></a>
10+
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License"></a>
11+
<a href="https://smartinghome.pl"><img src="https://img.shields.io/badge/Smarting%20HOME-smartinghome.pl-00CCAA.svg" alt="Smarting HOME"></a>
12+
</p>
13+
14+
---
15+
16+
Profesjonalna integracja HACS dla **Home Assistant**, pobierająca **ceny energii day-ahead** z platformy [ENTSO-E Transparency](https://transparency.entsoe.eu/).
17+
18+
Domyślnie skonfigurowana dla **Polski** — z przeliczeniem na **PLN/kWh**, automatycznym kursem EUR/PLN z **NBP** i polskim VAT 23%.
19+
20+
> 🏠 Wydawca: **[Smarting HOME](https://smartinghome.pl)** — inteligentne zarządzanie energią w domu
21+
22+
---
23+
24+
## ✨ Funkcje
25+
26+
| Funkcja | Opis |
27+
|---------|------|
28+
|**Aktualna cena** | Cena energii w bieżącej godzinie |
29+
| ⏭️ **Następna godzina** | Cena na kolejną godzinę |
30+
| 📉 **Minimum dzisiaj** | Najniższa cena dnia + godzina |
31+
| 📈 **Maksimum dzisiaj** | Najwyższa cena dnia + godzina |
32+
| 📊 **Średnia dzisiaj** | Średnia cena dnia |
33+
| 💰 **Najtańsze 3h** | Najtańsze 3 kolejne godziny |
34+
| 🏦 **Auto-kurs NBP** | Automatyczny kurs EUR/PLN z Narodowego Banku Polskiego |
35+
| 📋 **Ceny today/tomorrow** | Pełna lista cen w atrybutach sensora |
36+
| 🇵🇱 **Polski interfejs** | Pełne tłumaczenie na język polski |
37+
| 🌍 **60+ stref** | Wszystkie europejskie bidding zones |
38+
39+
## 📦 Instalacja
40+
41+
### HACS (zalecane)
42+
43+
1. Otwórz **HACS → Integracje**
44+
2. Kliknij ******Repozytoria niestandardowe**
45+
3. Dodaj URL: `https://github.com/GregECAT/entsoe-e`
46+
4. Kategoria: **Integracja**
47+
5. Zainstaluj **ENTSO-E Ceny Energii**
48+
6. Uruchom ponownie Home Assistant
49+
50+
### Ręcznie
51+
52+
1. Skopiuj folder `custom_components/entsoe_prices/` do katalogu `custom_components/` w Home Assistant
53+
2. Uruchom ponownie Home Assistant
54+
55+
## ⚙️ Konfiguracja
56+
57+
<p align="center">
58+
<img src="images/icon.png" alt="ENTSO-E Ceny Energii icon" width="80">
59+
</p>
60+
61+
1. **Settings → Devices & Services → Add Integration**
62+
2. Wyszukaj **"ENTSO-E Ceny Energii"**
63+
3. Wypełnij formularz:
64+
65+
| Pole | Opis | Domyślnie |
66+
|------|------|-----------|
67+
| 🔑 **Klucz API** | Token z [ENTSO-E](https://transparency.entsoe.eu/myAccount/webApiAccess) | — (wymagany) |
68+
| 🌍 **Strefa cenowa** | Bidding zone | 🇵🇱 Polska |
69+
| 💱 **Waluta** | EUR lub PLN | PLN |
70+
|**Jednostka** | kWh lub MWh | kWh |
71+
| 🧾 **VAT (%)** | Stawka VAT | 23.0 |
72+
| 🏦 **Auto-kurs NBP** | Automatyczny kurs walut | ✅ Tak |
73+
| 📝 **Kurs ręczny** | Gdy auto-kurs wyłączony | 4.30 |
74+
75+
### Jak uzyskać klucz API
76+
77+
1. Zarejestruj konto na [transparency.entsoe.eu](https://transparency.entsoe.eu/)
78+
2. Wyślij email na `transparency@entsoe.eu` z tematem *"Restful API access"*
79+
3. Po aktywacji: **My Account → Web API Security Token**
80+
81+
> 📖 Pełna dokumentacja API: [Postman Collection](https://documenter.getpostman.com/view/7009892/2s93JtP3F6)
82+
83+
## 📊 Sensory (Entities)
84+
85+
Po konfiguracji pojawią się sensory:
86+
87+
| Sensor | Entity ID | Opis |
88+
|--------|-----------|------|
89+
| ⚡ Aktualna cena | `sensor.entsoe_current_price` | Cena w bieżącej godzinie (PLN/kWh) |
90+
| ⏭️ Następna godzina | `sensor.entsoe_next_hour_price` | Cena na kolejną godzinę |
91+
| 📉 Minimum | `sensor.entsoe_today_min` | Najniższa cena dnia |
92+
| 📈 Maksimum | `sensor.entsoe_today_max` | Najwyższa cena dnia |
93+
| 📊 Średnia | `sensor.entsoe_today_avg` | Średnia cena dnia |
94+
| 💰 Najtańsze 3h | `sensor.entsoe_cheapest_hours_avg` | Najtańsze 3 kolejne godziny |
95+
96+
### Atrybuty sensora `current_price`
97+
98+
```yaml
99+
prices_today:
100+
- start: "2025-01-15T00:00:00+01:00"
101+
end: "2025-01-15T01:00:00+01:00"
102+
start_local: "00:00"
103+
value: 0.4523 # PLN/kWh
104+
raw_eur_mwh: 78.50 # oryginalna cena EUR/MWh
105+
- ...
106+
prices_tomorrow: [...] # Dostępne ok. 13:00 CET
107+
tomorrow_available: true
108+
exchange_rate: 4.3215 # kurs NBP
109+
updated_at: "2025-01-15T12:30:00+00:00"
110+
today_min: 0.2105
111+
today_max: 0.8734
112+
today_avg: 0.4521
113+
today_min_hour: "03:00"
114+
today_max_hour: "18:00"
115+
cheapest_hours_start: "02:00"
116+
cheapest_hours_end: "05:00"
117+
cheapest_hours_avg: 0.2234
118+
```
119+
120+
## 📈 Wizualizacja — przykłady kart Lovelace
121+
122+
### ApexCharts Card
123+
124+
```yaml
125+
type: custom:apexcharts-card
126+
header:
127+
title: ⚡ Ceny energii — dzisiaj
128+
show: true
129+
graph_span: 24h
130+
span:
131+
start: day
132+
series:
133+
- entity: sensor.entsoe_current_price
134+
data_generator: |
135+
return entity.attributes.prices_today.map(p => [
136+
new Date(p.start).getTime(),
137+
p.value
138+
]);
139+
```
140+
141+
### Mini Graph Card
142+
143+
```yaml
144+
type: custom:mini-graph-card
145+
entities:
146+
- sensor.entsoe_current_price
147+
name: Cena energii
148+
hours_to_show: 24
149+
points_per_hour: 1
150+
line_color: "#00CCAA"
151+
```
152+
153+
### Automatyzacja — najtańsze godziny
154+
155+
```yaml
156+
automation:
157+
- alias: "Włącz ładowanie w najtańszych godzinach"
158+
trigger:
159+
- platform: time
160+
at: sensor.entsoe_cheapest_hours_avg
161+
condition:
162+
- condition: numeric_state
163+
entity_id: sensor.entsoe_current_price
164+
below: 0.30
165+
action:
166+
- service: switch.turn_on
167+
target:
168+
entity_id: switch.charger
169+
```
170+
171+
## 🔄 Aktualizacja danych
172+
173+
| Co | Częstotliwość |
174+
|----|---------------|
175+
| Ceny day-ahead | Co 30 minut |
176+
| Kurs NBP | Raz dziennie |
177+
| Ceny na jutro | Publikowane ok. 13:00 CET |
178+
179+
## 🤝 Wsparcie
180+
181+
- 🐛 **Błędy**: [GitHub Issues](https://github.com/GregECAT/entsoe-e/issues)
182+
- 🏠 **Smarting HOME**: [smartinghome.pl](https://smartinghome.pl)
183+
- 📖 **API Docs**: [Postman Collection](https://documenter.getpostman.com/view/7009892/2s93JtP3F6)
184+
- 📧 **ENTSO-E**: [transparency@entsoe.eu](mailto:transparency@entsoe.eu)
185+
186+
## 📄 Licencja
187+
188+
MIT License — [LICENSE](LICENSE)
189+
190+
---
191+
192+
<p align="center">
193+
<strong>Powered by <a href="https://smartinghome.pl">Smarting HOME</a></strong><br>
194+
<em>Dane z <a href="https://transparency.entsoe.eu/">ENTSO-E Transparency Platform</a> · Kurs walut z <a href="https://api.nbp.pl/">API NBP</a></em>
195+
</p>

0 commit comments

Comments
 (0)