TwinTurbo.ai
Система почасового прогноза мощности двух ветротурбин на 24/48 часов по SCADA-истории и архивным прогнозам NOAA GFS.
О проекте
Команда: ChachMechanics
Кейс HackAlem.ai: Энергетика — Самрук-Казына
Стадия: Доведённый продукт
Задача кейса: AI-агент, прогнозирующий выработку ветровой электростанции по погодным данным
Суть
Система почасового прогноза мощности двух ветротурбин на 24/48 часов по SCADA-истории и архивным прогнозам NOAA GFS. Выдаёт квантили Q10/Q50/Q90, версионирует выпуски и показывает в Streamlit КИУМ, MAE, отклонения и рекомендации.
Как устроено
SCADA CSV (UTC+05) агрегируется в почасовые as-of наблюдения. Берётся только тот выпуск GFS, который был доступен к моменту прогноза (available_at <= origin_time); архив кэшируется и сопровождается SHA-256 provenance. Модели: отдельная power curve на каждую турбину, базовые mean и persistence, Ridge, опциональный boosting и ensemble. Выбор модели идёт по MAE на последовательном временном бэктесте, затем применяется online bias-коррекция по созревшим ошибкам. Квантили не выдаются, пока не накопится 30 ошибок. Агентные модули (forecaster, critic, advisor, weather_archivist, orchestrator) ведут журнал, всё хранится в SQLite/JSON/CSV с replay.
Ключевые решения
- power curve model
- online bias correction
- Ridge regression
- gradient boosting
- ensemble
- quantile intervals Q10/Q50/Q90
- pinball loss
- sequential temporal backtest
- as-of weather selection
- NOAA GFS archive
- capacity factor (КИУМ)
Метрики
Январь: MAE power curve 0.2266 против mean baseline 0.3023 (skill 25.06%); на пиковых часах улучшение 55.67%; power curve+bias на 16–31 янв MAE 0.1952 (−10.85%); Ridge 0.3707 (отключён); покрытие Q10–Q90 0.767 при цели 0.80, ширина 0.514
Особенности
Строгая защита от утечки будущего: погодный выпуск выбирается по времени его фактической доступности, есть задержка поступления факта 15 минут. Сложная модель подключается только после доказанного выигрыша по MAE, поэтому в production выбрана power curve с bias, а не Ridge или ансамбль. МВт·ч без подтверждённого номинала турбин не выдумываются.
Стек
Python · Streamlit · SQLite · ecCodes · Docker · GitHub Actions · Render
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-a9db1b13-chachmechanics.
README
README.mdTwinTurbo.ai
Почасовой прогноз нормализованной мощности двух ветровых турбин на 24 или 48 часов с честной неопределённостью, последовательной проверкой качества и полным происхождением данных.
TwinTurbo.ai объединяет реальную историю SCADA, архивные выпуски NOAA GFS, отдельные кривые мощности турбин, online bias-коррекцию, Q10/Q50/Q90, версионирование выпусков и Streamlit-интерфейс. Главный критерий выбора модели — минимальный MAE на будущих относительно обучения данных. Более сложная модель включается только после доказанного улучшения.
Продукт называется TwinTurbo.ai. Совместимое имя Python-пакета и CLI —
windoracle, поэтому штатные команды имеют видpython -m windoracle .... Исходники находятся вsrc/TwinTurbo.ai/; это не два разных проекта.
Что уже реализовано
- импорт двух исходных CSV, аудит качества и почасовая агрегация;
- подтверждённый фиксированный часовой пояс исходных меток UTC+05:00 (
Etc/GMT-5), семантика начала интервала и задержка поступления факта 15 минут; - выбор только такого погодного выпуска, который был доступен к
origin_time(available_at <= origin_time); - реальный архив NOAA GFS, локальный кэш, аудит покрытия и SHA-256 происхождения;
- ежедневный выпуск в 23:00 местного времени, то есть в 18:00 UTC, на 24/48 часов;
- отдельная forecast-space power curve для каждой турбины;
- mean и persistence baselines, Ridge, опциональный boosting и ensemble;
- последовательная временная проверка без перемешивания прошлого и будущего;
- bias-коррекция только по уже созревшим ошибкам;
- Q10/Q50/Q90, pinball loss, покрытие и ширина интервала;
- неизменяемые версии модели, bias и прогнозных выпусков;
- SQLite/JSON/CSV, проверка checksum, replay и журнал действий агентов;
- Streamlit-интерфейс: 24/48 часов, сравнение выпусков, доступный факт, КИУМ, MAE, типы отклонений, рекомендации и ветровая карта;
- отдельный синтетический fixture-режим для мгновенной демонстрации без сети.
Путь одного прогноза:
SCADA CSV (+05) ──> почасовые as-of наблюдения ─┐
├─> power curve ─> bias ─> Q10/Q50/Q90
архивный NOAA GFS ─> допустимый погодный run ───┘ │
v
SQLite + JSON/CSV + Streamlit
Модель не скачивает погоду и не читает сырой CSV. Это делает интеграционный слой, а predictor получает уже разрешённый AsOfSnapshot. UI также не пересчитывает прогноз: он работает через ForecastService.
Что проверено локально
Главный результат находится в кратком отчёте и полном JSON с provenance. Проверка использует 39 реальных выпусков GFS: 8 для предъянварской настройки и 31 для последовательного январского backtest. Полезная сетевая нагрузка архива — 2 000 847 617 байт.
| Проверка | Строк | MAE | Решение |
|---|---|---|---|
| Mean baseline, весь январь | 2 928 | 0.3023227 | База сравнения |
| Power curve, весь январь | 2 928 | 0.2265555 | Включена: skill к mean baseline 25.06% |
Mean baseline, пиковые часы fact >= 0.8 | 456 | 0.5690665 | Диагностика |
| Power curve, те же пиковые часы | 456 | 0.2522542 | Улучшение 55.67% |
| Power curve, нетронутый период 16–31 января | 1 488 | 0.2190094 | База для bias |
| Power curve + bias, тот же период | 1 488 | 0.1952489 | Финальный выбранный вариант |
| Ridge, тот же период | 1 488 | 0.3707068 | Отключён: MAE хуже |
Bias уменьшил MAE power curve на отложенном периоде примерно на 10.85%. Ridge не прошёл ворота качества; Ridge+bias также не победил. Ensemble отключён, потому что добавлять ещё одну степень свободы без независимого улучшения было бы необоснованно. В production выбран не самый сложный, а реально лучший из проверенных вариантов: power curve + bias.
MAE здесь измеряется в нормализованной мощности от 0 до 1, а не в МВт и не является «процентом точности». UI дополнительно показывает RMSE, среднюю знаковую ошибку, долю недопрогноза, перепрогноза и долю попаданий в нейтральный коридор ±0.05.
Неопределённость
На отложенном периоде 16–31 января:
- Q10/Q50/Q90 доступны для 100% из 1 488 оценённых строк;
- фактическое покрытие Q10–Q90 — 0.76747 при целевом 0.80;
- средняя ширина Q10–Q90 — 0.51440 нормализованной мощности.
Покрытие немного ниже цели, и это показывается как есть. До накопления 30 зрелых ошибок для пары «турбина × группа горизонта» квантили равны null, а статус содержит interval:insufficient_history. При устаревшем состоянии bias интервалы также не выдумываются. Так модель буквально сообщает, когда данных для уверенного диапазона недостаточно.
КИУМ, точность и способы отклонения
КИУМ (коэффициент использования установленной мощности, capacity factor) для равных часовых интервалов вычисляется как среднее power_norm:
КИУМ = sum(power_norm) / N
Интерфейс показывает прогнозный КИУМ выбранного горизонта и фактический КИУМ только по уже доступным измерениям. Для физической энергии в МВт·ч необходима подтверждённая номинальная мощность каждой турбины. Пока rated_power_mw: null, TwinTurbo.ai корректно оставляет МВт·ч пустыми и не подменяет неизвестный номинал предположением. Станционный КИУМ при разных номиналах должен быть взвешен по установленной мощности.
Знак ошибки принят как prediction - actual:
- недопрогноз — ошибка меньше
-0.05: фактическая мощность выше ожидаемой; - перепрогноз — ошибка больше
+0.05: фактическая мощность ниже ожидаемой; - нейтральная зона — абсолютная ошибка не больше 0.05;
- bias — средняя знаковая ошибка, а MAE — средний модуль ошибки.
Причины отклонений система не придумывает. По имеющимся данным можно доказать только само отклонение, его направление, длительность и связь с прогнозом погоды. Обледенение, curtailment, отказ датчика или поломка требуют отдельных эксплуатационных сигналов.
Рекомендации оператору и ремонту
Блок «Оперативная аналитика» формирует только проверяемые подсказки поддержки решения:
- при широком Q10–Q90 предлагает предусмотреть резерв или гибкость графика;
- при ожидаемой мощности не ниже 0.90 напоминает проверить сетевые ограничения и готовность приёма мощности;
- при устойчивом перепрогнозе предлагает проверить доступность установки, журнал ограничений, качество датчиков и состояние оборудования;
- при отсутствии интервалов предупреждает не использовать одно число как гарантированный диспетчерский график.
Это не команда автоматически повысить или понизить уставку и не диагноз «деталь скоро сломается». В датасете нет паспортных ограничений, аварийных кодов, вибрации, температур подшипников и редуктора, токов генератора, положения pitch/yaw, данных об обледенении и диспетчерском ограничении. Без них конкретная рекомендация «заменить редуктор» была бы выдумкой.
Практический следующий уровень для predictive maintenance:
- подключить SCADA alarms/events и журнал ремонтов;
- добавить vibration, bearing/gearbox temperature, generator current, pitch/yaw и icing-сигналы;
- задать паспортные пределы и регламент производителя;
- проверить правила на исторических отказах;
- только после этого выводить вероятный узел, срочность осмотра и основание рекомендации.
До такой интеграции TwinTurbo.ai рекомендует что проверить, но не утверждает, что именно сломано.
Ветровая карта
Streamlit показывает обе турбины на карте по их координатам и прикрепляет к точкам доступные скорость, направление ветра и температуру из сохранённого погодного снимка выпуска. Размер маркера отражает скорость ветра; выбранная турбина выделяется в интерфейсе.
Это точечная погодная карта, а не CFD-модель и не непрерывное поле ветра. Разрешение GFS — 0.25°, поэтому близкие турбины могут попадать в одну ячейку и иметь одинаковый внешний прогноз. Карта не доказывает wake-эффект, влияние рельефа или шероховатости. Для такой детализации нужны локальная мачта/LiDAR, цифровая модель рельефа и downscaling. У старого выпуска без manifest.weather_values карта честно сообщает, что погодные точки отсутствуют.
Запуск от clone до работающей системы
1. Требования
- Git;
- Python 3.11+; для Windows и нативного ecCodes рекомендуется Python 3.13;
- около 3 ГБ свободного места для полного январского GFS-кэша;
- интернет только для установки зависимостей и первой загрузки NOAA GFS.
2. Клонирование и окружение
git clone <URL_РЕПОЗИТОРИЯ>
cd hack-a9db1b13-chachmechanics
python -m venv .venv
Windows PowerShell:
.\.venv\Scripts\python.exe -m pip install --upgrade pip
.\.venv\Scripts\python.exe -m pip install -r requirements.lock
.\.venv\Scripts\python.exe -m pip install --no-deps -e .
.\.venv\Scripts\python.exe -m pip check
.\.venv\Scripts\python.exe -m eccodes selfcheck
Linux/macOS:
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install -r requirements.lock
.venv/bin/python -m pip install --no-deps -e .
.venv/bin/python -m pip check
.venv/bin/python -m eccodes selfcheck
3. Мгновенный просмотр
Без сети, GFS и базы:
python -m frontend.preview --port 8765
Открыть http://127.0.0.1:8765. Это явно маркированный синтетический fixture, предназначенный для проверки интерфейса, а не качества прогноза.
Полный Streamlit UI:
python -m streamlit run app.py
Он также открывается в fixture-режиме, но уже показывает оперативный блок, КИУМ, отклонения, рекомендации и карту.
4. Проверка конфигурации и импорт реальных CSV
В репозитории используются короткие стабильные имена:
data/raw/turbine_1.csv
data/raw/turbine_2.csv
configs/site.yaml
Ключевой фрагмент configs/site.yaml:
site:
timezone: Etc/GMT-5 # фиксированный UTC+05; знак в Etc/GMT инвертирован
timestamp_semantics: interval_start
time_basis: confirmed
observation_delay_minutes: 15
forecast:
issue_local_time: '23:00' # 18:00 UTC
horizon_hours: 48
Импорт:
python -m windoracle ingest \
--config configs/site.yaml \
--turbine-1 data/raw/turbine_1.csv \
--turbine-2 data/raw/turbine_2.csv \
--output reports/ingest-utc-plus05.json
В PowerShell обратные слеши можно убрать и выполнить команду одной строкой.
5. Bootstrap реального GFS
Один проверочный выпуск:
python -m windoracle weather fetch --config configs/site.yaml \
--origin 2026-01-01T18:00:00Z \
--run 2026-01-01T12:00:00Z \
--progress
Все 39 выпусков, использованные для предъянварской калибровки и январской проверки:
python -m windoracle weather fetch --config configs/site.yaml \
--start 2025-12-24 --end 2026-01-31 \
--max-runs 39 --max-download-mb 2600 --progress \
--output reports/weather-january-bootstrap.json
Команда идемпотентна относительно валидного кэша: уже сохранённые объекты повторно используются. Доступность run всё равно перепроверяется для каждого origin_time.
6. Полное воспроизведение январского выбора модели
После импорта и загрузки GFS:
python scripts/reproduce_january.py --config configs/site.yaml
Скрипт заново строит только допустимые as-of снимки, настраивает кривую до января, последовательно сравнивает baseline/power curve/bias/Ridge, применяет строгие ворота MAE и записывает:
reports/january-model-comparison.json— полный машиночитаемый отчёт;reports/january-model-comparison.md— краткую сводку;artifacts/models/february-production.json— выбранную модель;artifacts/bias/february-production-bias.json— состояние коррекции.
Проверка не использует январский факт раньше его реального available_at. Полный JSON содержит временные границы, гиперпараметры, GFS run IDs и хэши, версии состояния Critic и SHA-256 исходного кода эксперимента.
7. Проверка базового predictor через штатный CLI
PowerShell:
$env:TWINTURBO_MODEL_ARTIFACT = 'artifacts/models/february-production.json'
python -m windoracle predict `
--config configs/site.yaml `
--origin 2026-01-30T18:00:00Z `
--predictor windoracle.models.registry:load_predictor `
--mode replay `
--output outputs/forecast
python -m windoracle verify --input outputs/forecast
python -m windoracle export --input outputs/forecast --output outputs/forecast.csv
Linux/macOS:
export TWINTURBO_MODEL_ARTIFACT=artifacts/models/february-production.json
python -m windoracle predict \
--config configs/site.yaml \
--origin 2026-01-30T18:00:00Z \
--predictor windoracle.models.registry:load_predictor \
--mode replay \
--output outputs/forecast
python -m windoracle verify --input outputs/forecast
python -m windoracle export --input outputs/forecast --output outputs/forecast.csv
Один штатный 48-часовой выпуск для двух турбин содержит 96 строк. Артефакт модели проверяется по checksum; случайной или молчаливой fallback-модели нет. Эта команда проверяет точечную power curve: общий predict намеренно не угадывает, какое состояние bias загрузить. Полная выбранная цепочка power curve + конкретный versioned bias запускается следующим offline-скриптом, где оба артефакта переданы явно.
8. Февральский replay 1–28 февраля
Целевой сценарий — ежедневный выпуск в 23:00 UTC+05 с горизонтом 48 часов. Для целей 1–28 февраля нужны origin от 2026-01-31T18:00:00Z до 2026-02-27T18:00:00Z.
Сначала загрузить допустимые GFS-выпуски:
python -m windoracle weather fetch --config configs/site.yaml \
--start 2026-02-01 --end 2026-02-28 \
--max-runs 28 --max-download-mb 2600 --progress \
--output reports/weather-february-bootstrap.json
Затем выполнить offline-генерацию уже по кэшу и замороженным артефактам:
python scripts/generate_february.py \
--config configs/site.yaml \
--model artifacts/models/february-production.json \
--bias artifacts/bias/february-production-bias.json \
--output outputs/replay-february
python -m windoracle verify --input outputs/replay-february
generate_february.py не скачивает погоду и не читает CSV: он использует импортированный SQLite, проверенный GFS-кэш и неизменяемые модель/bias. Если bias становится старше разрешённого окна, точечный прогноз остаётся базовым, Q10/Q50/Q90 становятся null, а статус явно сообщает об устаревшей истории.
Статус: февральский replay является обязательным следующим артефактом сдачи, но в README не объявляется завершённым, пока каталог outputs/replay-february не сгенерирован, не прошёл verify и не открыт через UI.
9. Запуск UI на реальном сервисе
PowerShell:
$env:TWINTURBO_CONFIG = 'configs/site.yaml'
$env:TWINTURBO_MODEL_ARTIFACT = 'artifacts/models/february-production.json'
$env:TWINTURBO_PREDICTOR = 'windoracle.models.registry:load_predictor'
python -m streamlit run app.py
В интерфейсе переключиться из Демо в Проверка на истории. ForecastService предоставляет каталог выпусков, новый расчёт, сравнение, доступный факт, журнал и экспорт. Сгенерированные февральские выпуски уже содержат применённый versioned bias и отображаются без пересчёта. Новый расчёт через стандартную UI-фабрику использует подключённый predictor без автоматического выбора bias; для online-обновления bias нужна сервисная фабрика, которая передаёт явно выбранное допустимое состояние в create_forecast. Без модели просмотр сохранённых выпусков доступен, а новый расчёт отключён.
Что хранится в Git и почему
Чтобы проверяющий действительно мог клонировать, установить и запустить проект, в репозиторий должны входить:
- оба исходных CSV под стабильными именами
data/raw/turbine_1.csvиturbine_2.csv; - подтверждённый
configs/site.yamlбез секретов; - исходный код, lock-файл зависимостей и тесты;
- выбранные JSON-артефакты модели и bias;
- полный январский отчёт и маленькие отчёты загрузки GFS;
- проверенные финальные прогнозы/экспорт для показа;
- синтетические fixtures, всегда явно помеченные как
synthetic.
Не следует коммитить:
.venv/venv,__pycache__и кэши тестов;- временную SQLite, которая детерминированно восстанавливается командой
ingest; - весь
data/weather: текущий рабочий GFS-кэш занимает около 2.2 ГБ и содержит тысячи производных объектов; - временные файлы и незавершённые выгрузки.
Большой GFS-кэш не является скрытой зависимостью: команда bootstrap, run IDs, метаданные, размеры и хэши публикуются. Его загрузка из NOAA воспроизводима, а хранение в обычном Git резко утяжелило бы каждый clone. Если организаторы требуют полностью offline-архив, правильный вариант — приложить версионированный ZIP к GitHub Release или объектному хранилищу с SHA-256, а не помещать 2.2 ГБ в историю Git.
.gitignore нужен именно для машинных окружений и восстанавливаемых тяжёлых данных; он не должен исключать CSV, конфигурацию, production-артефакты, отчёт и финальные результаты. Пустые .gitkeep для работы системы не нужны.
Деплой: Render или Vercel
Что готово, а что только настроено
Локальный Streamlit, общий Python-сервис, модельные артефакты и команды запуска проверены. Публичный URL пока не заявляется: ниже приведена готовая конфигурация деплоя, которую ещё нужно выполнить и проверить в облаке.
Для текущей архитектуры проще и надёжнее один Render Web Service: Streamlit и Python backend уже работают одним процессом.
Рекомендуемые команды Render:
Build: pip install -r requirements.lock && pip install --no-deps -e .
Start: streamlit run app.py --server.address 0.0.0.0 --server.port $PORT
Для fixture-демо база данных не нужна. Для реальных выпусков и истории SQLite обязательна как текущее хранилище проекта. На Render файловая система сервиса по умолчанию эфемерна, поэтому для одного экземпляра нужен persistent disk и пути storage.database/weather.cache_dir под его mount point, например /var/data/twinturbo.sqlite и /var/data/weather. Это соответствует официальной документации Render о persistent disks.
SQLite подходит для демо и одного экземпляра. Для нескольких реплик и production-нагрузки разумно добавить отдельный адаптер хранилища для PostgreSQL; сейчас такой адаптер не заявлен реализованным.
Vercel не нужен для текущего репозитория. Его можно использовать позже только для отдельно собранного статического/Next.js frontend, который обращается к Render API. Сейчас интерфейс — Streamlit, а Vercel Python Runtime строится вокруг функций-запросов, имеет read-only filesystem кроме временного /tmp и ограничения на bundle/runtime; см. официальное описание Vercel runtimes. Разделение на Vercel + Render добавит CORS, авторизацию и второй деплой, не улучшив конкурсное демо.
Чек-лист деплоя
- Сначала добиться локального
pytest -qиeccodes selfcheck. - Сгенерировать и проверить
outputs/replay-february. - Для простого публичного показа развернуть fixture/готовые неизменяемые результаты на Render без online-загрузки GFS.
- Для новых расчётов подключить persistent disk и положить на него SQLite/GFS-кэш.
- Задать
TWINTURBO_CONFIG,TWINTURBO_MODEL_ARTIFACT,TWINTURBO_PREDICTOR. - Проверить в браузере прогноз, факт, Q10/Q50/Q90, КИУМ, отклонения, карту, рекомендации, сравнение выпусков и CSV.
- Только после этого публиковать URL как рабочий деплой.
Проверки
python -m pytest -q
python -m unittest tests.test_ui_contract -v
python -m pip check
python -m eccodes selfcheck
Тесты охватывают as-of, временную доступность, weather audit, модельные артефакты, baseline/power curve/Ridge, bias, интервалы, метрики, КИУМ, направления отклонений, replay, сохранение, экспорт, UI-контракт и запрет выдавать fixture за конкурсный результат.
Структура проекта
| Путь | Назначение |
|---|---|
src/TwinTurbo.ai/ingest.py, store.py, clock.py | CSV, as-of и хранение |
src/TwinTurbo.ai/weather/ | NOAA GFS, кэш, аудит и происхождение |
src/TwinTurbo.ai/features.py | Признаки только из разрешённого снимка |
src/TwinTurbo.ai/models/ | Baselines, power curve, ML, bias и интервалы |
src/TwinTurbo.ai/evaluate.py, backtest.py | Метрики и последовательная проверка |
src/TwinTurbo.ai/agents/ | Orchestrator, Forecaster, Critic, Advisor |
src/TwinTurbo.ai/service.py | Единый API для CLI и UI |
frontend/, ui/, app.py | Интерфейс и представление результатов |
scripts/reproduce_january.py | Воспроизведение выбора модели |
scripts/generate_february.py | Offline-генерация февральского replay |
reports/ | Воспроизводимые отчёты качества и загрузок |
artifacts/models/, artifacts/bias/ | Неизменяемые production-версии |
outputs/ | Сохранённые выпуски и экспорт |
Точные API и временные инварианты описаны в docs/CONTRACTS.md. Сценарий показа жюри — в docs/DEMO.md, проверка интеграции — в docs/RELEASE_CHECK.md, UI-контракт — в docs/UI_INTEGRATION.md.
Честные ограничения
- Номинальная мощность турбин пока не подтверждена, поэтому физические МВт и МВт·ч не выводятся.
- GFS 0.25° не моделирует микрорельеф, шероховатость и взаимное затенение двух близких турбин.
- Покрытие Q10–Q90 на отложенном январе 76.75%, а не ровно целевые 80%.
- Рекомендации — поддержка решения, а не удалённое управление и не автоматический диагноз оборудования.
- Fixture-режим синтетический и не доказывает качество реальной модели.
- Публичный деплой считается готовым только после публикации URL и сквозной проверки на развёрнутом окружении.
- Февральский результат считается готовым только после генерации,
verifyи проверки в интерфейсе; наличие обученного артефакта само по себе этого не доказывает.
Авторы коммитов
История коммитов
- 2026-09-23 17:55savesaveРома
- 2026-09-23 17:54saveРома
- 2026-09-23 17:53Update DockerfileРома
- 2026-09-23 17:52Update reproduce_january.pyРома
- 2026-09-23 17:51pushingРома
- 2026-09-23 17:45pushРома
- 2026-09-23 17:41upload testРома
- 2026-09-23 17:26Merge branch 'main' of https://github.com/BAITC-Hacks/hack-a9db1b13-chachmechanicsРома
Все коммиты (34)
- 2026-09-23 17:26testsРома
- 2026-09-23 17:21Improve dashboard navigation, readiness and forecast actionsnorerade
- 2026-09-23 16:55Merge all team branches into a verified TwinTurbo releaseWadag02
- 2026-09-23 16:34update testsРома
- 2026-09-23 16:32updateРома
- 2026-09-23 16:31Update test_models.pyРома
- 2026-09-23 16:28dataРома
- 2026-09-23 16:05fix(ui): validate dashboard integration and Streamlit exportsnorerade
- 2026-09-23 15:46feat(ui): build TwinTurbo seasonal dashboard with service adapter and demonorerade
- 2026-09-23 15:41Merge current main CI and resumable weather downloads into forecast modelsРома
- 2026-09-23 15:38Document model handoff and add prepared-cache evaluation runnerРома
- 2026-09-23 15:26Implement as-of forecasting, calibration, temporal evaluation and CriticРома
- 2026-09-23 15:25Add integration CI and resumable bounded weather downloadsWadag02
- 2026-09-23 15:24Rename project, Python namespace and CLI to TwinTurbo.aiРома
- 2026-09-23 14:55Harden integration state, portable exports and team API contractsWadag02
- 2026-09-23 14:43Merge data replay implementation preserving TwinTurbo.ai source layoutWadag02
- 2026-09-23 14:40Implement data ingestion, GFS archive and versioned forecast replayWadag02
- 2026-09-23 14:23renaming to TwinTurbo.aiРома
- 2026-09-23 14:17каркасРома
- 2026-09-23 14:09Update README.mdРома
- 2026-09-23 13:59docs: describe wind power forecasting task and implementation plannorerade
- 2026-09-23 13:57Update README.mdnorerade
- 2026-09-23 13:57chore: add docs directoryWadag
- 2026-09-23 13:57chore: add backend directoryWadag
- 2026-09-23 13:57chore: add frontend directoryWadag
- 2026-09-23 13:56Update README.mdРома
Структура репозитория (173 файлов)
.dockerignore .env.example .github/workflows/ci.yml .gitignore .python-version AGENTS.md Dockerfile README.md TEAM.md app.py artifacts/bias/february-production-bias.json artifacts/models/february-production.json artifacts/models/forecast-power-curve-prejan-2026.json artifacts/models/mean-baseline-final-prejan-2026.json artifacts/models/ridge-prejan-2026.json configs/site.example.yaml configs/site.yaml data/MANIFEST.json data/raw/turbine_1.csv data/raw/turbine_2.csv demo/manifest.json docs/CONTRACTS.md docs/DECISIONS.md docs/DEMO.md docs/PROJECT_SPEC.md docs/RELEASE_CHECK.md docs/UI_INTEGRATION.md docs/UI_VERIFICATION.md frontend/__init__.py frontend/assets/dashboard.css frontend/assets/dashboard.html frontend/assets/dashboard.js frontend/bootstrap.py frontend/contracts.py frontend/controller.py frontend/fixture_service.py frontend/fixtures/demo.json frontend/fixtures/exports/demo-0115-r1.csv frontend/fixtures/exports/demo-0115-r2.csv frontend/fixtures/exports/demo-0201-r1.csv frontend/fixtures/exports/demo-0201-r2.csv frontend/fixtures/exports/demo-0415-r1.csv frontend/fixtures/exports/demo-0415-r2.csv frontend/fixtures/exports/demo-0715-r1.csv frontend/fixtures/exports/demo-0715-r2.csv frontend/fixtures/exports/demo-1015-r1.csv frontend/fixtures/exports/demo-1015-r2.csv frontend/gateway.py frontend/preview.py frontend/requirements.txt outputs/replay-february/1110479f9f43c06c4a8127ab4abed16e398be1676cdb500e1b60cb3feb1b365e.json outputs/replay-february/13a7d9155ddc4744c050c4a6d43004c5a66376f4b7f0b532a361aacf82fc4d9f.json outputs/replay-february/143196579b1c0d008f954140a5aa2c4f01380b039d9113b24a68d50a9dfe62ca.json outputs/replay-february/17c3ef025f4d446646b0ca30ab36b5ba00bc96e05fb8f8e1dd9546822d59b9d5.json outputs/replay-february/1afd97f30ccdafc814a96e5143b2d41606cf34a03c4131497d2cd61606a90315.json outputs/replay-february/21991cd4386bf4d614eeaaed6ffbdcb7004042499a0eb3790ea362338a4553b7.json outputs/replay-february/31e1d0d951b6eb219410bf31f7f2c26347ae34702505fe06b36f9544eee0b2b2.json outputs/replay-february/345b5f4f8d47900be5d854322685d76c6ed68f6b1fc3dcf0ab41f10178ab396e.json outputs/replay-february/3b3604f71f534959f3d8b909dee5f3fc5dc1a414f2f802e0cf6d50f53a6e7619.json outputs/replay-february/3dedffb121cc988f3e93beb03976e262e8f18bce99508b9105242a72e31b7a0d.json outputs/replay-february/3f34bd8980ce9b81374ca7f2b3c8c8af3f46fbfac7bcd38884d87cdc94cf141c.json outputs/replay-february/42693bcbba1870ba85db13da26aaaeddabff08413e3d20ad06c4098f7865df65.json outputs/replay-february/5c5081fbd3c6022160ec565bc8e8c70cf91a2e00fcd01fc3fbedc4d2f17c16e6.json outputs/replay-february/63b73dd7cd22ce209a64a3a6faceead547b842d15debb6422e53e555faaeb495.json outputs/replay-february/72cbf9dfba83f9c070890d03bcc8510a0b1b12b489c2804073394b2b07d31538.json outputs/replay-february/83d2f33dd6d58ae03923908230984d3442d7100f43c62e5cc645790dc3cdf2de.json outputs/replay-february/8759f558678d82e38e7e7a695aa1b08335e4ae82cd16654d51f92d2ed3e5a5b2.json outputs/replay-february/882e4058684bd90047b31f9f79a7dcbbc2f42709eb1d206afe718f66aae4d47d.json outputs/replay-february/992044a5efdac536f190eb381a0502dab304a690d4719e6cbe411b85e8573c81.json outputs/replay-february/aaa977d1c7f27c8e8253b363b0583d32136f1fc094b10ea4bdec79940d5d825e.json outputs/replay-february/b8074da21c4037557615a79e55495a5ba8c192fd92d13e1d34c2a8b18d793a47.json outputs/replay-february/bad6a7a013264c51d4ac3026562196e15667d085b0ab23a4f6386e110a86fe40.json outputs/replay-february/c895014ae7481a5ade8d7c80f190b086ef800ecd7276cbeebfc43f5cf29a3d8c.json outputs/replay-february/cb169cb2eda569793fcef8c921966c4218070b3f8dbf26531b80bbfd8d26787e.json outputs/replay-february/cf41f54843d5dba0fecd4c69d928005a34285d749dbce195a80ada7b7b893895.json outputs/replay-february/d1b22007702058fff13c57389621afdfdecbcef89cc08d75ca1d589753b5c75f.json outputs/replay-february/e9e8e71c33c5f09ba56a4958f18b2097903dac1ba73a103478d013d1f7544197.json outputs/replay-february/f8f28da151c0624e632153c878c1d48669f69604fe7814c2dc35dfd4fe5880f5.json outputs/replay-february/forecasts.csv outputs/replay-february/index.json outputs/replay-february/replay-report.json pyproject.toml render.yaml reports/forecast-models/README.md reports/forecast-models/fixture-comparison.json reports/ingest-utc-plus05.json reports/january-model-comparison.json reports/january-model-comparison.md reports/weather-dec-24-27.json reports/weather-dec-28-31.json reports/weather-feb-01-07.json reports/weather-feb-08-14.json reports/weather-feb-15-21.json reports/weather-feb-22-28.json reports/weather-jan-01-07.json reports/weather-jan-08-14.json reports/weather-jan-15-21.json reports/weather-jan-22-28.json reports/weather-jan-29-31.json reports/weather-probe-2026-01-01.json requirements.lock scripts/bootstrap.py scripts/generate_february.py scripts/prepare_demo.py scripts/reproduce_january.py scripts/run.py src/TwinTurbo.ai/__init__.py src/TwinTurbo.ai/__main__.py src/TwinTurbo.ai/agents/__init__.py src/TwinTurbo.ai/agents/advisor.py src/TwinTurbo.ai/agents/critic.py src/TwinTurbo.ai/agents/forecaster.py src/TwinTurbo.ai/agents/memory.py src/TwinTurbo.ai/agents/orchestrator.py src/TwinTurbo.ai/agents/twin_builder.py src/TwinTurbo.ai/agents/weather_archivist.py src/TwinTurbo.ai/backtest.py src/TwinTurbo.ai/cli.py src/TwinTurbo.ai/clock.py src/TwinTurbo.ai/config.py src/TwinTurbo.ai/evaluate.py src/TwinTurbo.ai/export.py src/TwinTurbo.ai/features.py src/TwinTurbo.ai/ingest.py src/TwinTurbo.ai/models/README.md src/TwinTurbo.ai/models/__init__.py src/TwinTurbo.ai/models/baseline.py src/TwinTurbo.ai/models/bias.py src/TwinTurbo.ai/models/boosting.py src/TwinTurbo.ai/models/ensemble.py src/TwinTurbo.ai/models/intervals.py src/TwinTurbo.ai/models/ml.py src/TwinTurbo.ai/models/power_curve.py src/TwinTurbo.ai/models/registry.py src/TwinTurbo.ai/replay.py src/TwinTurbo.ai/schemas.py src/TwinTurbo.ai/service.py src/TwinTurbo.ai/store.py src/TwinTurbo.ai/weather/__init__.py src/TwinTurbo.ai/weather/archive.py src/TwinTurbo.ai/weather/audit.py src/TwinTurbo.ai/weather/base.py src/TwinTurbo.ai/weather/cache.py src/TwinTurbo/__init__.py src/TwinTurbo/ai/__init__.py src/TwinTurbo/ai/__main__.py src/TwinTurbo/ai/backtest.py src/TwinTurbo/ai/cli.py src/TwinTurbo/ai/evaluate.py tests/__init__.py tests/conftest.py tests/test_bias.py tests/test_clock.py tests/test_export.py tests/test_ingest.py tests/test_integration_merge.py tests/test_intervals.py tests/test_metrics.py tests/test_models.py tests/test_operations.py tests/test_replay.py tests/test_reproduction_scripts.py tests/test_service.py tests/test_temporal_contract.py tests/test_ui_contract.py tests/test_weather.py ui/__init__.py ui/charts.py ui/controls.py ui/dashboard.py ui/events.py ui/operations.py ui/provenance.py
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.