О проекте
Команда: Kar1na
Кейс HackAlem.ai: Энергетика — Самрук-Казына
Стадия: Доведённый продукт
Задача кейса: AI-агент, прогнозирующий выработку ветровой электростанции по погодным данным
Суть
Веб-приложение для почасового прогноза нормализованной мощности двух ветротурбин на 24 или 48 часов. В нём есть интервалы неопределённости, архив SCADA, интерактивная 3D-модель ветропарка и ИИ-агент, который объясняет прогноз и риски.
Как устроено
Сырые данные SCADA по турбинам агрегируются до часового ряда и объединяются с архивом погоды (кэш JSON) или с живым прогнозом погодного API. Для каждой турбины обучена своя модель (joblib), её проверяли бэктестом на январском holdout. FastAPI отдаёт прогноз с верхней и нижней границей в режимах Replay и Live, а также экспорт в CSV. Агент OpenAI вызывает реальные инструменты прогноза; без ключа выполняется детерминированный резервный расчёт. 3D-модель собрана в Blender и показывается через Three.js.
Ключевые решения
- почасовой прогноз мощности
- prediction intervals
- backtesting / holdout
- OpenAI tool calling
- deterministic fallback agent
- outage evaluation
Особенности
README прямо описывает ограничения: мощность нормализована, фактическая SCADA заканчивается 31.01.2026, метрики относятся только к январскому holdout. Интерфейс на трёх языках (RU/EN/KZ). 3D-модель турбины можно разобрать на узлы, и агент получает контекст выбранного узла. Для проверки добавлены make verify и SHA-256 артефактов.
Стек
Python · FastAPI · joblib · Node.js · Vite · Three.js · Blender · Docker · GitHub Actions · Makefile
Модели
gpt-4.1-mini
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-b0f17a1f-kar1na.
README
README.mdAlemWind — Agentic AI для прогнозирования ВЭС
Обзор проекта
AlemWind (WindAI) — веб-приложение для почасового прогнозирования мощности двух ветряных турбин на 24 или 48 часов. Оно объединяет прогнозы машинного обучения, архивную телеметрию SCADA, интерактивную 3D-модель ветропарка и ИИ-агента, который помогает объяснить результаты.
Проект позволяет выбрать турбину, посмотреть ожидаемую мощность и погодные условия, сравнить исторические наблюдения, изучить устройство турбины и скачать прогноз в CSV. Backend на FastAPI рассчитывает прогнозы и после сборки обслуживает веб-интерфейс; отдельный сервер для сайта не нужен.
Важно для чтения результатов: мощность нормализована от 0 до 1, это не кВт и не МВт·ч. Фактическая телеметрия заканчивается 31 января 2026 года. Режим Replay показывает воспроизводимый прогноз на основе архива, а Live использует текущий прогноз погоды, но не добавляет свежую SCADA. Измеренное качество модели относится к январскому holdout; фактических февральских значений для оценки нет.
Демонстрация проекта
Видео презентация приложения
https://youtu.be/KMi2fnEZ8cA
Смотреть или скачать видео демонстрации (MP4) — запись работы приложения. Нажмите на изображение или ссылку, чтобы открыть видео. Если просмотрщик репозитория не воспроизводит файл, скачайте его и откройте локально.
Скриншоты интерфейса
Главная страница. Представление проекта и переход к демонстрации.

3D-турбина и ИИ-агент. Архивные показатели SCADA, осмотр узлов и контекстное объяснение выбранной турбины показаны на обложке видео выше.
Заключительный экран лендинга. Переход к приложению и навигация по проекту.

Пример экспорта CSV
Скачать пример прогноза — Turbine 01, 24 часа (CSV)
Файл содержит 24 почасовых значения на 1 февраля 2026 года по времени Астаны: время UTC и UTC+05:00, ветер, температуру, прогноз мощности, нижнюю и верхнюю границы прогнозного интервала, начало прогноза, идентификаторы турбины и запуска, единицу измерения и источник погоды. Мощность нормализована в диапазоне 0–1.

