AAYMA
RU
Войти

WindPilot

Сервис, который превращает прогноз погоды в почасовой прогноз нормализованной мощности двух ветротурбин на 24–48 часов.

Доведённый продукт
Команда «Entropy» 11💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: Entropy
Кейс HackAlem.ai: Энергетика — Самрук-Казына
Стадия: Доведённый продукт

Задача кейса: AI-агент, прогнозирующий выработку ветровой электростанции по погодным данным

Суть

Сервис, который превращает прогноз погоды в почасовой прогноз нормализованной мощности двух ветротурбин на 24–48 часов. В дашборде есть сравнение с фактом, история, погода на площадке, подбор периода по порогу мощности, журнал шагов агента и карта ветра Windy.

Как устроено

Исходные CSV по турбинам (10-минутный шаг) агрегируются в часы с учётом часового пояса Asia/Almaty. Для каждой турбины своя модель HistGradientBoostingRegressor из двух компонент: базовая зависимость мощности от ветра и температуры плюс поправка по архивной прогнозной погоде (горизонт, циклические признаки часа). Погода берётся из Open-Meteo ECMWF IFS (ветер 100 м, температура 2 м), архив из Single Runs API. Детерминированный агент без LLM проходит шесть шагов (погода → проверка → признаки → модели → проверки → сохранение версии) и автообновляется каждые 900 с.

Ключевые решения

  • HistGradientBoostingRegressor
  • двухступенчатая модель (база + поправка по прогнозной погоде)
  • бэктест с временной границей обучения
  • baseline по последнему измерению
  • планировщик автообновления
  • версионирование расчётов

Метрики

Январь 2026, горизонт 1–48 ч: MAE 0,2093/0,2083, RMSE 0,2663/0,2657 (турбины 1/2) против бейзлайна MAE 0,3413/0,3440, RMSE 0,4486/0,4544; смещение +0,089

Особенности

Аккуратная валидация: модели обучены строго до момента прогноза, отдельная августовская ретроспектива, проверка перехода часовых поясов. В README честно названы систематическое завышение мощности (+0,09) и допущение о доступности выпуска IFS через 12 ч. Runtime-артефакты упакованы в zip с проверкой SHA-256, есть офлайн-дашборд и демо на Render.

Стек

Python · FastAPI · Uvicorn · scikit-learn · Open-Meteo · Windy · JavaScript · HTML · CSS · Render


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-16b87636-entropy.

README

README.md

WindPilot — прогноз выработки ВЭС

Команда Entropy · HackAlem AI

https://windpilot-demo.onrender.com/

WindPilot превращает прогноз погоды в почасовой прогноз относительной мощности двух ветротурбин на 24–48 часов. Пользователь видит ожидаемую выработку, сравнивает расчёт с историческими измерениями и просматривает реальные шаги агента.

Агент самостоятельно получает погоду по координатам установок, проверяет входы, запускает модель, анализирует результат и создаёт новую версию при изменении данных. Готовые модели и архив включены в репозиторий: для запуска сайта обучение не требуется.

Мощность модели — число от 0 до 1; интерфейс показывает его как 0–100%. Это нормализованная мощность по шкале датасета, не МВт, не вероятность и не процент точности. Обзор двух установок — среднее их нормализованных мощностей, а не суммарная мощность ВЭС.

Быстрый запуск

Нужны Python 3.11, Git и доступ к репозиторию. Интернет нужен для установки зависимостей, текущей погоды и карты. Сохранённые исторические расчёты работают из комплекта данных.

Windows / PowerShell

git clone https://github.com/BAITC-Hacks/hack-16b87636-entropy.git
cd hack-16b87636-entropy
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe scripts/restore_runtime.py
.\.venv\Scripts\python.exe -m uvicorn windpilot.api:app --host 127.0.0.1 --port 8000 --workers 1

Linux / macOS

git clone https://github.com/BAITC-Hacks/hack-16b87636-entropy.git
cd hack-16b87636-entropy
python3.11 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python scripts/restore_runtime.py
.venv/bin/python -m uvicorn windpilot.api:app --host 127.0.0.1 --port 8000 --workers 1

Откройте http://127.0.0.1:8000/. Документация API: http://127.0.0.1:8000/docs. Проверка сервера: /health.

Один worker нужен для согласованной работы встроенного планировщика и сохранения версий расчёта. Не запускайте несколько процессов на одну папку результатов.

restore_runtime.py проверяет SHA-256 файлов из deployment/runtime.zip по манифесту. Повторное восстановление не перезаписывает изменённые локальные артефакты. Исходные CSV и пути к компьютеру разработчика для просмотра не нужны.

