c8e3016fd6
- Implement `sigen_daemon.py` to poll Sigenergy plant metrics and store snapshots. - Create `web_daemon.py` for serving a web interface with various endpoints. - Add debug scripts: - `debug_duplicates.py` to find duplicate target times in forecast data. - `debug_energy_forecast.py` to print baseline energy forecast curves. - `debug_oracle_evaluations.py` to run the oracle evaluator. - `debug_sigen.py` to inspect stored Sigenergy plant snapshots. - `debug_weather.py` to trace resolved truth data. - `modbus_test.py` for exploring Sigenergy plants or inverters over Modbus TCP. - Introduce `oracle_evaluator.py` for evaluating stored oracle predictions against actuals. - Add TCN training scripts in `tcn` directory for training usage sequence models.
61 lines
2.3 KiB
Python
61 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from os import environ
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class EnergyForecastConfig:
|
|
horizon_hours: int = 24
|
|
oracle_step_minutes: int = 15
|
|
fallback_solar_peak_w: float = 10000
|
|
solar_peak_headroom: float = 1.05
|
|
solar_scale: float = 1.0
|
|
solar_training_days: int = 30
|
|
solar_min_training_samples: int = 24
|
|
solar_ridge_lambda: float = 0.1
|
|
load_lookback_minutes: int = 30
|
|
load_profile_days: int = 30
|
|
load_profile_bucket_minutes: int = 15
|
|
load_profile_min_samples: int = 5
|
|
load_recent_blend: float = 0.35
|
|
local_timezone: str = "Europe/Stockholm"
|
|
|
|
@classmethod
|
|
def from_env(cls) -> "EnergyForecastConfig":
|
|
return cls(
|
|
horizon_hours=int(environ.get("ASTRAPE_ENERGY_FORECAST_HOURS", "24")),
|
|
oracle_step_minutes=int(environ.get("ASTRAPE_ORACLE_STEP_MINUTES", "15")),
|
|
fallback_solar_peak_w=float(
|
|
environ.get("ASTRAPE_SOLAR_PEAK_W", "10000")
|
|
),
|
|
solar_peak_headroom=float(
|
|
environ.get("ASTRAPE_SOLAR_PEAK_HEADROOM", "1.05")
|
|
),
|
|
solar_scale=float(environ.get("ASTRAPE_SOLAR_FORECAST_SCALE", "1.0")),
|
|
solar_training_days=int(
|
|
environ.get("ASTRAPE_SOLAR_TRAINING_DAYS", "30")
|
|
),
|
|
solar_min_training_samples=int(
|
|
environ.get("ASTRAPE_SOLAR_MIN_TRAINING_SAMPLES", "24")
|
|
),
|
|
solar_ridge_lambda=float(
|
|
environ.get("ASTRAPE_SOLAR_RIDGE_LAMBDA", "0.1")
|
|
),
|
|
load_lookback_minutes=int(
|
|
environ.get("ASTRAPE_LOAD_LOOKBACK_MINUTES", "30")
|
|
),
|
|
load_profile_days=int(environ.get("ASTRAPE_LOAD_PROFILE_DAYS", "30")),
|
|
load_profile_bucket_minutes=int(
|
|
environ.get("ASTRAPE_LOAD_PROFILE_BUCKET_MINUTES", "15")
|
|
),
|
|
load_profile_min_samples=int(
|
|
environ.get("ASTRAPE_LOAD_PROFILE_MIN_SAMPLES", "5")
|
|
),
|
|
load_recent_blend=float(environ.get("ASTRAPE_LOAD_RECENT_BLEND", "0.35")),
|
|
local_timezone=environ.get(
|
|
"ASTRAPE_LOCAL_TIMEZONE",
|
|
environ.get("TZ", "Europe/Stockholm"),
|
|
),
|
|
)
|