Если Excel показывает строку целиком в одном столбце, импортируйте файл через Данные → Из текста/CSV и выберите разделитель запятая.
Руководство по запуску и использованию
1. Подготовьте окружение
Для запуска нужны Python 3.11, Node.js 22 с npm и make — эти версии Python и Node.js используются в конфигурации Docker и CI. Команды ниже рассчитаны на macOS/Linux или WSL и выполняются из корня репозитория. Готовые модели, исходные данные и архив погоды уже включены, поэтому переобучать модель перед первым запуском не нужно.
Создайте локальный файл настроек, если его ещё нет:
test -f .env || cp .env.example .env
Куда вставить API-ключ при запуске с локального ноутбука
Откройте файл .env в корне проекта — в той же папке, где находятся README.md и Makefile. Найдите строку OPENAI_API_KEY= и вставьте свой ключ сразу после знака =:
OPENAI_API_KEY=ваш_ключ_OpenAI
OPENAI_MODEL=gpt-4.1-mini
Замените ваш_ключ_OpenAI на настоящий ключ, сохраните файл и выполните команды запуска из шага 2 ниже. Если сервер уже работает, остановите его сочетанием Ctrl+C и снова выполните make serve, чтобы он прочитал настройки.
Ключ нужно вставлять именно в корневой .env, а не в .env.example, web/.env или файлы frontend. Backend автоматически читает этот файл при запуске; отдельно передавать ключ в команду запуска не нужно. .env исключён из Git — не публикуйте его и не добавляйте ключ в README.
Проверить, что backend увидел ключ, можно после запуска по адресу http://127.0.0.1:8000/api/health: поле openai_configured должно быть true. Это подтверждает наличие ключа в настройках; для проверки его работоспособности отправьте вопрос ИИ-агенту в интерфейсе.
Для просмотра графиков, 3D-модели и численного прогноза ключи не нужны. OPENAI_API_KEY нужен для языкового ИИ-агента; его запросы используют платный API.
Что сможет проверить организатор без ключа
При скачивании репозитория ваш локальный .env не передаётся. Без OPENAI_API_KEY доступны Replay-прогнозы, графики, метрики, 3D, экспорт CSV и численный пересчёт. Кнопка запуска агента выполнит резервный расчёт реальными инструментами и покажет сводку с пометкой о недоступности ИИ; панель 3D также покажет сводку данных. Это не полноценный запуск языковой модели: свободные вопросы и выбор инструментов через OpenAI требуют ключа.
Для полной проверки организатор может указать свой ключ в .env. Альтернатива — предоставить ссылку на развёрнутый сайт, где ключ настроен на backend: посетителю свой ключ не нужен, запросы оплачиваются владельцем серверного ключа. Не добавляйте ключ в репозиторий или frontend.
2. Установите зависимости и запустите сайт
make install
make build
make serve
make install создаёт Python-окружение .venv и устанавливает зависимости backend и frontend. make build собирает сайт в web/dist, а make serve запускает приложение на порту 8000. Сборку нужно выполнить до запуска сервера, чтобы FastAPI подключил веб-интерфейс.
Откройте http://127.0.0.1:8000/ и нажмите Launch Demo либо сразу перейдите к Overview. Оставьте терминал работающим; для остановки нажмите Ctrl+C. При следующих запусках достаточно make serve; после изменений frontend повторите make build перед запуском.
Если make не установлен, выполните те же шаги вручную:
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
npm ci --prefix web
npm run build --prefix web
.venv/bin/python -m uvicorn src.api.main:app --host 127.0.0.1 --port 8000
3. Посмотрите первый прогноз
Названия элементов ниже приведены для английского интерфейса; язык можно переключить в шапке на RU, EN или KZ.
- В разделе Overview выберите Turbine 01 или Turbine 02.
- Для первого знакомства оставьте режим Replay · February 2026: он использует архив и по умолчанию начинает прогноз с 1 февраля 2026 года. Для прогноза от текущего момента выберите Live weather forecast — потребуется доступ к погодному API через интернет.
- Выберите горизонт 24h или 48h. Посмотрите среднюю и пиковую мощность, время пика и график прогноза с интервалом неопределённости.
- Передвигайте ползунок времени, чтобы изучить прогноз мощности, ветра и температуры для отдельного часа. Время в интерфейсе отображается по Астане, UTC+05:00.
- Перейдите в Analytics, чтобы посмотреть графики, исторические ряды мощности, ветра и температуры, а также метрики проверки модели. Карточки SCADA показывают последние архивные измерения.
- Нажмите Export CSV, чтобы скачать прогноз для выбранной турбины, режима и горизонта. Кнопка Refresh forecast повторно загружает данные, а Recalculate forecast в разделе AI Agent запускает пересчёт.
4. Изучите 3D-модель и задайте вопрос агенту
В Overview используйте кнопки Generator, Gearbox, Shaft и Rotor для осмотра узлов. Ползунок Disassembly раскрывает модель, а Reset inspection сбрасывает осмотр. Вращение ротора иллюстрирует прогноз ветра, а не измеренные обороты.
Справа от модели находится контекстный ИИ-агент: выбор узла обновляет контекст пояснения. Можно запросить прогноз, оценку рисков или задать свой вопрос. Температуры генератора, вибрации и показателей состояния узлов в исходной SCADA нет, поэтому агент не может подтвердить их техническое состояние.
Для подробного запроса откройте AI Agent, введите, например, «Объясни прогноз для выбранной турбины и укажи основные риски» и нажмите «Запустить ИИ-агента». Агент использует выбранную турбину, горизонт и режим; вызовы инструментов доступны в блоке «Вызовы инструментов и результаты». Для языковых ответов нужен настроенный OPENAI_API_KEY; численный пересчёт работает без него.
5. Проверьте запуск или устраните проблему
- Сайт не открывается: убедитесь, что
make serveпродолжает работать, и проверьте состояние API. - API работает, но сайт не появился: остановите сервер, выполните
make buildи сноваmake serve. - Прогноз недоступен: прочитайте сообщение в интерфейсе и терминале. Для Live проверьте интернет; для демонстрации переключитесь на Replay и нажмите Refresh forecast.
- ИИ-агент не отвечает: проверьте настройку
OPENAI_API_KEYв.envи перезапустите сервер. - Нужна документация API: откройте Swagger UI. Подробности разработки frontend находятся в web/README.md.
Проверки численного прогноза без OpenAI:
make test
make verify
Полное повторное обучение и replay из локального архива: make reproduce. Проверка без свежей SCADA без переобучения и сетевых запросов: make check-scada. Командный ИИ-агент: make agent (требует локального API-ключа).
Дополнительные способы запуска и API
Публикация сайта: пошаговый деплой backend на Render и frontend на Vercel.
- Сценарий защиты и соответствие критериям
- Проверяемые результаты и SHA-256 артефактов
- Интерактивная схема API
Дополнительные маршруты:
| Метод | Маршрут | Назначение |
|---|---|---|
| POST | /api/agent/run | OpenAI → реальные инструменты → прогноз и объяснение |
| POST | /api/agent/inspect | Пояснение выбранной турбины или её узла по фактическому контексту |
| POST | /api/agent/check-updates | Проверка обновлений двух турбин без LLM |
| GET | /api/agent/status | Этапы прогнозирования и состояние монитора |
| GET | /api/export/turbine_1?hours=48&mode=replay | CSV: UTC, время Астаны, интервалы и происхождение |
POST /api/agent/run принимает turbine_id, hours, mode, необязательный forecast_origin
со смещением и message до 1500 символов. Ключ никогда не принимается от браузера и не возвращается в API.
Локальные журналы находятся в игнорируемых results/agent_runs, results/forecasts, results/monitor.
Docker-альтернатива (ключ передаётся при запуске, не во время сборки):
docker build -t windai .
docker run --rm -p 127.0.0.1:8000:8000 --env-file .env windai
Локальное приложение предназначено для доверенного пользователя. Для публичного сервера потребуются аутентификация, ограничение частоты запросов и постоянное хранилище. Dockerfile и CI добавлены; фактическую проверку Docker нужно проводить при работающем Docker daemon.
Problem
Диспетчеру нужен почасовой прогноз выработки каждой турбины на следующие сутки/двое. В реальной работе будущая фактическая погода неизвестна. Решение должно использовать доступные на момент расчёта метеопрогнозы, учитывать недоступность телеметрии и давать проверяемый результат.
Мощность в CSV нормализована в диапазоне [0, 1]. Это не кВт и не МВт·ч. Номинальная мощность и высота ступицы не предоставлены; rated_power_kw и hub_height_m возвращаются как null.
Solution
- Реальные CSV → аудит → почасовые средние с контролем покрытия.
- Архив операционных прогнозов GFS Open-Meteo Previous Runs → прогноз погоды на каждый целевой час.
- Отдельная HistGradientBoosting-модель для каждой турбины → прямой прогноз всех 48 часов, без рекурсивной подстановки будущих actuals.
- Агент получает конфигурацию и погоду, проверяет данные, запускает модель, проверяет результат, сохраняет JSON и состояние.
- FastAPI отдаёт прогнозы, неопределённость, последние известные наблюдения, метрики и этапы выполнения.
По умолчанию API работает в replay на 01.02.2026. Для реального текущего прогноза используйте ?mode=live или FORECAST_MODE=live. Ответ всегда содержит mode, forecast_origin и источник погоды.
Architecture
Weather API (GFS archive / live)
|
v
Weather Agent (retry, cache, explicit fallback)
|
v
Data Processor (UTC, coverage, origin-only history)
|
v
Forecast Model (direct multi-horizon HistGradientBoosting)
|
v
Validation Agent (bounds, NaN, timestamps, ramps)
|
v
FastAPI (JSON + agent status)
|
v
3D Dashboard + OpenAI operator interface
Численный цикл реализован в ForecastAgent. Над ним работает Copilot: OpenAI Responses API выбирает реальные инструменты проверки данных, расчёта, оценки рисков и сравнения результатов. Модель мощности работает без ключа; ключ нужен для языкового агента.
src/
config.py # координаты, timezone, пути
utils.py # JSON без NaN, атомарная запись
data/
loader.py # проверка схемы и фактического CSV
preprocessing.py # 10-minute → hourly, audit
features.py # календарь, лаги, rolling, horizon
models/
train.py # chronological train/calibration, joblib
predict.py # проверка cutoff, prediction intervals
evaluate.py # MAE, RMSE, R², coverage
backtest.py # daily rolling origins
services/weather_provider.py
agents/forecast_agent.py
api/main.py
api/schemas.py
scripts/
analyze_data.py
fetch_weather.py
train_models.py
run_backtest.py
report_results.py
run_pipeline.py
smoke_api.py
models/ # deployment + evaluation joblib для каждой турбины
results/ # метрики, прогнозы, EDA, примеры JSON
eda/
data/
raw/ # точные копии исходных CSV
processed/ # часовые ряды
weather/ # реальные ответы Open-Meteo и URL/время загрузки
tests/ # тесты pipeline, leakage и API
Dataset
Копии оригинальных CSV находятся в data/raw/turbine_1.csv и data/raw/turbine_2.csv. Исходные файлы в Downloads не изменялись. SHA-256, полный audit и статистики сохранены в results/eda/report.json.
Формат проверен на содержимом файлов: UTF-8 без BOM, разделитель запятая, переводы строк CRLF. Колонки:
| Исходная колонка | Тип / использование |
|---|---|
ID | integer, идентификатор; не признак |
Статистическое время | timestamp,%Y-%m-%d %H:%M:%S |
Средняя скорость ветра(m/s) | float →wind_speed, м/с |
Нормализованная активная мощность | float →power, target |
Средняя температура окружающей среды(°C) | float →temperature, °C |
Время проекта — Астана, UTC+05:00. Внутри pipeline и в транспортных timestamp — aware UTC. Суточные границы, CSV-экспорт и календарные признаки используют UTC+05:00; OpenAI получает уже переведённые локальные даты. Для даты прогноза 2026 года IANA-зона — Asia/Almaty. Исторические исходные CSV без смещения интерпретируются как фиксированный UTC+05 для совместимости с предоставленным рядом и сохранёнными моделями. Историческую смену официального часового пояса нельзя автоматически применить к SCADA без подтверждения формата выгрузки; при иной трактовке нужно заново подготовить данные и переобучить модели.
| Показатель | Turbine 1 | Turbine 2 |
|---|---|---|
| Исходных строк | 142 360 | 149 499 |
| Начало, локальное время | 2023-03-11 00:00 | 2023-03-11 00:00 |
| Конец, локальное время | 2026-01-31 23:50 | 2026-01-31 23:50 |
| Явных null / duplicate timestamps | 0 / 0 | 0 / 0 |
| Пропущенных 10-минутных timestamps | 9 992 | 2 853 |
| Часов в регулярной сетке | 25 392 | 25 392 |
| Часов без допустимого target | 1 664 | 473 |
| Скорость ветра, min…max, м/с | 0…22,97 | 0,11…21,43 |
| Нормализованная мощность | 0…1 | 0…1 |
| Температура, min…max, °C | −19,26…43,48 | −19,08…43,97 |
| Максимальный интервал между записями, ч | 999 | 57,5 |
Координаты извлечены из Google Maps redirect ссылок в PDF кейса:
- Turbine 1: 43.645150, 78.535604 — https://maps.app.goo.gl/iN6svMt69D5qRpFU9
- Turbine 2: 43.643198, 78.538828 — https://maps.app.goo.gl/8UQMwsYavY6nLvFY8
Data preprocessing
- Проверка encoding, separator, обязательных колонок и числовых преобразований.
- Строгий timestamp parse → фиксированный UTC+05 → UTC → сортировка.
- Проверка шага и сетки 10 минут. Если появятся дубликаты, измерения одного timestamp усредняются до агрегации, чтобы не завышать покрытие часа.
- Невозможные значения заменяются на missing с подсчётом в audit: power вне [0,1], wind вне [0,75] м/с, temperature вне [−80,60] °C. В предоставленных данных таких значений не найдено.
- Почасовая арифметическая средняя по равным 10-минутным интервалам. Час требует минимум 4 из 6 измерений для каждой переменной.
*_samplesсохраняют фактическое покрытие. - Недостаточно покрытые часы остаются missing. Target не интерполируется, не forward-fill и не backfill. Неизвестный target исключается из обучения/метрик, а не превращается в ноль.
- Низкая мощность при сильном ветре сохраняется: возможны остановы, ограничения или неисправность. Причина без SCADA-флагов неизвестна.
Timestamp часа — начало интервала [t, t+1h). Его средняя считается доступной только на t+1h. Дополнительная задержка SCADA в MVP не моделируется.
EDA для жюри: results/eda/report.md, распределения target/ветра/температуры, power curves, корреляции, сравнение турбин. Месячные средние с покрытием ниже 80% скрываются на графике сравнения, а покрытие показано отдельно.
Feature engineering
Прямой прогноз: одна строка признаков = (forecast_origin, target_timestamp, horizon).
- Календарь целевого часа:
hour,day_of_week,month,day_of_year. - Циклические пары sin/cos для hour, month, day_of_year.
- Прогнозные, а не фактические будущие
wind_speed,temperature. power_lag_1/3/6/12/24,wind_lag_1/3/6/24относительно origin.- Rolling mean/std по wind и power за 3/6/12/24 часа перед origin. Требуется минимум половина окна и не менее двух наблюдений.
horizon= 1…48.
Для горизонта 48 lag_1 всё ещё означает последний завершённый час до origin, а не фактическую мощность на 47-м часе будущего. Все 48 значений рассчитываются напрямую. Отсутствующие лаги обрабатывает HistGradientBoosting. Для устойчивости к пропавшей телеметрии добавляются копии каждой четвёртой training-строки с masked history features; targets и weather не синтезируются.
Model
Две отдельные HistGradientBoostingRegressor: max_iter=180, max_leaf_nodes=15, learning_rate=0.06, l2_regularization=8, min_samples_leaf=40, random_state=42. Random early stopping отключён. Достаточно CPU; XGBoost/LightGBM не требуются.
Данные показывают разные объёмы пропусков, остановы и небольшие различия power curves. Раздельные модели позволяют учесть их и независимо сохранять/калибровать турбины. Утверждения, что этот вариант лучше общей модели, без эксперимента нет.
Модель обучается на архивных прогнозах погоды с января 2024; 2023 используется в EDA и остаётся доступен в истории, но не подменяется фактической погодой для training. Строки без archived forecast исключаются явно. Число использованных строк: results/model_metadata.json.
Два набора артефактов:
models/turbine_*_evaluation.joblib: веса обучены до 01.12.2025, декабрь — только калибровка интервалов; январь — holdout.models/turbine_*.joblib: после оценки веса переобучены на данных до 01.02.2026 для февраля/live. Январские метрики относятся к evaluation-модели, не к этому refit.
Интервалы lower_power, upper_power используют декабрьские квантили абсолютной ошибки отдельно для lead 1–24 и 25–48. Номинальное покрытие 90%; это эмпирические интервалы, не гарантия 90% при временной зависимости или сдвиге данных. Радиусы перенесены на deployment refit; его покрытие ещё не проверено на новых actuals.
Baseline
Persistence повторяет последнее фактически известное значение мощности перед origin на весь горизонт. Никакие будущие actuals baseline не получает. Для февраля сохраняется history_age_hours, поскольку новых наблюдений нет. MAE, RMSE и R² считаются на том же наборе origin-target пар, что и ML. Normalized MAE совпадает с MAE, поскольку диапазон мощности равен единице.
Backtesting methodology
Январь: origin ежедневно в 00:00 UTC+05:00, прогноз первых 48 часов начиная с origin. Это граница закрытия предыдущего дня: выпуск для 1 февраля соответствует закрытию 31 января. При origin 2026-02-01T00:00:00+05:00 первый target имеет UTC timestamp 2026-01-31T19:00:00Z и horizon=1.
Каждый origin использует только завершённые исторические часы. Веса в течение оцениваемого месяца фиксированы: это rolling-origin backtest с обновлением доступной истории, без ежедневного retrain. January holdout: 1–31 января; 744 уникальных target-часа и 1 464 оцениваемые origin-target пары на турбину. Перекрывающиеся горизонты учитываются отдельно. Предсказания за границей оцениваемого месяца сохраняются, но не включаются в метрики.
Февраль: 28 origin × 48 часов × 2 турбины = 2 688 строк results/backtest_predictions.csv. 48 строк относятся к target-часам 1 марта, вне февральского scoring window. Остальные 2 640 также не имеют фактических меток, потому что February SCADA не предоставлена. Значения actual_power и error пустые; статус — unscored_missing_actuals. После первого дня missing history остаётся missing, прогнозная мощность не выдаётся за наблюдение.
Защита от data leakage
- Никаких random train/test split. Train до декабря, calibration в декабре, test в январе.
- Training rows с target за cutoff удаляются, включая конец 48-часового горизонта. Пересечения target между train/calibration/test нет.
history.index < originдо формирования lag/rolling. Среднее текущего незавершённого часа использовать нельзя.- Никакой интерполяции назад, full-dataset scaling или mean imputation по test.
- В training и backtest weather — archived forecast, не future SCADA/reanalysis.
- Predictor отвергает artifact, чьи training или calibration cutoffs позже origin.
- Тест изменяет/добавляет будущую фактическую мощность и погоду на невозможные значения и проверяет, что features и prediction не меняются.
- Production refit после января никогда не используется для январских метрик.
Источник и доступность погоды
services/weather_provider.py реализует единый контракт get_forecast(latitude, longitude, forecast_origin, horizon_hours).
В backtest применяется Open-Meteo Previous Runs API, models=gfs_global, wind_speed_80m_previous_day3, temperature_2m_previous_day3, wind_speed_unit=ms, timezone=UTC. Данные получены реальными HTTP-запросами, закэшированы по месяцу/координатам с URL и retrieved_at.
previous_day3 — прогноз за 72 часа до target согласно документации провайдера. Для target от origin до origin+47h последнее референсное время не позднее origin−25h. Добавляем консервативный запас 12 часов на публикацию: target−72h+12h <= origin. Это намеренно более старый прогноз, чем самый свежий доступный запуск.
Ограничение provenance: API fixed-lead не возвращает точный run ID и фактический журнал публикации. Сохранена консервативная граница доступности по документированной семантике; точные исторические publication timestamps независимо не доказаны. Это не reanalysis и не seamless historical observations.
Исследован и Single Runs API. Его архив большинства моделей начинается после февраля 2026, а ранний ECMWF описан как hindcasts. Поэтому февральский результат не основан на таком hindcast. Для production нужен архив отдельных операционных запусков с issue/publication timestamps.
Источники:
- Previous Runs API
- Single Runs API и ограничения архивов
- Live Forecast API
- Open-Meteo attribution/licence, weather model: NOAA GFS, data delivery: Open-Meteo.
Live-режим получает текущий GFS forecast с теми же переменными и единицами, кэширует его на 30 минут. Архивный кэш не обновляется автоматически, чтобы повторные запуски были воспроизводимыми. Кэш live не делает его архивом для произвольных прошлых origin.
Agentic AI architecture
src/agents/forecast_agent.py — детерминированный domain agent. После запроса цели «турбина + 24/48 часов» он сам вызывает инструменты и принимает решения по состоянию данных:
- Загружает конфигурацию и выбирает replay/live provider.
- Получает погоду с максимум тремя попытками и cache.
- При недоступности NWP может выбрать явно помеченный persistence weather fallback; он разрешён только при наблюдениях не старше 24 часов. Иначе возвращается 503.
- Проверяет timestamp coverage, физические пределы и свежесть истории; missing telemetry ведёт к weather/calendar-only inference, а не к выдуманным наблюдениям.
- Создаёт features, загружает модель, проверяет training cutoff.
- Прогнозирует, отвергает NaN/Inf, ограничивает нормализованную мощность [0,1], логирует коррекции и jumps >0.6. Jumps отмечаются, но не сглаживаются произвольно.
- Проверяет response schema, сохраняет результат атомарно и возвращает JSON.
- По POST с обновлённой погодой повторяет расчёт; SHA-256 входной погоды и
run_idпозволяют отличить версии.
Состояния: IDLE → FETCHING_WEATHER → VALIDATING_DATA → PREPARING_FEATURES → RUNNING_MODEL → VALIDATING_FORECAST → COMPLETED; при ошибке — FAILED. Каждый шаг имеет timestamp и сообщение. GET /api/agent/status можно опрашивать из frontend во время расчёта; sync handlers FastAPI выполняются в thread pool, status-запрос не ждёт завершения прогноза. Для одной турбины конкурентный расчёт получает 409.
OpenAI-агент в src/agents/copilot.py вызывает инструменты через Responses API, ограничен 7 обращениями и 10 вызовами tools. Численные результаты, временные ограничения и область действия устанавливает сервер. При сбое API возвращается явный deterministic_recovery, а не ложное подтверждение работы LLM.
ForecastMonitor внутри lifecycle FastAPI проверяет обе турбины, если AGENT_MONITOR_ENABLED=true. Это значение включено в .env.example и Docker; без настройки монитор выключен. Интервал задаёт AGENT_MONITOR_INTERVAL_SECONDS (по умолчанию 1800 секунд, минимум 60); первая проверка происходит после этого интервала. Режим задаёт FORECAST_MODE: в replay монитор использует фиксированный origin, для текущей погоды нужен live. SHA-256 погоды, последних 24 часов истории, модели и параметров задаёт версию результата. Неизменные входы не создают новую опубликованную версию. Изменённые входы дают новую версию с отличиями по совпадающим целевым часам. Live cache истекает через 30 минут; архивный cache остаётся неизменным для воспроизводимости. Монитор не вызывает OpenAI и не расходует LLM-токены. Он перечитывает подготовленные hourly-файлы, но не получает новую SCADA из внешней системы и не запускает её подготовку. Сервис рассчитан на один uvicorn worker, пока процесс запущен; JSON сохраняются на диске.
API
Swagger UI: http://127.0.0.1:8000/docs. Схема: /openapi.json.
| Метод | Endpoint | Назначение |
|---|---|---|
| GET | /api/health | liveness иready для моделей/processed data |
| GET | /api/turbines | конфигурации двух турбин |
| GET | /api/turbines/{id} | одна конфигурация |
| GET | /api/forecast/{id}?hours=48 | прогноз 24/48h |
| GET | /api/forecast/all?hours=48 | прогнозы обеих турбин |
| GET | /api/turbines/{id}/details?hours=48 | полный JSON для клика по 3D-турбине |
| GET | /api/backtest/metrics | февральский summary, включая null metrics |
| GET | /api/backtest/{id}?limit=200&offset=0 | пагинация прогнозов февраля |
| GET | /api/validation/metrics | реальные январские метрики |
| GET | /api/agent/status | состояние и шаги обеих турбин |
| POST | /api/forecast/recalculate | повторный расчёт, опционально новая погода |
id: turbine_1 или turbine_2. Query mode=replay|live доступен на forecast/details. Неизвестный id → 404, неверный horizon/тип → 422, конфликт выполнения → 409, отсутствующий artifact/недоступная погода → 503. Ошибки с custom forecast, обнаруженные weather validation, также возвращают 503; Pydantic-ошибки тела запроса — 422.
details.current означает latest known SCADA, не текущий live sensor. Содержит timestamp, is_live=false, age_hours. В details.model приведены январские метрики и явно назван evaluation artifact. Не выдавайте их пользователю как измеренное качество текущего live-прогноза.
forecast_summary.peak_time относится ко всему запрошенному горизонту; next_24h_average и next_24h_peak — только к первым 24 часам. Все JSON numbers конечны; missing результаты передаются как null.
Полный пример фронтенд-интеграции: docs/frontend.md. Реальные примеры ответов после smoke test: results/example_replay_turbine_1.json, results/example_live_turbine_1.json (содержат фактическое время проверки, не обновляются сами).
Installation
Выполняйте команды из корня репозитория. Версии Docker/CI и фактически проверенного локального окружения указаны в быстром запуске; наличие CI-конфигурации не означает подтверждённого запуска CI или Docker.
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
test -f .env || cp .env.example .env
Для численного прогноза секреты не требуются. Для OpenAI укажите OPENAI_API_KEY в локальном .env; .env исключён из Git и Docker build context. Не перезаписывайте существующий .env командой копирования. Оригинальные данные, модели, processed данные и weather cache включены в проект для воспроизводимого запуска. Если их убрали из своей копии, верните CSV с исходной русской схемой в data/raw/turbine_1.csv и data/raw/turbine_2.csv.
Running
Полный pipeline: EDA → обучение → January validation → February replay → графики → tests:
source .venv/bin/activate
python scripts/run_pipeline.py
С сохранённым weather cache полный расчёт не требует сети:
WEATHER_OFFLINE=true python scripts/run_pipeline.py
Отдельные команды:
python scripts/analyze_data.py
python scripts/fetch_weather.py --start 2024-01-01 --end 2026-03-03
python scripts/train_models.py
python scripts/run_backtest.py
python scripts/report_results.py
python -m pytest -q
fetch_weather.py необязателен: training/backtest сами получат отсутствующие cached месяцы. API start не запускает обучение скрыто.
Запуск backend:
uvicorn src.api.main:app --host 127.0.0.1 --port 8000 --reload
В другом терминале:
source .venv/bin/activate
curl http://127.0.0.1:8000/api/health
curl http://127.0.0.1:8000/api/turbines
curl 'http://127.0.0.1:8000/api/forecast/turbine_1?hours=48'
curl 'http://127.0.0.1:8000/api/forecast/turbine_2?hours=24'
curl 'http://127.0.0.1:8000/api/turbines/turbine_1/details?hours=48'
python scripts/smoke_api.py --live
Текущая погода и прогноз:
curl 'http://127.0.0.1:8000/api/forecast/turbine_1?hours=48&mode=live'
Пересчёт стандартной погоды:
curl -X POST http://127.0.0.1:8000/api/forecast/recalculate \
-H 'Content-Type: application/json' \
-d '{"turbine_id":"turbine_1","hours":48,"mode":"replay"}'
Пользовательскую новую погоду можно передать массивом weather (24/48 строк с aware timestamp, wind_speed, temperature), weather_issued_at и forecast_origin. Issue time обязан быть не позже origin. Это заявление вызывающей стороны; подлинность произвольного пользовательского прогноза независимо не проверяется.
CORS по умолчанию: localhost:3000, localhost:5173, 127.0.0.1:5173. Настройка — CORS_ORIGINS в .env.
Results
Фактический независимый период: январь 2026. Веса обучены до декабря, интервалы откалиброваны на декабре. Горизонт 1–48h, одинаковые 1 464 пары на турбину:
| Turbine | Baseline MAE | Model MAE | RMSE | R² |
|---|---|---|---|---|
| Turbine 1 | 0.335164 | 0.246388 | 0.309170 | 0.156847 |
| Turbine 2 | 0.332802 | 0.255451 | 0.320662 | 0.094980 |
Снижение MAE относительно persistence: 26,49% и 23,24%. Это улучшение baseline, но абсолютная ошибка остаётся значительной; результат не следует трактовать как промышленную точность.
Январская проверка без обновления SCADA
История заморожена на 01.01.2026 00:00 UTC+05:00. Январские измерения используются только для оценки, а модель получает наблюдения строго до этой границы. Первый запуск имеет декабрьскую историю; со 2 января все lag/rolling признаки отсутствуют. Использованы те же evaluation-модели, архивная погода и 1 464 оцениваемые пары на турбину. Переобучения и перекалибровки интервалов нет. Контрольный прогноз со свежей историей воспроизведён с допуском 1e-12.
| Турбина | MAE со свежей SCADA | MAE без обновлений | Изменение MAE | RMSE без обновлений | R² без обновлений | Покрытие интервалов |
|---|---|---|---|---|---|---|
| Turbine 1 | 0.246388 | 0.252976 | +2.67% | 0.320405 | 0.094450 | 86.41% |
| Turbine 2 | 0.255451 | 0.265397 | +3.89% | 0.332941 | 0.024345 | 87.23% |
В этой симуляции отсутствие свежей истории увеличило MAE на 2.67–3.89%. Абсолютная точность остаётся ограниченной, а средняя ширина интервалов составляет 0.753 и 0.775 при шкале мощности 0–1. Это проверка одного январского сценария, не измеренное февральское или live-качество. Покрытие интервалов deployment refit по-прежнему не проверено.
Повторить: make check-scada. Методика и результаты, метрики по горизонтам и baseline, построчные прогнозы. Baseline без обновлений фиксирует последнюю мощность декабря; исходный январский baseline ежедневно получает свежие наблюдения. Исходные validation/backtest артефакты сохраняются отдельно.
Файлы с реальными результатами:
- results/RESULTS.md: summary и наблюдаемое покрытие prediction intervals.
results/metrics.json,results/validation_metrics.json: metrics overall / 1–24h / 25–48h / каждый lead.results/validation_predictions.csv: сравнение с настоящими January actuals.results/backtest_predictions.csv: February forecasts,actual_power/errorпустые.results/backtest_metrics.json:unscored_missing_actuals, n=0, metrics=null.results/validation_forecasts.png: actual/model/baseline и интервалы.results/api_smoke_checks.json: фактические HTTP-проверки.
Tests
python -m pytest -q
Тесты используют реальные CSV, модели и cached погодные ответы, без сети. Проверяются CSV/schema, почасовое покрытие и anomalies, lag/rolling, будущие actuals, purge на cutoff, stale history, временная доступность прогнозов, полный horizon, finite/bounds, prediction schema, state/failure/lock, пересчёт при новой погоде, FastAPI/CORS, параметры и отсутствие выдуманных February actuals.
Для настоящего HTTP-процесса отдельно запустите uvicorn и python scripts/smoke_api.py --live. Это проверяет и текущий внешний weather API; если он недоступен, smoke test честно завершится ошибкой, а не засчитает fallback как live.
Limitations
- February SCADA отсутствует. Февральское качество и полноценное ежедневное обновление телеметрии проверить нельзя. Добавление новых данных должно сохранять evaluation cutoffs; не переобучайте модель на февральских labels перед February replay.
- Fixed-lead weather archive даёт документированную границу доступности, не exact publication audit. Используется заведомо старый 72h прогноз; оптимальный свежий NWP run пока не выбирается.
- Неизвестны hub height и rated power. GFS wind 80m — внешняя метеопеременная, не измеренная скорость на роторе. GFS grid coarse; две близкие турбины могут получить один grid cell. Это ограничивает качество.
- Live forecasts имеют другое распределение lead-time, чем training; свежих SCADA observations после января нет. Live работает с missing-history режимом; его качество и интервалы не валидированы.
- Prediction intervals приближённые. Refit, fallback, отсутствие истории и shift могут изменить покрытие.
- Не моделируются curtailment, availability/fault flags, направление ветра, wake effects и задержки доставки SCADA. Частично покрытые часы (4/6+) могут давать смещение в target.
- Численный ForecastAgent детерминирован; Copilot использует LLM и реальные инструменты. Фоновый монитор работает внутри процесса API. Нет распределённой очереди, базы состояний, auth и production observability. Нагрузочные и multi-worker проверки не выполнялись.
- 3D frontend интегрирован, Dockerfile и CI-конфигурация включены. Облачная публикация и успешный запуск Docker/CI здесь не подтверждены. Внешнего потока свежей SCADA нет.
Future improvements
- Получить настоящие February actuals, SCADA availability и turbine metadata; повторно оценить frozen forecasts.
- Подключить архив конкретных operational NWP runs с publication times и обучить weather calibration на свежих lead-time.
- Добавить wind direction, NWP ensemble, availability/curtailment, измерения на hub height и probabilistic models.
- Проверить общую модель с turbine ID, сезонный walk-forward и несколько независимых test-периодов.
- Подключить live SCADA ingest, durable task queue и event stream для frontend; дополнить периодический монитор обнаружением конкретного нового NWP run.
Авторы коммитов
История коммитов
- 2026-09-23 17:49Update README with video presentation link and formatting𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 17:47Update README with API key instructions𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 17:09Update video section in README.md𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 17:00feat: add project demo, CSV, translations and deployment setup𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 16:35docs: Update README for improved project overview and setup instructions𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 16:35feat: Add animated turbine cursor and enhance dashboard interactivity𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 16:26Refactor code structure for improved readability and maintainability𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 16:13feat: Integrate charting functionality with SVG support and enhance dashboard styling𝓴𝓪𝓻𝓲𝓷𝓪 🤍
Все коммиты (46)
- 2026-09-23 16:06Add outage evaluation script and corresponding tests𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 15:52feat: Implement overview motion for responsive card entrance and enhance dashboard styling𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 15:48Update dashboard styles and HTML structure for improved layout and functionality𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 15:41feat: Enhance turbine assistant panel and context features𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 15:33feat: Add turbine insights context and inspection endpoint, enhance dashboard styling, and update blueprint rendering𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 15:29feat: Update time handling in agents and enhance validation in schemas𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 15:29feat: Implement Docker support and CI workflow for verification𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 15:21feat: Enhance landing page translations and styling𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 15:10feat: implement multilingual support for dashboard interface and enhance language selection𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 15:05feat: enhance dashboard aesthetics with improved background opacity and new soft center effect𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 15:00feat: enhance dashboard layout with new summary tiles and improved styling𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:58feat: integrate blueprint creation for turbine visualization and interaction𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:53feat: enhance 3D turbine model with improved lighting and environmental effects𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:46feat: add weathering effect for turbine materials to enhance visual realism𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:42feat: update dashboard layout and styles for improved visibility and responsiveness𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:39feat: add multilingual support with translations for landing page content𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:38feat: enhance dashboard layout with improved grid structure and responsive design adjustments𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:33feat: enhance dashboard layout with new top metrics section and improved styling for better visibility𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:32feat: enhance dashboard with new background assets and refined styles for improved visual appeal𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:27feat: update landing page with new logo and enhanced styles for better branding𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:23feat: add diamond fade effect to scroll journey for enhanced visual transition𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:22feat: refine scroll journey by removing percentage display and enhancing visual transitions𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:17feat: enhance scroll journey with spatial fades and popup animations𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:16feat: add scroll journey section with video integration and animations𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 14:11feat: update final call-to-action section with new design and footer assets𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 13:57Enhance landing page with new hero section and styles𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 13:47Refactor code structure for improved readability and maintainability𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 13:44Add initial WindAI website structure and assets𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 13:39feat: add verification.json for pipeline results and HTTP checks𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 13:33Add forecast data for turbines 1 and 2 with detailed weather and model information𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 13:30Add scripts for reporting results, running pipeline, and API smoke checks𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 13:28feat: enhance wind farm controls with disassembly features and UI updates𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 13:26Add comprehensive integration tests for forecasting pipeline𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 13:23feat: add ForecastAgent for deterministic weather forecasting and API integration𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 13:21Implement backtesting and model training scripts with evaluation metrics𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 13:21Add data analysis and weather fetching scripts𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 13:17Add initial project structure with configuration, data loading, and preprocessing scripts𝓴𝓪𝓻𝓲𝓷𝓪 🤍
- 2026-09-23 13:11Refactor code structure for improved readability and maintainability𝓴𝓪𝓻𝓲𝓷𝓪 🤍
Структура репозитория (255 файлов)
.dockerignore .env.example .github/workflows/verify.yml .gitignore .python-version 3d/.vite/deps/_metadata.json 3d/.vite/deps/chunk-DLGT4YEF.js 3d/.vite/deps/chunk-DLGT4YEF.js.map 3d/.vite/deps/package.json 3d/.vite/deps/three.js 3d/.vite/deps/three.js.map 3d/.vite/deps/three_addons_controls_OrbitControls__js.js 3d/.vite/deps/three_addons_controls_OrbitControls__js.js.map 3d/.vite/deps/three_addons_loaders_GLTFLoader__js.js 3d/.vite/deps/three_addons_loaders_GLTFLoader__js.js.map 3d/README_3D.md 3d/models/wind_farm.blend 3d/models/wind_farm.blend1 3d/models/wind_farm.glb 3d/references/drivetrain_diagram.png 3d/references/turbine_components.png 3d/references/wind_farm_photo.png 3d/renders/assembled.png 3d/renders/exploded.png 3d/renders/inspection.png 3d/reports/disassembly_validation.json 3d/reports/model_manifest.json 3d/reports/validation_report.json 3d/reports/web_validation.json 3d/scripts/build_wind_farm.py 3d/scripts/export_wind_farm.py 3d/scripts/turbine_details.py 3d/scripts/validate_disassembly.py 3d/scripts/validate_wind_farm.py 3d/web/.gitignore 3d/web/index.html 3d/web/main.mjs 3d/web/package-lock.json 3d/web/package.json 3d/web/test_controls.mjs 3d/web/vite.config.mjs 3d/web/wind_farm_controls.mjs Dockerfile Makefile README.md assets/1d056d30b95ecc8b8b17a0db3b525034.jpg assets/6e4284ac273cb0b05ad2a74a116cb92c.jpg assets/images (1).jpeg assets/images (2).jpeg assets/images (3).jpeg assets/images (4).jpeg assets/images.jpeg assets/Подключение репозитория к хакатону.html assets/Подключение репозитория к хакатону_files/11436.8549434e85.css assets/Подключение репозитория к хакатону_files/120833.5cde4c1ca9.css assets/Подключение репозитория к хакатону_files/136463.c28a1f0121.css assets/Подключение репозитория к хакатону_files/14340.878d82dc27.css assets/Подключение репозитория к хакатону_files/175788.05d57fa378.css assets/Подключение репозитория к хакатону_files/188164.55fa60f698.css assets/Подключение репозитория к хакатону_files/193615.ad5433ce8b.css assets/Подключение репозитория к хакатону_files/213699.8cf85f5599.css assets/Подключение репозитория к хакатону_files/233745.fed56cd892.css assets/Подключение репозитория к хакатону_files/341394.cdeca58eb1.css assets/Подключение репозитория к хакатону_files/551330.53a902d6f4.css assets/Подключение репозитория к хакатону_files/586918.5cde4c1ca9.css assets/Подключение репозитория к хакатону_files/618513.f17267a5ff.css assets/Подключение репозитория к хакатону_files/665460.d272920e47.css assets/Подключение репозитория к хакатону_files/80015.ada3a842c7.css assets/Подключение репозитория к хакатону_files/829048.9ffdd62fb4.css assets/Подключение репозитория к хакатону_files/861238.1578b23665.css assets/Подключение репозитория к хакатону_files/886701.fe58a31829.css assets/Подключение репозитория к хакатону_files/904586.5cde4c1ca9.css assets/Подключение репозитория к хакатону_files/944667.4755d9bf54.css assets/Подключение репозитория к хакатону_files/977882.4bead31f2e.css data/processed/turbine_1_hourly.csv data/processed/turbine_2_hourly.csv data/raw/turbine_1.csv data/raw/turbine_2.csv data/weather/03961ac3564e54882cb76d8d867ea8e17d40d2b51dff39cd1b0219aeecd9299c.json data/weather/06a66ab38883024a4eb4aa7e05743181902158d806104fda396544ccf47cdb51.json data/weather/06d40f383bbcd536c61bf50784a916e43156e3a20631ec16a76d323d3b60ce2a.json data/weather/07f89c801014f95d1d71be6a84eb5518352976cc079e6b9c365153ab24cf4f76.json data/weather/0c087a52e2f8552ae67290f50ce0d7fa4f3d0ac670b2275c1e8bf3ed93e9e96f.json data/weather/0c37d95c6b40e5ed73a82d29bcec4f109858f899ceb49d84e5b0ec0de2b7baf8.json data/weather/218f6322f3062dacd90bc134d666850c29090f5384725d534698a13e63dfbc36.json data/weather/23d558a558cb696409a4f90a6adc750443b515eb0fea3d8d4587948561a784c7.json data/weather/25beba36b451ab9cbf196f1904ac3696d3b0554b0d5f201c91b2dfa11eec1993.json data/weather/2c63849d6c25c5420955300d822a2fc348b9e29ba4ff11c1b94c1bbdd376c345.json data/weather/332b74d34e615f2738d6e311984f857898a3dfa92f178ee1842c9a345c4245ff.json data/weather/37b718e63b1686a607cb9bd78c555195316915fd02520fb9ec9b82a20b91b504.json data/weather/3b33dbbcb5ac39dee1752bfc1413c5ef73e323a2386779a3ca9dd9d8fe12fb53.json data/weather/42472d4acd1ab5e26b117a281cd9a1140b13c5f4e94801af3cf1283f8b24234b.json data/weather/45a0278f6fea6ed3ef25367af371b0b107c1aee692557260a5adda920e17eaf8.json data/weather/4e3c2279706993a65a3fb6f57c4a6c0f517008c2f9a80dbd798f1037e4f90415.json data/weather/52863b3b6d08cf6e97617f90990b59ba22dd40d0911b72642f3822794751cb48.json data/weather/5691d855e1619af1cd0bb5df36685e514ceb8d34ee29a909b2c4d6a265e57443.json data/weather/5f0c8fddae76bce3bde0cb255dc287cd7405456b49b3ea483ef1f6d602d360ee.json data/weather/6118c611b76b6e1cede6a57960709890a04349f5b3fb75fabc99236783a64a15.json data/weather/634f3c0e320c59c161bb477d4ba8503653abe0cced180913215c3d1ea6b5bd40.json data/weather/66343d62fbc5d21c1991bc911ac1a93fc83bdf80403059a083845c652f73d94b.json data/weather/7084f64e9cff532e6f6722c953f0b2d7288153a633e61e752409538c31424e1e.json data/weather/725dd69ef8afb8aadd2128b72a993eaee1f2590f160681e978c0e48cfe8e30d7.json data/weather/7368c73079151ef86b0e4ff35aa7ba62e1c18db0c04f7411c9068afc8d184d9b.json data/weather/791a4eb51d8a3dc76510723fed26289164ca61a79e154cb308aedabc0cc25b13.json data/weather/7c4868aa1a44c93b1bd24ea4584919a279616ab7f6c2961b080359ea51223953.json data/weather/7e0f00ea8e427ed2edc636d5dff484bd7051d8f9778b84b09d832a862f701c82.json data/weather/7ef2f90103ee7e868c17e2c7c0d6eb0a29ca89ba34c92a7f2fe5bf604657c407.json data/weather/808c1bb986cd33de555fadec3c2013b1e8852ff27615aaacb900f8b327869680.json data/weather/832833173f2ccd925770871ac3b3d2965d2a507a01566028a9d5cd39b003411b.json data/weather/84afed2218cedc37c2f1037134481a54f055c982e1d1897c5b0611d6ba855afd.json data/weather/8a752ed8e284d2936725b098f4c8604db6c21b302c7afb611ce8a464ca41a1db.json data/weather/8e8ffca5a381e9d5034bbf3bb20da78221556760e8acf1658334cdf8222822de.json data/weather/9d3563cfa0f891d1900acfc40c130b1035e2348a4f400dff9eb32518e58a9a3f.json data/weather/9e18f2d704b5cbfaeb064de0feebb82efe42c8292e78a8430601eee43fcfcc53.json data/weather/abba1d1ad33579a5d3ac7b7dc3f32b9462c2d43f1fe2a1bed984f7e5f77533fc.json data/weather/b69fdf27db5843f7c7eee639cf171d3a98a40364474d842ad2d4bfd420eb64e9.json data/weather/b7e7754ceb41e507b63d335ff132b2f1b2262e63d6ebe6da060cc8ed972a08dd.json data/weather/baf3e3d95028df4bd2cc4ec416953c1b7a78aa6ae257184485bdb601ed1429f3.json data/weather/bde69263b9eaad028529c1fe87bfb46e7900a212f32a980dc65b4b45b1982c47.json data/weather/bfa5196ec4410609e3bf4d509a8054d58c4f365eaae03a12b44a0f1bd412b40c.json data/weather/bfe26ac696ff0a28e9c61219a144084a7449f9619dbacbee83b085460d8056e0.json data/weather/c1a414172cdcced5fd39ccf8b23accffd80d5e915d7c79a17ebee947c8b14ee1.json data/weather/c4795ca136ce23e79eb928634be13634251ce60d2735ef0254fead77a1ec93d4.json data/weather/cceddee7b4ac3e48f06fa87fd3d7781ef35315bc41d2f617c2a9a38fb48d258b.json data/weather/d1df0221a9766e45deeac94acdc956c276197f86d9e4d66d922626cac58927a6.json data/weather/e390bfd2fba1a7c263a749a5bae10f18f22fc9929e493b65d4b2cf17ae495edd.json data/weather/e4dff511aebace995e5ffdf7b13adfdb791013214157990f2f3abe342dd6f3e0.json data/weather/e56251e99c3c4415d0331b5a49e3181e4e112f82d0402ba5a2f25a20562dfcb7.json data/weather/e5e69c2369307da5f819db749266b37404a9b812f5200c19974c0b572a79ff21.json data/weather/e7a47220c3f41d0e752d862d35432c71d77c30b2010fa39ebb24bd86260f3915.json data/weather/eaa925267f05931b480cc75950459ac9956e3373e11b3e3d1ee292ef3fc30f5a.json data/weather/eacd324bf1392787758b321824d30709f567b7ae1ef3c32e5ff7a9e6781e7b98.json data/weather/edcc7c848336f83089e629587087ff961b01691fef4923d8cc85efc5f5bfcc49.json data/weather/f75bd10b54290a4ea0db9bfb884f619e2cbf9b6bd4d4757739eec39a8467a8aa.json data/weather/f7bca7a38cf03cdfbbeb4d3813ab16b1bb1e4b38c3185a5b49077dd1e6512658.json data/weather/f9985b1e047ae095b1e53f226e0dde33665672c27065ddac9cc4b0c0ae15b73f.json docs/DEFENSE.md docs/DEPLOYMENT.md docs/FILES.md docs/examples/turbine_1_24h.csv docs/frontend.md docs/media/dashboard-agent.png docs/media/forecast-csv.png docs/media/landing-footer.png docs/media/landing.png docs/media/windai-demo.mp4 image/README/1790153145464.png models/turbine_1.joblib models/turbine_1_evaluation.joblib models/turbine_2.joblib models/turbine_2_evaluation.joblib pytest.ini render.yaml requirements.txt results/RESULTS.md results/api_smoke_checks.json results/backtest_metrics.json results/backtest_predictions.csv results/eda/correlations.png results/eda/distributions.png results/eda/power_curves.png results/eda/report.json results/eda/report.md results/eda/turbine_comparison.png results/example_live_turbine_1.json results/example_live_turbine_2.json results/example_replay_turbine_1.json results/example_replay_turbine_2.json results/metrics.json results/model_metadata.json results/scada_outage/REPORT.md results/scada_outage/metrics.json results/scada_outage/predictions.csv results/submission_evidence.json results/validation_forecasts.png results/validation_metrics.json results/validation_predictions.csv results/verification.json scripts/_bootstrap.py scripts/analyze_data.py scripts/check_scada_outage.py scripts/fetch_weather.py scripts/report_results.py scripts/run_agent.py scripts/run_backtest.py scripts/run_pipeline.py scripts/smoke_api.py scripts/train_models.py scripts/verify_submission.py src/__init__.py src/agents/__init__.py src/agents/assessment.py src/agents/copilot.py src/agents/forecast_agent.py src/agents/monitor.py src/agents/turbine_insights.py src/api/__init__.py src/api/main.py src/api/schemas.py src/config.py src/data/__init__.py src/data/features.py src/data/loader.py src/data/preprocessing.py src/models/__init__.py src/models/backtest.py src/models/evaluate.py src/models/predict.py src/models/train.py src/services/__init__.py src/services/weather_provider.py src/utils.py tests/test_agent.py tests/test_pipeline.py tests/test_scada_outage.py tests/test_turbine_insights.py tests/test_website.py vercel.json web/.env.example web/README.md web/app.js web/assets/dashboard-background-prompt.md web/assets/dashboard-blueprint-prompt.md web/assets/dashboard-blueprint.png web/assets/dashboard-landscape.png web/assets/digital-twin-title.png web/assets/footer-background-prompt.md web/assets/footer-wind-background.png web/assets/landing-background-prompt.md web/assets/landing-wind-background.png web/assets/turbine-cursor.svg web/assets/wind-farm.png web/assets/wind-scroll-transition.mp4 web/assets/windai-icon.svg web/assets/windai-logo.png web/assets/windai-logo.svg web/assistant-panel.js web/backend.js web/charts.js web/dashboard-i18n.js web/dashboard.css web/index.html web/landing-i18n.js web/landing.css web/overview-art.js web/overview-motion.js web/package-lock.json web/package.json web/scroll-journey.js web/style.css web/turbine-cursor.js web/twin-blueprint.js web/twin-materials.js web/twin.js web/vite.config.mjs
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.