Просмотр без сервера: откройте dashboard.html как файл. В нём есть 58 сохранённых расчётов, график, таблица и подбор периода. Полная история с фактом, текущая погода, живой прогноз и карта требуют FastAPI. Автономный режим явно обозначен.

Возможности

РазделЧто можно сделать
Сегодня и завтраПолучить прогноз мощности на текущих погодных входах, с отметкой демо-режима.
Обзор и «По часам»Посмотреть график, пик и минимум, значения по установкам, погодные входы; скачать CSV.
Прогноз и фактСравнить январскую проверку и августовскую ретроспективу с измерениями; один прогноз на час, горизонт 1–24 часа.
ИсторияВыбрать до 31 дня, посмотреть последние измерения, пропуски и происхождение расчётов.
Погода на площадкеПосмотреть температуру, ветер, порывы, влажность; прогноз по дням с выбором параметров.
Подобрать периодНайти часы с мощностью не ниже порога или с минимальным средним уровнем. Это не разрешение на ремонт и не гарантия производства.
Работа агентаПроследить шесть шагов, реальные отметки времени, версию модели, проверки и автообновление.
Карта ветраОткрыть независимый слой Windy, приблизить установки, выбрать прогнозный день и час.

Среднее двух установок выводится только при наличии обоих значений за час. Пропуски остаются пустыми ячейками и разрывами линий. MAE/RMSE доступны в отчётах и API, без перегрузки бизнес-интерфейса.

Данные и доступные периоды

Исходные данные — два CSV, по одному на турбину: время, скорость ветра, нормализованная активная мощность и температура. Интервал — 10 минут. Подготовка проверяет даты, дубликаты, пропуски и диапазоны; час считается средним только при наличии всех шести корректных записей.

Часовой пояс CSV подтверждён как Asia/Almaty. При переводе в UTC учитывается историческое изменение смещения; неоднозначные локальные отметки исключаются, а не угадываются. Координаты и погодная конфигурация находятся в config.json.

ПериодФактическая мощностьПрогноз мощности
11.03.2023 — 31.01.2026Есть, с пропускамиСохранён только для подготовленных проверочных периодов.
Август 2025737 полных часов на каждую турбинуОтдельный бэктест: 648 часов прогноза, 641 час с парой «прогноз — факт» на турбину.
Январь 2026744 часа на каждую турбинуОтложенная проверка; обучение строго до первого момента прогноза.
Февраль 2026Нет в предоставленных файлахВоспроизведение на архивной погоде.
Август 2026НетСохранённых расчётов нет.
Текущая датаНет подключения к измерениям мощностиЖивой прогноз; качество на текущей дате не проверено.

Несмотря на название исходных файлов с упоминанием февраля, фактические записи заканчиваются 31 января 2026. Погодный API не предоставляет фактическую выработку наших турбин.

В августе 2025 прогноз отсутствует 7–10 августа: в архиве не нашлось полных погодных входов. Для 6 августа использован выпуск на 24 часа старше исходно выбранного. Замена отражена в метаданных и CSV; более свежие выпуски из будущего не использовались. Августовский отчёт.

Как работает агент

flowchart LR
    A[Запрос пользователя или таймер] --> B[Получить погоду Open-Meteo]
    B --> C[Проверить входы и их версию]
    C --> D{Входы изменились?}
    D -->|Да| E[Подготовить признаки]
    E --> F[Запустить модели турбин]
    F --> G[Сформировать почасовой прогноз]
    G --> H[Проверить диапазон, пропуски и изменения]
    H --> I[Сохранить CSV, JSON и журнал]
    D -->|Нет| J[Вернуть сохранённый расчёт]

Это агент с явной цепочкой действий и проверок, без LLM-чата и управления оборудованием. Обучение — отдельная операция; обычный прогноз веса не меняет.

Исторический агент проверяет границу обучения и соответствие погодной конфигурации. Живой агент сравнивает новые входы с последним запуском, а результаты — по совпадающим целевым часам. Невалидная или неполная погода приводит к понятной ошибке. Число ограничений предсказаний до диапазона [0, 1] записывается в анализ.

По умолчанию FastAPI запускает живую проверку при старте и затем через 900 секунд после завершения предыдущего цикла. Настройка: WINDPILOT_AUTO_REFRESH_SECONDS; 0 отключает таймер, положительное значение должно быть не меньше 30. Статус — /agent/status. Переменную задавайте в окружении процесса; .env автоматически используется только для ключа карты.

Версии и журнал хранятся в artifacts/api_runs/ для исторического API и artifacts/live_runs/ для живых расчётов. Фоновое обновление не заменяет выбранную историческую дату текущими данными.

