WindPower Agent
CLI-система почасового прогноза нормализованной мощности двух ветротурбин на 24/48 часов по историческим данным и архивному прогнозу погоды…
О проекте
Команда: Astana Hackers
Кейс HackAlem.ai: Энергетика — Самрук-Казына
Стадия: Рабочий MVP
Задача кейса: AI-агент, прогнозирующий выработку ветровой электростанции по погодным данным
Суть
CLI-система почасового прогноза нормализованной мощности двух ветротурбин на 24/48 часов по историческим данным и архивному прогнозу погоды Open-Meteo, с интервалами P10/P50/P90 и расчётом энергии.
Как устроено
10-минутные CSV турбин приводятся к единой схеме, чистятся от дубликатов и агрегируются в часовую сетку, неполные часы исключаются. weather_archive.py берёт последний доступный запуск ECMWF IFS через Open-Meteo Single Runs API (ветер 10/80 м, температура) и сохраняет snapshot с SHA-256 и manifest. forecast_agent.py обучает power curve (биннинг скорости ветра), Ridge с лаговыми, rolling и календарными признаками и LightGBM с квантилями. Модели объединяются ансамблем с весами 0.35/0.20/0.45, прогноз рекурсивный. Бенчмарк считает MAE, RMSE и WMAPE.
Ключевые решения
- power curve binning
- Ridge regression
- LightGBM
- LightGBM quantile P10/P50/P90
- weighted ensemble
- recursive forecasting
- rolling-origin backtest
- Open-Meteo ECMWF IFS
Особенности
Используется архивный прогноз погоды (Single Runs API) с задержкой доступности 6 ч, что честнее для проверки на истории. Provenance каждого snapshot (URL, model run, SHA-256) сохраняется. В backend/wind_agent есть заготовки LLM-чата и оркестратора, но README говорит, что LLM в сценарии не вызывается.
Стек
Python · pandas · NumPy · LightGBM · Open-Meteo API · React · Vite
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-54f1ae1b-astana-hackers.
README
README.mdWindPower Agent
Система краткосрочного прогнозирования почасовой выработки двух ветряных турбин.
1. Название проекта
WindPower Agent — ML-решение для прогноза нормализованной активной мощности турбин на горизонте 24 или 48 часов.
2. Краткое описание
Операторам и диспетчерам ветряных электростанций необходимо заранее понимать ожидаемую выработку, чтобы планировать энергобаланс и эксплуатацию станции. Проект строит почасовой прогноз мощности для двух турбин на основе исторических измерений и погодного прогноза.
Результат выдаётся в нормализованном диапазоне 0–1. Если указать установленную мощность турбины, система дополнительно рассчитывает ожидаемую энергию в кВт·ч и МВт·ч.
Решение запускается локально из командной строки и ориентировано на воспроизводимую проверку жюри хакатона.
3. Что реализовано
- чтение CSV-файлов двух турбин;
- приведение исходных колонок к единой схеме и обработка некорректных дат/чисел;
- удаление дубликатов временных меток;
- агрегация 10-минутных измерений в почасовую сетку;
- исключение неполных часов из обучения и валидации;
- baseline-модель
PowerCurveRegressorс биннингом скорости ветра; RidgePowerRegressorс погодными, календарными, лаговыми и rolling-признаками;- point-модель LightGBM при наличии библиотеки;
- модели квантилей P10/P50/P90 на LightGBM;
- fallback на Ridge и эмпирический residual band, если LightGBM не установлен;
- взвешенный ансамбль моделей;
- рекурсивный прогноз на 24 или 48 часов;
- расчёт MAE, RMSE и WMAPE при benchmark-проверке;
- получение архивного погодного прогноза через Open-Meteo Single Runs API;
- сохранение исходного ответа API, нормализованного CSV и manifest с параметрами запуска и SHA-256;
- расчёт энергии при переданной установленной мощности;
- сохранение прогнозов в CSV и метаданных запусков в JSONL.
4. Как работает решение
Основной сценарий:
- Пользователь задаёт дату и время запуска прогноза, горизонт и, при необходимости, мощность турбин.
weather_archive.pyвыбирает последний доступный модельный запуск погоды и получает для координат каждой турбины почасовые значения температуры и скорости ветра.- Исторические CSV читаются и агрегируются до часовой сетки.
- На данных до момента прогноза обучаются power curve, Ridge и LightGBM (если доступен).
- Для каждого будущего часа формируются признаки и рассчитываются прогнозы отдельных моделей.
- Прогнозы объединяются фиксированными весами: power curve — 0.35, Ridge — 0.20, LightGBM — 0.45. При отсутствии LightGBM его компонент заменяется Ridge fallback.
- Одновременно формируется интервал P10/P50/P90.
- Нормализованная мощность сохраняется в
outputs/forecast/*.csv; при заданной мощности добавляются оценки энергии.
Для отдельного benchmark-сценария ml_baseline.py использует исторические измеренные ветер и температуру на validation-горизонте. Это benchmark для проверки моделей, а не полноценная оценка качества будущего прогноза погоды.
5. Технологии
- Python 3.10+;
- pandas — чтение и обработка временных рядов;
- NumPy — признаки, расчёты и Ridge-регрессия;
- LightGBM — point- и quantile-регрессия;
- стандартная библиотека Python (
urllib,json,csv,hashlib,zoneinfo) — запросы, нормализация и versioning погодных данных; - argparse — CLI-интерфейс;
- Open-Meteo Single Runs API — архивные погодные прогнозы;
- JSON/JSONL/CSV — форматы результатов и метаданных.
Полный набор объявленных зависимостей находится в requirements.txt. В нём также указаны scikit-learn, requests, pyarrow, fastapi, uvicorn, anthropic, openai, python-dotenv, joblib и pytest; текущий CLI-пайплайн напрямую использует прежде всего pandas, NumPy и опционально LightGBM. LLM API в текущем сценарии не вызываются.
6. Архитектура проекта
datasets/*.csv
│
▼
ml_baseline.py
├─ read_turbine_csv()
├─ to_hourly()
├─ make_features()
├─ PowerCurveRegressor
├─ RidgePowerRegressor
└─ evaluate_origins()
│
└──────────────► outputs/ml_benchmark.json
weather_archive.py ──► Open-Meteo API
│
└──────────────► outputs/weather_archive/
├─ runs/*/response.json
├─ runs/*/forecast.csv
└─ manifest.jsonl
forecast_agent.py
├─ получает/читает weather snapshot
├─ обучает набор моделей
├─ строит ensemble и P10/P50/P90
└─ рассчитывает энергию
│
└──────────────► outputs/forecast/
├─ forecast_*.csv
└─ forecast_manifest.jsonl
Основные файлы:
ml_baseline.py— подготовка исторических данных, модели baseline/Ridge и валидация;weather_archive.py— выбор доступного запуска погоды, запрос Open-Meteo и сохранение snapshot;forecast_agent.py— интегрированный сценарий «погода → модели → интервалы → энергия»;requirements.txt— зависимости проекта;datasets/— исторические CSV турбин.
7. Установка и запуск
7.1. Установка
git clone https://github.com/BAITC-Hacks/hack-54f1ae1b-astana-hackers.git
cd hack-54f1ae1b-astana-hackers
python -m venv .venv
# Linux/macOS
source .venv/bin/activate
# Windows PowerShell:
# .\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
Для минимального benchmark достаточно установить pandas и NumPy:
python -m pip install "pandas>=2.2,<3" "numpy>=2,<3"
7.2. Benchmark исторических данных
В репозитории должны присутствовать два файла из раздела «Данные и интеграции». Запуск из корня проекта:
python ml_baseline.py \
--turbine1 "datasets/Dataset HackAlemAI для участников 11.03.2023-28.02.2026 - turbine 1.csv" \
--turbine2 "datasets/Dataset HackAlemAI для участников 11.03.2023-28.02.2026 - turbine 2.csv" \
--output outputs/ml_benchmark.json
В Windows PowerShell используйте обратный апостроф ` вместо \ для переноса строк либо выполните команду в одну строку.
7.3. Проверка выбора погодного запуска без сетевого запроса
python weather_archive.py \
--as-of "2026-01-31T00:00" \
--horizon-hours 48 \
--dry-run
7.4. Полный прогноз
Команда ниже получает погодные данные, строит ансамблевый прогноз и сохраняет результаты:
python forecast_agent.py \
--as-of "2026-01-31T00:00" \
--horizon-hours 48 \
--capacity-kw-turbine1 3000 \
--capacity-kw-turbine2 3000
Значения --capacity-kw-turbine1 и --capacity-kw-turbine2 нужно заменить на фактическую установленную мощность. Если параметры не указаны, прогноз мощности всё равно строится, но абсолютная энергия не рассчитывается.
8. Как проверить решение
Жюри может повторить следующий сценарий:
- Клонировать репозиторий и установить зависимости.
- Убедиться, что CSV-файлы находятся в
datasets/. - Запустить benchmark из раздела 7.2.
- Проверить напечатанные в консоли MAE, RMSE, WMAPE и число использованных validation origins.
- Открыть JSON-результат:
cat outputs/ml_benchmark.json
В Windows PowerShell:
Get-Content -Raw .\outputs\ml_benchmark.json
Для проверки полного пользовательского сценария запустите команду из раздела 7.4 с доступом к интернету и проверьте:
outputs/weather_archive/manifest.jsonlи сохранённые погодные snapshot;outputs/forecast/forecast_turbine_*.csv;outputs/forecast/forecast_manifest.jsonl;- колонки
power_p10_norm,power_p50_norm,power_p90_normи, при заданной мощности,energy_p50_kwh/energy_p50_mwh.
9. Данные и интеграции
Исторические данные
Используются два CSV-файла:
datasets/Dataset HackAlemAI для участников 11.03.2023-28.02.2026 - turbine 1.csv;datasets/Dataset HackAlemAI для участников 11.03.2023-28.02.2026 - turbine 2.csv.
Первые пять колонок интерпретируются как идентификатор, время, средняя скорость ветра, нормализованная активная мощность и средняя температура окружающей среды. Исходная периодичность — 10 минут.
Погодный API
weather_archive.py использует Open-Meteo Single Runs API:
https://open-meteo.com/en/docs/single-runs-api
Для турбин заданы координаты:
- turbine 1:
43.645150, 78.535604; - turbine 2:
43.643194, 78.538833.
Запрашиваются temperature_2m, wind_speed_10m и wind_speed_80m. Используется модель ecmwf_ifs, часовой пояс Asia/Almaty, выбор наземной grid cell и консервативная задержка доступности запуска 6 часов.
Каждый snapshot содержит исходный JSON, нормализованный CSV и запись provenance в manifest.jsonl, включая URL, выбранный model run, координаты, горизонт, время получения и SHA-256 ответа.
10. Ограничения текущей версии
- нет веб-интерфейса, публичного API, планировщика и production-мониторинга;
- deployed-версия отсутствует, запуск выполняется локально через CLI;
- validation в
ml_baseline.pyиспользует фактические исторические погодные значения, а не архивный forecast, доступный на момент исторического запуска; - LightGBM является опциональным для работы
forecast_agent.py: без него используется Ridge fallback, а интервалы строятся по residual band; - веса ансамбля заданы конфигурационно и автоматически не подбираются по out-of-fold-прогнозам;
- абсолютная энергия зависит от корректно переданной установленной мощности;
- рекурсивный прогноз может накапливать ошибку на длинном горизонте;
- архивные погодные snapshot сохраняются локально, но автоматическое управление сроком их хранения не реализовано;
- текущая версия работает с двумя заранее заданными турбинами и не предоставляет универсальный интерфейс конфигурации станции.
11. Deployed-версия
В текущем репозитории deployed-версия не обнаружена. Решение запускается локально командами из раздела 7.
Исходный репозиторий: https://github.com/BAITC-Hacks/hack-54f1ae1b-astana-hackers
Авторы коммитов
История коммитов
- 2026-09-23 17:44Create comprehensive Russian README for WindPower Agentjanymau
- 2026-09-23 17:42BackendArkazhan
- 2026-09-23 17:40other filesjanymau
- 2026-09-23 17:35Merge pull request #1 from BAITC-Hacks/new-mljanymau
- 2026-09-23 17:27more-powerfull-ml-modelsArkazhan
- 2026-09-23 16:28ML-baseline-readmejanymau
- 2026-09-23 16:18ML-baselinejanymau
- 2026-09-23 17:42test-frontendErsultanN
Все коммиты (9)
- 2026-09-23 16:52open-meteo api featureErsultanN
Структура репозитория (60 файлов)
README.md artifacts/agent_log_production.jsonl artifacts/agent_log_validation.jsonl artifacts/metrics_validation.json artifacts/missing_turbine_1.json artifacts/missing_turbine_2.json artifacts/model_selection.json artifacts/model_selection_basis.json artifacts/predictions_production.csv artifacts/predictions_validation.csv artifacts/previous_runs_check.json artifacts/revisions_production.csv artifacts/revisions_validation.csv artifacts/run_summary.json artifacts/selected_production.csv artifacts/selected_validation.csv backend/wind_agent/__init__.py backend/wind_agent/analysis.py backend/wind_agent/api.py backend/wind_agent/backtest.py backend/wind_agent/chat.py backend/wind_agent/config.py backend/wind_agent/data.py backend/wind_agent/llm.py backend/wind_agent/model.py backend/wind_agent/orchestrator.py backend/wind_agent/tools.py backend/wind_agent/weather_agent.py data/case.pdf data/raw/turbine_1.csv data/raw/turbine_2.csv datasets/Dataset HackAlemAI для участников 11.03.2023-28.02.2026 - turbine 1.csv datasets/Dataset HackAlemAI для участников 11.03.2023-28.02.2026 - turbine 2.csv forecast_agent.py frontend/index.html frontend/package-lock.json frontend/package.json frontend/src/main.jsx frontend/src/style.css frontend/vite.config.js install_advanced_ml.ps1 integration_forecast_local/forecast_manifest.jsonl integration_forecast_local/forecast_turbine_1_20260131T0000.csv integration_forecast_local/forecast_turbine_2_20260131T0000.csv ml_baseline.py outputs/ml_benchmark.json requirements.txt tests/test_chat.py tests/test_core.py weather_archive.py weather_archive_test/manifest.jsonl weather_archive_test/runs/turbine_1__asof-20260130T1900Z__run-20260130T1200Z__retrieved-20260923T113345Z__11a60b0f/forecast.csv weather_archive_test/runs/turbine_1__asof-20260130T1900Z__run-20260130T1200Z__retrieved-20260923T113345Z__11a60b0f/response.json weather_archive_test/runs/turbine_2__asof-20260130T1900Z__run-20260130T1200Z__retrieved-20260923T113346Z__7a6a903e/forecast.csv weather_archive_test/runs/turbine_2__asof-20260130T1900Z__run-20260130T1200Z__retrieved-20260923T113346Z__7a6a903e/response.json weather_archive_test2/manifest.jsonl weather_archive_test2/runs/turbine_1__asof-20260130T1900Z__run-20260130T1200Z__retrieved-20260923T113509Z__658a0902/forecast.csv weather_archive_test2/runs/turbine_1__asof-20260130T1900Z__run-20260130T1200Z__retrieved-20260923T113509Z__658a0902/response.json weather_archive_test2/runs/turbine_2__asof-20260130T1900Z__run-20260130T1200Z__retrieved-20260923T113509Z__6abb764c/forecast.csv weather_archive_test2/runs/turbine_2__asof-20260130T1900Z__run-20260130T1200Z__retrieved-20260923T113509Z__6abb764c/response.json
Ветки (4)
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.