Příklady
Inteligentní nabíjení podle spotových cen
VeřejnéTyp obsahu: Návod
Ukázka v Pythonu vyhledá nejlevnější hodiny podle spotových cen elektřiny, naplánuje odložený start nabíjení přes MyBox API a sleduje energetický mix.
Úvod do spotového nabíjení
Spotové ceny elektřiny se mění každou hodinu podle aktuální nabídky a poptávky na energetickém trhu. Inteligentní nabíjení podle těchto cen vám může ušetřit až 50% nákladů na nabíjení elektromobilu.
Kdy jsou ceny nejnižší?
- Noční hodiny (23 - 5) - nízká poptávka
- Slunečné dny (11 - 15) - přebytek solární energie
- Větrné dny - přebytek větrné energie
- Víkendy a svátky - nižší průmyslová spotřeba
Implementace spotového nabíjení s MyBox
Architektura řešení
graph LR
A[Spot Price API] --> B[Kontrolní Server]
B --> C[MyBox API]
C --> D[Nabíjecí stanice]
D --> E[Elektromobil]
Krok 1: Získání spotových cen
import requests
import json
from datetime import datetime, timedelta
class SpotPriceManager:
"""
Manager pro práci se spotovými cenami elektřiny
"""
def __init__(self, api_key, api_secret):
self.api_key = api_key
self.api_secret = api_secret
self.base_url = "https://cloud.mybox.pro/admin-panel/v1"
self.auth = (api_key, api_secret)
def get_spot_prices(self):
"""
Získání aktuálních spotových cen
Pro CZ používáme data z OTE (Operátor trhu s elektřinou)
"""
# Pro demonstraci - v reálné aplikaci použijte API OTE nebo jiného poskytovatele
# Příklad: https://www.ote-cr.cz/cs/kratkodobe-trhy/elektrina/denni-trh
# Simulace spotových cen na 24 hodin
current_hour = datetime.now().hour
base_price = 2.5 # Základní cena v Kč/kWh
# Simulace cenového profilu během dne
price_profile = {
0: 0.7, 1: 0.6, 2: 0.5, 3: 0.5, 4: 0.6, 5: 0.8, # Noc
6: 1.2, 7: 1.5, 8: 1.4, 9: 1.3, 10: 1.0, 11: 0.9, # Ráno
12: 0.8, 13: 0.9, 14: 1.0, 15: 1.1, 16: 1.3, 17: 1.6, # Odpoledne
18: 1.8, 19: 1.7, 20: 1.5, 21: 1.3, 22: 1.0, 23: 0.8 # Večer
}
prices = []
for hour in range(24):
time = datetime.now().replace(hour=hour, minute=0, second=0, microsecond=0)
if time.hour < current_hour:
time += timedelta(days=1)
prices.append({
"time": time.isoformat(),
"hour": hour,
"price_czk_kwh": base_price * price_profile.get(hour, 1.0),
"price_eur_mwh": base_price * price_profile.get(hour, 1.0) * 40 # Převod na EUR/MWh
})
return sorted(prices, key=lambda x: x["price_czk_kwh"])
def find_cheapest_hours(self, hours_needed=4, max_price=None):
"""
Najde nejlevnější hodiny pro nabíjení
Args:
hours_needed: Počet hodin potřebných pro nabíjení
max_price: Maximální akceptovatelná cena (Kč/kWh)
"""
prices = self.get_spot_prices()
if max_price:
prices = [p for p in prices if p["price_czk_kwh"] <= max_price]
# Najít nejlevnější souvislé období
cheapest_period = self._find_continuous_period(prices, hours_needed)
return cheapest_period
def _find_continuous_period(self, prices, hours_needed):
"""
Najde nejlevnější souvislé období pro nabíjení
"""
best_period = None
best_total_price = float('inf')
for i in range(len(prices) - hours_needed + 1):
period = prices[i:i+hours_needed]
total_price = sum(p["price_czk_kwh"] for p in period)
if total_price < best_total_price:
best_total_price = total_price
best_period = period
if best_period:
return {
"start_time": best_period[0]["time"],
"end_time": best_period[-1]["time"],
"hours": best_period,
"avg_price": best_total_price / hours_needed,
"total_price": best_total_price
}
return NoneKrok 2: Automatické řízení nabíjení
class SmartChargingController:
"""
Kontrolér pro inteligentní nabíjení podle cen
"""
def __init__(self, device_id, api_key, api_secret):
self.device_id = device_id
self.api_key = api_key
self.api_secret = api_secret
self.base_url = "https://cloud.mybox.pro/admin-panel/v1"
self.auth = (api_key, api_secret)
self.price_manager = SpotPriceManager(api_key, api_secret)
def calculate_charging_time(self, battery_capacity_kwh, current_soc_percent, target_soc_percent, charging_power_kw):
"""
Výpočet potřebného času nabíjení
"""
energy_needed = battery_capacity_kwh * (target_soc_percent - current_soc_percent) / 100
charging_time_hours = energy_needed / charging_power_kw
return {
"energy_needed_kwh": energy_needed,
"time_hours": charging_time_hours,
"time_minutes": charging_time_hours * 60
}
def schedule_charging(self, battery_capacity_kwh=60, current_soc=20, target_soc=80, max_price=3.0):
"""
Naplánování nabíjení podle spotových cen
Args:
battery_capacity_kwh: Kapacita baterie (kWh)
current_soc: Aktuální stav nabití (%)
target_soc: Cílový stav nabití (%)
max_price: Maximální cena za kWh
"""
# Výpočet potřebného času
charging_info = self.calculate_charging_time(
battery_capacity_kwh,
current_soc,
target_soc,
charging_power_kw=11 # 11 kW pro 3-fázové nabíjení
)
hours_needed = int(charging_info["time_hours"] + 0.5) # Zaokrouhlení nahoru
# Najít nejlevnější období
cheapest_period = self.price_manager.find_cheapest_hours(hours_needed, max_price)
if cheapest_period:
print(f"Optimální nabíjecí plán nalezen!")
print(f"Start: {cheapest_period['start_time']}")
print(f"Konec: {cheapest_period['end_time']}")
print(f"Průměrná cena: {cheapest_period['avg_price']:.2f} Kč/kWh")
print(f"Energie: {charging_info['energy_needed_kwh']:.2f} kWh")
print(f"Celková cena: {cheapest_period['avg_price'] * charging_info['energy_needed_kwh']:.2f} Kč")
# Aplikovat plán
self._apply_charging_schedule(cheapest_period)
return cheapest_period
else:
print("Nelze najít vhodné období pro nabíjení s danou cenovou limitací")
return None
def _apply_charging_schedule(self, schedule):
"""
Aplikace nabíjecího plánu na zařízení
"""
start_time = datetime.fromisoformat(schedule["start_time"])
# Pokud je čas v budoucnosti, nastavit odložený start
if start_time > datetime.now():
delay_minutes = int((start_time - datetime.now()).total_seconds() / 60)
self._set_delayed_charging(delay_minutes)
else:
# Začít nabíjet okamžitě
self._start_charging()
def _start_charging(self):
"""
Spuštění nabíjení
"""
response = requests.post(
f"{self.base_url}/external/device/{self.device_id}/action",
auth=self.auth,
json={
"action": "start_charging",
"parameters": {
"max_current": 16 # 16A
}
}
)
return response.json()
def _stop_charging(self):
"""
Zastavení nabíjení
"""
response = requests.post(
f"{self.base_url}/external/device/{self.device_id}/action",
auth=self.auth,
json={
"action": "stop_charging"
}
)
return response.json()
def _set_delayed_charging(self, delay_minutes):
"""
Nastavení odloženého startu nabíjení
"""
print(f"Nabíjení začne za {delay_minutes} minut")
# Implementace pomocí scheduleru nebo cron jobu
# V produkci byste použili robustnější řešení
import threading
def delayed_start():
time.sleep(delay_minutes * 60)
self._start_charging()
print("Nabíjení zahájeno!")
thread = threading.Thread(target=delayed_start)
thread.daemon = True
thread.start()Krok 3: Adaptivní nabíjení s predikcí cen
import numpy as np
from sklearn.linear_model import LinearRegression
from datetime import datetime, timedelta
class AdaptiveChargingAI:
"""
AI-powered adaptivní nabíjení s predikcí cen
"""
def __init__(self, device_id, api_credentials):
self.device_id = device_id
self.api_credentials = api_credentials
self.price_history = []
self.model = LinearRegression()
def collect_price_history(self, days=30):
"""
Sbírání historických dat o cenách
"""
# V reálné aplikaci byste načetli data z databáze
# Pro demonstraci generujeme syntetická data
history = []
for day in range(days):
for hour in range(24):
timestamp = datetime.now() - timedelta(days=day, hours=hour)
# Simulace sezónních a denních vzorů
base_price = 2.5
hour_factor = 1 + 0.5 * np.sin(2 * np.pi * hour / 24)
day_factor = 1 + 0.2 * np.sin(2 * np.pi * day / 7)
random_factor = np.random.normal(1, 0.1)
price = base_price * hour_factor * day_factor * random_factor
history.append({
"timestamp": timestamp,
"hour": hour,
"weekday": timestamp.weekday(),
"price": max(0.5, price) # Minimální cena 0.5 Kč/kWh
})
self.price_history = history
return history
def train_prediction_model(self):
"""
Trénování predikčního modelu
"""
if not self.price_history:
self.collect_price_history()
# Příprava dat pro trénování
X = []
y = []
for record in self.price_history:
features = [
record["hour"],
record["weekday"],
np.sin(2 * np.pi * record["hour"] / 24), # Cyklická hodina
np.cos(2 * np.pi * record["hour"] / 24),
np.sin(2 * np.pi * record["weekday"] / 7), # Cyklický den
np.cos(2 * np.pi * record["weekday"] / 7)
]
X.append(features)
y.append(record["price"])
# Trénování modelu
self.model.fit(X, y)
print("Model pro predikci cen natrénován")
def predict_prices(self, hours_ahead=24):
"""
Predikce budoucích cen
"""
predictions = []
current_time = datetime.now()
for h in range(hours_ahead):
future_time = current_time + timedelta(hours=h)
features = [
future_time.hour,
future_time.weekday(),
np.sin(2 * np.pi * future_time.hour / 24),
np.cos(2 * np.pi * future_time.hour / 24),
np.sin(2 * np.pi * future_time.weekday() / 7),
np.cos(2 * np.pi * future_time.weekday() / 7)
]
predicted_price = self.model.predict([features])[0]
predictions.append({
"time": future_time.isoformat(),
"predicted_price": predicted_price,
"confidence": 0.85 # Simulovaná confidence
})
return predictions
def optimize_charging_strategy(self, battery_info, constraints):
"""
Optimalizace nabíjecí strategie pomocí AI
Args:
battery_info: Info o baterii (kapacita, SoC, atd.)
constraints: Omezení (deadline, max cena, atd.)
"""
predictions = self.predict_prices(48) # Predikce na 48 hodin
# Dynamické programování pro optimální plán
strategy = self._dynamic_programming_optimization(
predictions,
battery_info,
constraints
)
return strategy
def _dynamic_programming_optimization(self, predictions, battery_info, constraints):
"""
Optimalizace pomocí dynamického programování
"""
energy_needed = battery_info["capacity_kwh"] * \
(battery_info["target_soc"] - battery_info["current_soc"]) / 100
deadline = constraints.get("deadline", 24) # hodiny
max_price = constraints.get("max_price", float('inf'))
prefer_green = constraints.get("prefer_green_energy", False)
# Inicializace DP tabulky
dp = {}
path = {}
def solve(hour, energy_remaining):
if energy_remaining <= 0:
return 0
if hour >= min(len(predictions), deadline):
return float('inf')
if (hour, energy_remaining) in dp:
return dp[(hour, energy_remaining)]
# Možnosti: nabíjet nebo čekat
price = predictions[hour]["predicted_price"]
# Čekat
wait_cost = solve(hour + 1, energy_remaining)
# Nabíjet
charge_amount = min(11, energy_remaining) # Max 11 kWh za hodinu
charge_cost = price * charge_amount + solve(hour + 1, energy_remaining - charge_amount)
if charge_cost < wait_cost:
dp[(hour, energy_remaining)] = charge_cost
path[(hour, energy_remaining)] = "charge"
else:
dp[(hour, energy_remaining)] = wait_cost
path[(hour, energy_remaining)] = "wait"
return dp[(hour, energy_remaining)]
total_cost = solve(0, energy_needed)
# Rekonstrukce optimálního plánu
plan = []
hour = 0
energy = energy_needed
while hour < len(predictions) and energy > 0:
action = path.get((hour, energy), "wait")
if action == "charge":
charge_amount = min(11, energy)
plan.append({
"hour": hour,
"action": "charge",
"amount_kwh": charge_amount,
"price": predictions[hour]["predicted_price"]
})
energy -= charge_amount
hour += 1
return {
"total_cost": total_cost,
"total_energy": energy_needed,
"avg_price": total_cost / energy_needed if energy_needed > 0 else 0,
"plan": plan
}Krok 4: Integrace s energetickým mixem
class GreenEnergyOptimizer:
"""
Optimalizace nabíjení podle podílu zelené energie
"""
def __init__(self, api_credentials):
self.api_credentials = api_credentials
def get_energy_mix(self):
"""
Získání aktuálního energetického mixu
"""
# Data z ČEPS nebo podobného zdroje
# Pro demonstraci používáme simulovaná data
current_hour = datetime.now().hour
# Simulace energetického mixu během dne
if 11 <= current_hour <= 15: # Polední hodiny - více solární
solar = 35
wind = 15
nuclear = 30
coal = 15
gas = 5
elif 18 <= current_hour <= 22: # Večerní špička
solar = 0
wind = 10
nuclear = 35
coal = 40
gas = 15
else: # Noc
solar = 0
wind = 20
nuclear = 40
coal = 30
gas = 10
return {
"timestamp": datetime.now().isoformat(),
"solar_percent": solar,
"wind_percent": wind,
"nuclear_percent": nuclear,
"coal_percent": coal,
"gas_percent": gas,
"renewable_percent": solar + wind,
"carbon_free_percent": solar + wind + nuclear
}
def calculate_carbon_footprint(self, energy_kwh, energy_mix):
"""
Výpočet uhlíkové stopy nabíjení
"""
# CO2 emisní faktory (kg CO2/kWh)
emission_factors = {
"solar": 0.04,
"wind": 0.01,
"nuclear": 0.01,
"coal": 0.82,
"gas": 0.49
}
total_emissions = 0
for source, factor in emission_factors.items():
percent = energy_mix.get(f"{source}_percent", 0) / 100
total_emissions += energy_kwh * percent * factor
return {
"total_co2_kg": total_emissions,
"co2_per_kwh": total_emissions / energy_kwh if energy_kwh > 0 else 0,
"trees_equivalent": total_emissions / 21 # Jeden strom absorbuje ~21 kg CO2 ročně
}
def find_greenest_hours(self, hours_needed=4):
"""
Najde hodiny s nejvyšším podílem zelené energie
"""
green_hours = []
for hour in range(24):
# Simulace predikce energetického mixu
mix = self.get_energy_mix() # V reálu byste použili predikci
green_hours.append({
"hour": hour,
"renewable_percent": mix["renewable_percent"],
"carbon_free_percent": mix["carbon_free_percent"]
})
# Seřadit podle podílu obnovitelných zdrojů
green_hours.sort(key=lambda x: x["renewable_percent"], reverse=True)
return green_hours[:hours_needed]Monitoring a notifikace
class ChargingMonitor:
"""
Monitoring nabíjení s notifikacemi
"""
def __init__(self, device_id, api_credentials):
self.device_id = device_id
self.api_credentials = api_credentials
self.notification_endpoints = []
def add_notification(self, endpoint_type, config):
"""
Přidání notifikačního endpointu
"""
self.notification_endpoints.append({
"type": endpoint_type,
"config": config
})
def monitor_charging_session(self):
"""
Sledování probíhající nabíjecí relace
"""
session_data = {
"start_time": datetime.now(),
"energy_delivered": 0,
"cost": 0,
"carbon_saved": 0
}
while True:
# Získat aktuální stav
status = self._get_charging_status()
if status["is_charging"]:
# Update statistik
session_data["energy_delivered"] = status["energy_kwh"]
session_data["cost"] = status["energy_kwh"] * status["current_price"]
# Kontrola milníků
if session_data["energy_delivered"] >= 10 and session_data["energy_delivered"] < 10.1:
self._send_notification("10 kWh nabito", session_data)
if status["soc_percent"] >= 80:
self._send_notification("Baterie nabita na 80%", session_data)
break
time.sleep(60) # Kontrola každou minutu
# Finální report
self._generate_session_report(session_data)
def _send_notification(self, message, data):
"""
Odeslání notifikace
"""
for endpoint in self.notification_endpoints:
if endpoint["type"] == "email":
self._send_email(endpoint["config"], message, data)
elif endpoint["type"] == "webhook":
self._send_webhook(endpoint["config"], message, data)
def _generate_session_report(self, session_data):
"""
Generování reportu nabíjecí relace
"""
duration = datetime.now() - session_data["start_time"]
report = f"""
REPORT NABÍJECÍ RELACE
========================
Doba nabíjení: {duration}
Nabito: {session_data['energy_delivered']:.2f} kWh
Celková cena: {session_data['cost']:.2f} Kč
Průměrná cena: {session_data['cost']/session_data['energy_delivered']:.2f} Kč/kWh
Ušetřeno CO2: {session_data['carbon_saved']:.2f} kg
Děkujeme za používání inteligentního nabíjení!
"""
return reportPříklad kompletního použití
# Konfigurace
API_KEY = "YOUR_API_KEY"
API_SECRET = "YOUR_API_SECRET"
DEVICE_ID = "qfeb-od13-ul2c-sgrl"
# Inicializace kontroléru
controller = SmartChargingController(DEVICE_ID, API_KEY, API_SECRET)
# Nastavení parametrů vozidla
vehicle_params = {
"battery_capacity_kwh": 60, # Tesla Model 3 SR+
"current_soc": 25, # Aktuální nabití 25%
"target_soc": 80, # Cílové nabití 80%
"deadline_hours": 12 # Potřebuji nabít do 12 hodin
}
# Naplánování nabíjení
charging_plan = controller.schedule_charging(
battery_capacity_kwh=vehicle_params["battery_capacity_kwh"],
current_soc=vehicle_params["current_soc"],
target_soc=vehicle_params["target_soc"],
max_price=3.0 # Maximální cena 3 Kč/kWh
)
# Spuštění monitoringu
monitor = ChargingMonitor(DEVICE_ID, (API_KEY, API_SECRET))
monitor.add_notification("email", {"to": "user@example.com"})
monitor.monitor_charging_session()Tipy pro maximální úspory
- Nastavte flexibilní deadline - čím více času, tím lepší ceny
- Využijte víkendy - obvykle nižší ceny
- Sledujte predikce počasí - větrné a slunečné dny = levnější energie
- Kombinujte s domácí fotovoltaikou - prioritizujte vlastní výrobu
- Nastavte cenové limity - ochrana před cenovými špičkami