ML-модель и качество

Используется scikit-learn HistGradientBoostingRegressor, отдельно для каждой установки. У каждой модели два компонента:

  1. Базовая зависимость мощности от наблюдённых ветра и температуры.
  2. Поправка по архивной прогнозной погоде: ветер, температура, горизонт, циклические признаки часа UTC и выход базовой модели.

Фиксирован random_seed=42. LightGBM, LSTM, лаги фактической мощности и прогнозные интервалы в текущую архитектуру не входят.

Основная модель обучена до 31.01.2026, 23:00 местного времени; январская проверочная — до 31.12.2025, 23:00. Для августа используется третья независимая модель, обученная до 31.07.2025, 23:00. Обучающие часы должны завершиться к соответствующей границе.

Январь 2026, горизонт 1–48 часов: метрики по 1464 парам «момент прогноза / целевой час» на турбину. Пересекающиеся прогнозы оцениваются отдельно; это 744 уникальных часа, а не 1464 независимых наблюдения.

УстановкаMAE моделиRMSE моделиMAE бейзлайнаRMSE бейзлайна
10,20930,26630,34130,4486
20,20830,26570,34400,4544

Бейзлайн — последнее завершённое известное измерение, если его возраст не больше трёх часов. Ошибки выражены на шкале мощности 0–1: MAE 0,20 означает отклонение в среднем на 20 процентных пунктов, а не «точность 80%».

Экран «Прогноз и факт» использует только горизонт 1–24 часа, поэтому его выборка отличается от таблицы выше. Разрезы сохранены в artifacts/metrics.json после восстановления пакета. Январское среднее смещение составляет +0,0892/+0,0902: модель систематически завышает мощность. Физическая отсечка при экстремальном ветре не моделируется надёжно.

Погода, карта и ограничения

Для мощности используется Open-Meteo / ECMWF IFS: ветер на 100 м и температура на 2 м. Архив запрашивается через Single Runs API, текущая погода — через Forecast API.

В историческом расчёте выпуск выбирается с допущением доступности через 12 часов после инициализации. Инициализация не равна публикации. Первоначальное оперативное происхождение архива независимо не подтверждено; для части истории IFS поставщик упоминает hindcast. Результаты представлены как ретроспективное воспроизведение, а не журнал прогнозов, действительно выданных нашей системой в те даты.

Живой API не сообщает используемое здесь время выпуска: weather_issued_at=null. Возраст выпуска не выдумывается. В живом прогнозе нет бейзлайна, поскольку нет свежих измерений мощности. «Онлайн» означает доступ к погодному источнику, а не соединение с энергосистемой.

Карта Windy / GFS у поверхности — отдельная визуализация. Её время не меняет входы модели мощности. Доступны ближайшие прогнозные дни, подтверждённые Windy; архива прошлых месяцев на карте нет. Погода за прошлые периоды в разделе истории относится к точкам установок.

Карта необязательна. Для неё задайте WINDY_MAP_API_KEY в окружении или локальном .env; без ключа остальные разделы работают. Ключ браузерный, поэтому ограничьте его разрешёнными доменами. .env и ключ не входят в Git. Бесплатный Windy Testing предназначен для разработки; условия публичного использования проверьте отдельно. Настройка карты, документация Windy.

У системы нет доверительных интервалов P10/P90, подтверждённой диагностики остановок, модели обледенения, подключения к энергосистеме и автоматического управления турбинами. Визуальные элементы не имитируют эти возможности.

HTTP API

Метод и маршрутНазначение
GET /Дашборд.
GET /healthСостояние процесса и наличие основной модели.
GET /forecast?date=2026-02-15&horizon=48&offline=trueИсторический прогноз; date — первый целевой день, origin — 23:00 предыдущего дня.
GET /forecast/live?horizon=48Живой демонстрационный прогноз на 24 или 48 часов.
GET /history?start=2026-01-01&end=2026-01-31Факт и прогноз, обе даты включены, максимум 31 день.
GET /history/availabilityГраницы наблюдений и подготовленные прогнозные периоды.
GET /weather/overview?turbine_id=1Текущая погодная оценка и семь дней прогноза; refresh=true обновляет кэш.
GET /weather/statusПроверка доступности Open-Meteo.
GET /agent/statusСостояние фонового цикла, последняя и следующая проверки.
GET /qualityЯнварские метрики и допущения проверки.
GET /map/windyСтраница карты внутри iframe.

/forecast: offline=true запрещает сеть; refresh=true проверяет архив через сеть, если offline выключен. Январские запросы выбирают проверочную модель. Августовская ретроспектива читается через /history, а не основной /forecast.

