services/discord_bot.py: gateway klient jako lifespan task (spojení ven, žádný veřejný endpoint; bez DISCORD_BOT_TOKEN tiše spí). Tlačítka [za 2h][za 4h][ráno][do plna][nenabíjet] s custom_id ev:<site>:<charger>:<akce> (přežijí restart); whitelist DISCORD_ALLOWED_USER_IDS; akce = fn_ev_session_ apply_patch → run_rolling_replan → export_setpoints → edit zprávy novým plánem. services/ev_notify.py: sdílený builder souhrnu (vyčleněno z collectoru), send bot-first s webhook fallbackem. requirements: discord.py>=2.4. 7 testů helperů (parse, deadline akce vč. morning přes Prague TZ). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
65 lines
2.1 KiB
Python
65 lines
2.1 KiB
Python
"""Application settings loaded from environment (see .env.example)."""
|
|
|
|
from functools import lru_cache
|
|
|
|
from pydantic import Field
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
model_config = SettingsConfigDict(
|
|
env_file=".env",
|
|
env_file_encoding="utf-8",
|
|
extra="ignore",
|
|
)
|
|
|
|
db_host: str = Field(default="localhost")
|
|
db_port: int = Field(default=5432)
|
|
db_name: str = Field(default="ems")
|
|
db_user: str = Field(default="ems_user")
|
|
db_password: str = Field(default="")
|
|
database_url: str | None = Field(default=None)
|
|
|
|
postgrest_jwt_secret: str = Field(default="")
|
|
postgrest_anon_role: str = Field(default="ems_anon")
|
|
|
|
ote_api_url: str = Field(
|
|
default=(
|
|
"https://www.ote-cr.cz/cs/kratkodobe-trhy/elektrina/denni-trh/@@chart-data"
|
|
),
|
|
)
|
|
eur_czk_rate: float = Field(default=25.0)
|
|
|
|
open_meteo_api_url: str = Field(
|
|
default="https://api.open-meteo.com/v1/forecast",
|
|
)
|
|
open_meteo_forecast_days: int = Field(default=7)
|
|
|
|
loxone_user: str = Field(default="")
|
|
loxone_password: str = Field(default="")
|
|
|
|
discord_webhook_url: str = Field(default="")
|
|
|
|
telemetry_poll_interval_sec: int = Field(default=60)
|
|
planning_horizon_hours: int = Field(default=36)
|
|
planning_hp_max_cost_czk_kwh: float = Field(default=3.0)
|
|
planning_cheap_price_threshold: float = Field(default=0.85)
|
|
planning_expensive_price_threshold: float = Field(default=1.15)
|
|
# Discord bot — fáze B tlačítka (docs/discord-ev-interaction.md); prázdné = jen webhook
|
|
discord_bot_token: str = Field(default="")
|
|
discord_ev_channel_id: str = Field(default="")
|
|
discord_allowed_user_ids: str = Field(default="")
|
|
|
|
# Tesla Fleet API (docs/tesla-fleet-api.md); prázdné = integrace vypnutá
|
|
tesla_client_id: str = Field(default="")
|
|
tesla_client_secret: str = Field(default="")
|
|
tesla_refresh_token: str = Field(default="")
|
|
|
|
planning_engine_version: str = Field(default="v1")
|
|
planning_engine_compare_enabled: bool = Field(default=False)
|
|
|
|
|
|
@lru_cache
|
|
def get_settings() -> Settings:
|
|
return Settings()
|