Основные поля прогноза: run_id, turbine_id, forecast_origin, valid_at, power_pred, weather_source, weather_issued_at, model_version. Ответ также содержит status (created/reused), analysis, trace и baseline. История возвращает power_actual, погодные поля, вид расчёта и уведомления; недоступные значения — null.

Шкала исторического обзора выбирает дату origin, API принимает дату первого целевого часа. Например, 31 января в 23:00 соответствует /forecast?date=2026-02-01.

Воспроизведение и разработка

Команды ниже выполняются с Python из созданного окружения: в PowerShell замените python на .\.venv\Scripts\python.exe, в Linux/macOS — на .venv/bin/python.

Расчёты из готового пакета

python -m windpilot forecast --origin 2026-01-31T23:00:00+05:00 --horizon 48 --offline
python -m windpilot replay --start 2026-02-01 --end 2026-02-28 --horizon 48 --offline --out artifacts/february_replay
python scripts/backtest_august_2025.py

replay выполняет 28 запусков перед целевыми днями 1–28 февраля. В дашборде 58 расчётов: 29 origins с 31 января по 28 февраля, каждый на 24 и 48 часов; последний origin прогнозирует уже март. Полные горизонты сохраняются даже за границей месяца.

Августовский скрипт повторно обучает только отдельную августовскую модель. С готовым кэшем он работает без сети; --fetch-weather разрешает получение архива. Основные веса и январские результаты защищены проверками контрольных сумм.

Обучение из исходных CSV

Этот шаг необязателен для демонстрации. Положите два исходных файла в data/raw/ под указанными именами либо передайте свои пути. Папка data/ исключена из Git. Ожидаются исходные русские заголовки столбцов; их сопоставление — в data.py.

python -m windpilot prepare --turbine-1 "data/raw/turbine1.csv" --turbine-2 "data/raw/turbine2.csv" --out data/retrained
python -m windpilot fetch-weather --start 2025-10-01 --end 2026-03-01
python -m windpilot train --history data/retrained/hourly.csv --weather-start 2025-10-01 --validation-start 2026-01-01 --validation-end 2026-01-31 --final-cutoff 2026-01-31T23:00:00+05:00 --out artifacts/retrained

Результат записывается отдельно от поставляемых моделей. Диапазон наблюдений читается из CSV; границы эксперимента задаются параметрами CLI и не расширяются автоматически при поступлении новых данных. Для прогноза с новыми весами укажите --model artifacts/retrained/model.joblib. Недостающие погодные выпуски нужно получить до обучения.

Сборка интерфейса и комплекта

python scripts/build_dashboard.py
python scripts/package_runtime.py

Первая команда собирает HTML из web/, сохраняя существующие 58 расчётов. Вторая упаковывает текущие подготовленные артефакты и контрольные суммы; запускайте её после осознанного обновления данных. Для пересчёта встроенных 58 запусков служит python -m windpilot.export_dashboard: ему нужны диагностические зависимости и погодный кэш до первого целевого дня 01.03.2026.

Проверки

API-тестам и проверке комплекта нужен httpx, поэтому установите диагностические зависимости:

python -m pip install -r requirements-diagnostics.txt
python -m unittest discover -s tests -v
python scripts/check_deployment_bundle.py

DOM-тесты интерфейса — отдельно, нужен Node.js (проверено на версии 24):

npm install --prefix artifacts/ui_checks [email protected] --no-audit --no-fund
node tests/dashboard.test.cjs
node tests/weather_ui.test.cjs
node tests/history_ui.test.cjs
node tests/map_time.test.cjs

Перед текущим релизом прошли 36 Python-тестов, четыре набора DOM-тестов и воспроизведение 58 расчётов в изолированной папке без исходных CSV. В браузере проверены январь/август, отсутствие факта, CSV, обе темы, мобильный вид, живой прогноз и выбор часа Windy. Локальная проверка не подтверждает доступность публичного сервиса.

Расширенная диагностика: python -m windpilot.predict_checks. Для python -m windpilot.diagnostics нужны исходные CSV; пути передаются через --turbine-1 и --turbine-2. Диагностика не изменяет основные веса.

Публикация

Подготовлен render.yaml: один FastAPI-сервис, отдающий HTML и API с одного домена. Раздельный фронтенд и CORS не требуются. Сборка восстанавливает комплект моделей; обучение при деплое не выполняется.

Публичный HTTPS-деплой пока не подтверждён. Для публикации Render должен получить доступ к закрытому репозиторию организации; подключение только личного GitHub-аккаунта его не заменяет. Порядок публикации и проверки.

На Render Free сервис засыпает после простоя; первое обращение запускает его заново. Во время сна фоновая проверка погоды не выполняется. Новые живые расчёты на непостоянном диске могут теряться после перезапуска; исходный комплект восстанавливается из репозитория. Это ограничение хостинга, не непрерывная работа 24/7. Условия Render Free.

После получения фактической ссылки проверьте её с другого устройства и запустите python scripts/check_public_service.py https://ВАШ-СЕРВИС.onrender.com — замените пример реальным адресом.

Структура проекта

ПутьСодержимое
windpilot/Подготовка данных, модель, погода, агенты, планировщик, FastAPI, история.
web/Исходники HTML/CSS/JS, история, погода и отдельная страница Windy.
dashboard.htmlСобранный интерфейс и встроенные исторические расчёты.
config.jsonКоординаты, часовой пояс, источник погоды и задержка доступности.
scripts/Сборка, упаковка, восстановление, проверка деплоя и августовский бэктест.
tests/Python- и JavaScript-проверки.
reports/Диагностика и описание ограничений.
deployment/Комплект моделей/данных, манифест, инструкции хостинга и карты.
data/, artifacts/Рабочие данные и результаты после восстановления; исключены из Git.

Комплект содержит основную, январскую проверочную и августовскую модели, подготовленную историю, архив погоды и результаты. Исходные CSV, .env, ключи, виртуальное окружение и новые живые пользовательские запуски в него не включаются.

Звёзды
⭐ 1
Форки
0
Язык
HTML
Последний push
в прошлом месяце
Коммиты
15
Авторы
3
Файлы
56
Ветки
1

Авторы коммитов

Mevinss 11Assem Abdikarim 3Sarsenbayeva Aidana 1

История коммитов

  • 2026-09-23 17:54Add demo URL to READMEAssem Abdikarim
  • 2026-09-23 17:53Remove jury scenario section from READMEAssem Abdikarim
  • 2026-09-23 17:46Fix formatting by removing an empty lineSarsenbayeva Aidana
  • 2026-09-23 17:45Fix formatting in deployment section of READMEAssem Abdikarim
  • 2026-09-23 17:36docs: rewrite WindPilot README for judges and reproducible setupMevinss
  • 2026-09-23 17:19Fix actual-series legend contrast in history chartsMevinss
  • 2026-09-23 17:16feat: add live site weather and historical forecast comparisonMevinss
  • 2026-09-23 16:22Publish business dashboard with live agent and optional wind mapMevinss
Все коммиты (15)
  • 2026-09-23 15:45Document web interface and agent architectureMevinss
  • 2026-09-23 15:10Package WindPilot for single-service Render deploymentMevinss
  • 2026-09-23 15:03Refine dashboard interface and update documentationMevinss
  • 2026-09-23 14:44Add dashboard testsMevinss
  • 2026-09-23 14:43Add portable dashboard exportMevinss
  • 2026-09-23 14:40Add WindPilot dashboardMevinss
  • 2026-09-23 14:39Add WindPilot forecasting pipeline, API, tests and diagnosticsMevinss
Структура репозитория (56 файлов)
.env.example
.gitignore
README.md
config.json
dashboard.html
deployment/README.md
deployment/WINDY.md
deployment/manifest.json
deployment/runtime.zip
render.yaml
reports/august_2025.md
reports/january_2026_diagnostics.md
reports/power_curve_january.png
reports/windpilot_project_audit_2026-09-23.md
requirements-diagnostics.txt
requirements.txt
scripts/backtest_august_2025.py
scripts/build_dashboard.py
scripts/check_deployment_bundle.py
scripts/check_public_service.py
scripts/package_runtime.py
scripts/restore_runtime.py
tests/dashboard.test.cjs
tests/history_ui.test.cjs
tests/map_time.test.cjs
tests/test_api.py
tests/test_dashboard.py
tests/test_history_view.py
tests/test_live_agent.py
tests/test_map_view.py
tests/test_pipeline.py
tests/test_weather_overview.py
tests/weather_ui.test.cjs
web/dashboard.css
web/dashboard.js
web/dashboard.template.html
web/history.js
web/weather.js
web/windy.html
windpilot/__init__.py
windpilot/__main__.py
windpilot/agent.py
windpilot/api.py
windpilot/common.py
windpilot/dashboard_data.py
windpilot/data.py
windpilot/diagnostics.py
windpilot/export_dashboard.py
windpilot/history_view.py
windpilot/live.py
windpilot/map_view.py
windpilot/model.py
windpilot/predict_checks.py
windpilot/scheduler.py
windpilot/weather.py
windpilot/weather_overview.py

Обсуждение 0 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.