Brief do Agente: Construir Conectores de Relatórios de Fitness OpenClaw para Garmin, WHOOP, Speediance e Mais
Um brief de implementação pronto para agentes para construir conectores de relatórios de fitness OpenClaw em Garmin, WHOOP, Speediance, Cronometer, 8Sleep, snapshots JSON normalizados e repositórios públicos do GitHub.
Este artigo deve ser entregue a um agente de codificação de IA como um brief de implementação.
O objetivo não é replicar minha máquina local nem fazer engenharia reversa dos meus arquivos. O objetivo é que um agente leia esta página e construa conectores funcionais para os sistemas de fitness: Garmin, WHOOP, Speediance, Cronometer, 8Sleep e o Open Wearables opcional.
A instrução central é simples: trate cada fornecedor como um conector, persista snapshots JSON normalizados e faça o gerador de relatórios consumir apenas esses snapshots. Essa separação transforma a bagunça das APIs específicas de cada fornecedor em um sistema que um agente consegue construir.
O agente deve construir a mesma classe de conexões, sem depender dos meus caminhos locais exatos:
- Garmin para cardio, carga de treino, pace, zonas de frequência cardíaca e detalhes da atividade
- WHOOP para recuperação, VFC, FCR, sono, strain e contexto de prontidão
- Speediance para histórico de sessões de força, volume, calorias, templates e detalhes dos exercícios
- Cronometer para contexto de nutrição
- 8Sleep para dados tardios de sono quando disponíveis
- OpenClaw como a camada de orquestração que executa as sincronizações, normaliza os dados e gera os relatórios
Também aborda os projetos no GitHub, APIs públicas, contratos de dados, modos de falha e verificações de aceitação que um agente de implementação precisa para entregar uma stack funcional sem ver meu repositório privado.
1. Tarefa do agente
Construa uma stack local-first de relatórios de fitness em OpenClaw que consiga se conectar aos sistemas, normalizar os dados deles e gerar relatórios sem chamadas ao vivo aos fornecedores durante a renderização.
O agente deve produzir:
- Scripts de conector
Um job de sincronização por sistema: Garmin, WHOOP, Speediance, Cronometer e 8Sleep quando configurado. - Snapshots brutos
Payloads com data, em JSON bruto ou derivados de CSV, para depurar mudanças dos fornecedores. - Contratos normalizados
Arquivos JSON estáveis nos quais o gerador de relatórios pode confiar mesmo quando os payloads dos fornecedores mudam. - Relatório matinal
Um relatório que combina recuperação, sono, prontidão, carga de treino, nutrição e o plano do dia. - Snapshot de treino adaptativo
Um plano datado de Speediance/BJJ/corrida derivado da prontidão do dia e da carga recente. - Relatório noturno
Uma revisão plano vs. realizado, comparando o que foi recomendado com a realidade de Garmin, WHOOP e Speediance. - Saída publicável
HTML estático e JSON legível por máquina que possa ser implantado no GitHub Pages ou em outro host estático.
Não construa isso como "um único script que chama seis APIs e renderiza HTML ao vivo". Isso é frágil.
2. Arquitetura que o agente deve implementar
Construa em quatro camadas:
- Camada de conectores
Um job de sincronização por plataforma.
Camada de dados normalizada
Cada sincronização grava snapshots JSON estáveis.
3. Camada de análise/relatórios
O código de relatório lê apenas JSON normalizado.
4. Camada de apresentação
HTML, dashboards, briefings diários, posts no Telegram, resumos de voz.
Essa separação é o que torna o sistema mantível.
Contrato de implementação de IA
Agente, construa este contrato antes de escrever qualquer UI de dashboard:
- Entradas: apenas variáveis de ambiente e credenciais de fornecedores; nunca codifique segredos diretamente em arquivos de código-fonte.
- Saídas de sincronização: um snapshot JSON bruto por pull de fornecedor, mais um arquivo JSON normalizado por fornecedor.
- Entradas de relatório: apenas JSON normalizado. O construtor de relatórios não deve chamar Garmin, WHOOP, Speediance, ou Cronometer diretamente.
- Modo de falha: se um conector falhar, preserve o arquivo normalizado do último estado válido conhecido de ontem e marque essa fonte como desatualizada no relatório.
- Auditabilidade: mantenha payloads brutos suficientes para depurar mudanças na API do fornecedor sem registrar tokens, cookies, senhas ou cabeçalhos privados.
- Gate de envio: e-mail, voz, Telegram e ações de treino adaptativo devem exigir dados de recuperação pontuados do mesmo dia. Um relatório web ainda pode ser gerado em modo degradado, mas o sistema não deve enviar coaching confiante a partir de recuperação desatualizada.
- Snapshots de plano: planos de treino adaptativo devem ser escritos como snapshots JSON diários antes de serem enviados para qualquer lugar. O relatório noturno pode então comparar o plano com o que realmente aconteceu.
Variáveis de ambiente mínimas para um build pronto para o agente:
GARMIN_EMAIL=
GARMIN_PASSWORD=
WHOOP_CLIENT_ID=
WHOOP_CLIENT_SECRET=
WHOOP_ACCESS_TOKEN=
WHOOP_REFRESH_TOKEN=
SPEEDIANCE_USER_ID=
SPEEDIANCE_TOKEN=
SPEEDIANCE_REGION=Global
CRONOMETER_EXPORT_PATH=
EIGHTSLEEP_EMAIL=
EIGHTSLEEP_PASSWORD=
3. Definição de pronto
Um agente de implementação só está pronto quando esses artefatos existem e podem ser regenerados:
data/garmin/summary/latest.jsondata/whoop/normalized/latest.jsondata/speediance/normalized/history.jsondata/speediance/normalized/by_exercise.jsondata/nutrition/latest.jsondata/eightsleep/normalized/latest.json, se 8Sleep estiver configuradodata/training_plans/YYYY-MM-DD_morning.jsonreports/morning/latest.htmlreports/nightly/latest.html- um gate de envio que retenha envios de e-mail, voz, Telegram e treino adaptativo quando a recuperação WHOOP pontuada do mesmo dia estiver ausente
- avisos de fonte desatualizada quando um conector falha, mas os dados normalizados do último estado válido conhecido de ontem estão disponíveis
- uma verificação de ausência de segredos provando que tokens, cookies, senhas e cabeçalhos privados não foram commitados
Se o agente não conseguir autenticar em um fornecedor durante o desenvolvimento, ele ainda deve implementar a interface do conector, .env.example, fixtures falsos, normalizador, tratamento de fontes obsoletas e integração de relatórios.
4. Projetos públicos e referências de código-fonte
Estas são as peças públicas que um agente deve usar como referências de implementação.
Checklist rápido de GitHub/API:
- Garmin connector:
https://github.com/cyberjunky/python-garminconnect - Garmin legacy auth context:
https://github.com/matin/garth - WHOOP official developer API:
https://developer.whoop.com/api - Speediance public extraction for this build:
https://github.com/clawdassistant85-netizen/speediance-smartgym-workout-manager - Speediance working fork this was extracted from:
https://github.com/ANPC86/SmartGymWorkoutManager - Speediance upstream/original reference:
https://github.com/hbui3/UnofficialSpeedianceWorkoutManager - Report generator/template reference:
https://github.com/tobyglenn/scriptsJinja - Cronometer exports/integrations:
https://cronometer.com/
OpenClaw
- Plataforma/orquestrador: OpenClaw
- Papel: agendar jobs de sincronização, executar transformações, gerar relatórios, publicar saídas
Garmin
- Cliente Python principal: cyberjunky/python-garminconnect
GitHub:https://github.com/cyberjunky/python-garminconnect - Biblioteca de autenticação legada que antes era relevante: matin/garth
GitHub:https://github.com/matin/garth - Nota de status:
garthestá deprecated;python-garminconnectagora usa fluxos de autenticação Garmin mais recentes e é nele que se deve construir.
WHOOP
- Documentação oficial da API de desenvolvedor:
https://developer.whoop.com/api - Superfície pública da API: endpoints OAuth2 + REST para recovery, cycles, sleep, workouts, profile, body measurements
- Wrappers opcionais da comunidade existem, mas um conector construído pelo agente deve se ancorar na API oficial de desenvolvedor WHOOP sempre que possível.
Speediance
- Referência prática de implementação pública de Speediance: ANPC86/SmartGymWorkoutManager
GitHub:https://github.com/ANPC86/SmartGymWorkoutManager - Linhagem do projeto upstream / referência pública original: hbui3/UnofficialSpeedianceWorkoutManager
GitHub:https://github.com/hbui3/UnofficialSpeedianceWorkoutManager - Use o fork ANPC86 SmartGymWorkoutManager como referência prática de conexão porque ele contém trabalho útil em torno de histórico, exports, debugging de API, tratamento de timezone e tratamento de unidades.
- Esta é uma integração não oficial de Speediance e deve ser tratada como instável por padrão.
Nutrição
- Site do produto Cronometer / exports / integrações:
https://cronometer.com/ - Trate o Cronometer como uma fonte estruturada de export de nutrição, não como uma dependência mágica direta para relatórios.
5. Atualizações de produção que o agente deve preservar
A versão atual deste stack tem alguns comportamentos importantes que o agente deve preservar.
Máquina única proprietária
O pipeline de fitness deve ter uma máquina autoritativa sempre ligada. Não deixe dois computadores diferentes gerar e deployar relatórios contra o mesmo repositório de saída.
A máquina ativa é responsável pelos jobs de sincronização com fornecedores, geração de relatórios, geração adaptativa de treinos, deploy no GitHub Pages e verificações de watchdog.
Outras máquinas podem visualizar os relatórios ou hospedar dashboards locais, mas não devem regenerar os relatórios de fitness.
Pipeline sequencial em vez de chutes com cron escalonados
Os pipelines matinal e noturno devem rodar como fases ordenadas:
- sincronizar dados dos fornecedores
- verificar dados obrigatórios do mesmo dia
- gerar relatórios
- fazer deploy
- enviar notificações
- gerar resumos em voz, se utilizados
- executar validação do watchdog
O erro antigo é agendar essas etapas com offsets fixos de relógio e torcer para que cada fase anterior tivesse terminado. O padrão melhor é um orquestrador que executa cada fase somente depois que a anterior termina de forma limpa.
Gate de recuperação do WHOOP no mesmo dia
Para esta stack, a recuperação do WHOOP no mesmo dia é um gate obrigatório para o coaching. Se a recuperação de hoje estiver ausente, o sistema ainda pode publicar um relatório web com avisos de fonte desatualizada, mas deve reter os envios de email, voz, coaching pelo Telegram e treinos adaptativos.
Essa única regra evita o pior modo de falha: uma recomendação plausível construída a partir da recuperação de ontem.
Tratamento de dados atrasados do 8Sleep
O 8Sleep pode atualizar depois da primeira execução matinal. Uma reexecução deve forçar a atualização de hoje e de ontem antes de regenerar, em vez de confiar em um arquivo JSON local existente só porque ele existe.
Apenas zonas de FC reais do Garmin
Não invente distribuições de zonas de frequência cardíaca a partir da frequência cardíaca média. Se o detalhe da atividade do Garmin incluir dados de tempo na zona, use-os. Se não incluir, oculte esse gráfico ou marque-o como indisponível.
Revisão da execução do plano
O relatório noturno agora funciona melhor quando compara o plano do dia com os dados reais do dia:
- treino de BJJ planejado vs treino de BJJ do WHOOP
- sessão de Speediance planejada vs sessões de Speediance concluídas
- corrida planejada vs distância de corrida do Garmin
- passos planejados vs passos do Garmin
Isso transforma o relatório noturno em um loop de feedback, em vez de apenas um resumo.
Modo sombra do Open Wearables
O Open Wearables é útil como uma futura camada de abstração, mas eu não trocaria de uma vez um sistema pessoal de relatórios que já funciona. A migração mais segura é o modo sombra:
- manter o pipeline baseado em arquivos existente como autoritativo
- importar ou espelhar dados de Garmin/WHOOP no Open Wearables
- exportar os dados do Open Wearables de volta para arquivos JSON sombra
- comparar os arquivos sombra com os arquivos de produção
- promover somente depois que contagens, datas e registros do mesmo dia coincidirem
Os arquivos sombra nunca devem sobrescrever as entradas de produção durante o piloto.
6. Garmin: a camada de cardio e detalhes de atividade
Se WHOOP responde "quão recuperado estou?", Garmin responde "o que exatamente eu fiz?"
Garmin é onde o relatório obtém:
- distância
- pace e velocidade
- duração
- FC média e máxima
- zonas de frequência cardíaca
- cadência
- potência
- efeito de treino
- metadados da atividade
- detalhes mais amplos de cardio/treino que WHOOP não enfatiza tão fortemente
Repositório público para usar
Recomendado: cyberjunky/python-garminconnect
GitHub:
https://github.com/cyberjunky/python-garminconnect
Por que isso importa:
- está ativamente posicionado como o wrapper Python do Garmin Connect a ser usado
- expõe uma superfície muito ampla de endpoints do Garmin
- inclui exemplos e padrões de tratamento de tokens
- substituiu suposições de autenticação mais antigas que quebravam em mudanças anteriores do Garmin
Nota importante de compatibilidade com Garmin
Historicamente, muitas builds usavam garth.
GitHub:
https://github.com/matin/garth
Mas garth agora está explicitamente descontinuado. Isso importa porque um agente não deve centralizar uma nova implementação em autenticação descontinuada.
Exemplo mínimo executável de Garmin
from garminconnect import Garmin
from datetime import date
from pathlib import Path
import json
import os
email = os.environ["GARMIN_EMAIL"]
password = os.environ["GARMIN_PASSWORD"]
client = Garmin(email=email, password=password)
client.login()
today = date.today().isoformat()
stats = client.get_stats(today)
activities = client.get_activities_by_date(today, today)
payload = {
"date": today,
"stats": stats,
"activities": activities,
}
out = Path("data/garmin/raw")
out.mkdir(parents=True, exist_ok=True)
(out / f"{today}.json").write_text(json.dumps(payload, indent=2))
O que normalizar a partir de Garmin
Não despeje payloads brutos de Garmin diretamente na lógica do seu relatório final. Normalize-os primeiro em campos como:
calendarDatetotalStepsrestingHeartRatesleepingSecondsbodyBatteryactivityNameactivityTypedurationSecondsdistanceMetersdistanceMilesaverageHRmaxHRcaloriestrainingEffectcadencepower
Padrão de armazenamento recomendado
data/garmin/raw/YYYY-MM-DD.jsondata/garmin/normalized/YYYY-MM-DD.jsondata/garmin/summary/latest.json
Isso oferece tanto capacidade de reprodução quanto acesso rápido ao relatório.
7. WHOOP: a camada de recuperação e prontidão
WHOOP é o que torna os relatórios úteis como um motor de decisão, em vez de apenas um registro de atividades.
Ele contribui com:
- score de recuperação
- HRV
- frequência cardíaca em repouso
- desempenho do sono
- strain
- contexto de ciclo
- enquadramento de prontidão para recomendações matinais e noturnas
API pública a ser usada
Use a API oficial para desenvolvedores do WHOOP:
- Documentação:
https://developer.whoop.com/api
Grupos de endpoints relevantes:
/developer/v2/cycle/developer/v2/recovery/developer/v2/activity/sleep/developer/v2/activity/workout/developer/v2/user/profile/basic/developer/v2/user/measurement/body
Limitação crítica
Uma das constatações de implementação mais importantes: os dados de diário não estão disponíveis na API do WHOOP.
Se você quer respostas de diário ou anotações de hábitos, não dá para contar com um endpoint público da API do WHOOP para isso. As opções práticas são:
- exportação manual de CSV a partir do WHOOP
- sua própria camada paralela de diário
- metadados separados que você anexa após a sincronização
Essa limitação precisa ser declarada de forma clara no artigo porque afeta qualquer implementação séria.
Exemplo mínimo executável com WHOOP
from pathlib import Path
import json
import os
import requests
BASE = "https://api.prod.whoop.com/developer/v2"
TOKEN = os.environ["WHOOP_ACCESS_TOKEN"]
headers = {"Authorization": f"Bearer {TOKEN}"}
def get(path):
response = requests.get(f"{BASE}{path}", headers=headers, timeout=30)
response.raise_for_status()
return response.json()
payload = {
"recovery": get("/recovery"),
"sleep": get("/activity/sleep"),
"workouts": get("/activity/workout"),
}
out = Path("data/whoop/raw")
out.mkdir(parents=True, exist_ok=True)
(out / "latest.json").write_text(json.dumps(payload, indent=2))
O que normalizar a partir do WHOOP
Normalize em campos como:
recovery_scorehrv_rmssd_milliresting_heart_ratespo2_percentageskin_temp_celsiussleep_performance_percentagerespiratory_ratestraincycle_startcycle_endworkout_sport_name
Padrão de armazenamento recomendado
data/whoop/raw/recovery.jsondata/whoop/raw/sleep.jsondata/whoop/raw/workouts.jsondata/whoop/normalized/latest.json
8. Speediance: a camada de musculação
Speediance é o conector mais incomum de toda a stack.
Diferente do Garmin e do WHOOP, este não é uma plataforma oficial pública e bem estruturada para desenvolvedores. O agente deve usar estes repositórios públicos como referências de conexão:
Extração/referência pública: https://github.com/clawdassistant85-netizen/speediance-smartgym-workout-manager
ANPC86/SmartGymWorkoutManager
GitHub: https://github.com/ANPC86/SmartGymWorkoutManager
Esse repositório é, por si só, um fork pessoal / continuação do projeto público original do Speediance:
hbui3/UnofficialSpeedianceWorkoutManager
GitHub: https://github.com/hbui3/UnofficialSpeedianceWorkoutManager
Esses repositórios são o ponto de partida importante porque mostram como:
- se autenticar nos endpoints do Speediance
- inspecionar dados de treino e respostas da API
- navegar/exportar o histórico de treinos
- gerenciar templates/treinos de forma amigável para desktop
- lidar com questões práticas como exibição de fuso horário e tratamento de pesos em imperial/métrico
Por que esses repositórios importam
Use o fork ANPC86 SmartGymWorkoutManager como base prática para o padrão de integração Speediance, preservando a referência upstream hbui3 para fins de procedência. Juntos, eles são as referências públicas mais claras para trabalhar com dados do Speediance fora do aplicativo oficial.
Aviso de estabilidade
O projeto original observa que o Speediance vem implementando atualizações de segurança. Isso significa que:
- esta integração pode quebrar
- cabeçalhos e comportamento de autenticação podem mudar
- endpoints podem mudar
- você deve isolar este conector atrás de uma etapa de normalização para que seus relatórios sobrevivam às mudanças do lado do fornecedor
Padrão executável mínimo para Speediance
Se você usar ANPC86/SmartGymWorkoutManager como ponto de partida, conferindo o upstream hbui3/UnofficialSpeedianceWorkoutManager para o contexto original, a abordagem limpa é:
- Execute o app ou a camada cliente localmente
- Faça autenticação com sua conta Speediance
- Extraia o histórico de treinos a partir dos métodos de API que ele expõe
- Exporte o JSON normalizado para o seu próprio diretório de dados
Pseudo-exemplo usando esse padrão de cliente:
# Modele isso em torno do api_client.py em:
# https://github.com/clawdassistant85-netizen/speediance-smartgym-workout-manager
from api_client import SpeedianceClient
from datetime import date
from pathlib import Path
import json
import os
client = SpeedianceClient()
success, msg, debug = client.login(
os.environ["SPEEDIANCE_USER_ID"],
os.environ["SPEEDIANCE_TOKEN"],
)
if not success:
raise RuntimeError(msg)
start_date = os.environ.get("SPEEDIANCE_START_DATE", "2026-01-01")
end_date = date.today().isoformat()
records = client.get_training_data(start_date, end_date)
out = Path("data/speediance/raw")
out.mkdir(parents=True, exist_ok=True)
(out / "history.json").write_text(json.dumps(records, indent=2))
O que normalizar a partir do Speediance
Normalize em campos como:
training_iddatetitleduration_secondscaloriestotal_volumeexercise_counttemplate_nameplanned_durationactual_durationexercise_breakdownestimated_1rm
Modelo de dados de melhor prática
Para um sistema de relatórios sério, mantenha dois índices:
- bySession
- um registro por treino concluído
- byExercise
- um fluxo de registros por nome de movimento
- inclui peso, repetições, lado, id da sessão, timestamp
Essa estrutura torna gráficos de progressão e detecção de PRs triviais depois.
Padrão de armazenamento recomendado
data/speediance/raw/monthly/YYYY-MM.jsondata/speediance/normalized/history.jsondata/speediance/normalized/by_exercise.jsondata/speediance/dashboard/latest.json
Snapshots adaptativos de treinos do Speediance
A versão mais avançada desta build não lê apenas treinos concluídos do Speediance.
Ele também cria treinos planejados a partir de dados de prontidão em tempo real.
O padrão útil é:
- Carregar recuperação WHOOP do mesmo dia, strain atual, strain BJJ, body battery Garmin, FC de repouso, carga de corrida recente, clima e histórico recente do plano Speediance.
- Classificar o dia em uma categoria como
build,maintain,recover,protectoupost_bjj_brutal. - Selecionar um implemento Speediance para o treino inteiro, geralmente alças, barra ou corda.
- Escolher apenas exercícios no aparelho para o treino núcleo de Speediance.
- Adicionar de zero a dois acessórios off-Speediance somente quando a recuperação permitir.
- Escrever o plano em
data/training_plans/YYYY-MM-DD_context.json. - Usar o snapshot tanto para a recomendação da manhã quanto para a revisão noturna da execução do plano.
Para controle de repetição, compare a assinatura do novo treino com snapshots de planos recentes. A versão de produção usa uma janela de unicidade rolante que cresce até 30 dias e sempre carimba o título do treino com a data de hoje, para que um treino que reapareça ainda esteja atualizado e pesquisável.
9. Cronometer: a camada de contexto de nutrição
Independentemente do aplicativo de nutrição exato que você usa, o papel é o mesmo: dar ao relatório contexto sobre a ingestão de energia.
Isso importa porque carga de treino sem contexto de nutrição leva a conclusões ruins.
O relatório deve ser capaz de perguntar:
- A recuperação estava baixa porque a carga de treino estava alta?
- Ou porque o sono foi ruim e a ingestão calórica foi baixa?
- O atleta estava subalimentado em relação à produção?
Conselho prático de implementação
Não dependa de uma API de nutrição em tempo real no momento da renderização. Use uma das opções:
- Exportação CSV
- Ingestão por webhook
- Sincronização agendada para JSON normalizado
Normalize em campos como:
calories_consumedprotein_gcarbs_gfat_gfiber_gtarget_caloriesestimated_deficit
Padrão de armazenamento recomendado
data/nutrition/raw/YYYY-MM-DD.csvdata/nutrition/normalized/YYYY-MM-DD.jsondata/nutrition/latest.json
10. 8Sleep: a camada de contexto de sono que chega atrasada
8Sleep é opcional, mas se estiver configurado, o agente deve tratá-lo como qualquer outro conector: sincronizar primeiro, normalizar em segundo, renderizar a partir dos arquivos por último.
O comportamento importante é o tratamento de dados atrasados. Os dados de sono podem mudar após a primeira execução da manhã, então uma reexecução manual ou uma retentativa agendada deve forçar a atualização tanto de hoje quanto de ontem antes de regenerar o relatório.
Normalize campos como:
sleep_scoresleep_startsleep_endtime_in_bed_secondstime_asleep_secondshrvresting_heart_ratetemperature_adjustmentsaway_mode
Padrão de armazenamento recomendado:
data/eightsleep/raw/YYYY-MM-DD.jsondata/eightsleep/normalized/YYYY-MM-DD.jsondata/eightsleep/normalized/latest.json
11.
O que o OpenClaw realmente faz neste stack
O OpenClaw não é a fonte de dados. Ele é a camada de orquestração e raciocínio.
A função dele é:
- executar jobs de sincronização conforme o agendamento
- armazenar saídas estáveis
- comparar fontes
- gerar o HTML do relatório
- publicar links
- produzir resumos amigáveis a partir dos dados normalizados
Isso significa que o código de geração de relatórios deve ler de arquivos como:
data/garmin/summary/latest.jsondata/whoop/normalized/latest.jsondata/speediance/normalized/history.jsondata/nutrition/latest.jsondata/eightsleep/normalized/latest.json
O gerador de relatórios nunca deve precisar saber como funciona a autenticação do Garmin ou como os cabeçalhos do Speediance mudaram nesta semana.
12. Estrutura de diretórios construível por agente
Aqui está uma estrutura que um agente pode criar antes que qualquer autenticação real de fornecedor seja bem-sucedida:
project/
data/
garmin/
raw/
normalized/
summary/
whoop/
raw/
normalized/
speediance/
raw/
normalized/
dashboard/
nutrition/
raw/
normalized/
eightsleep/
raw/
normalized/
training_plans/
scripts/
sync_garmin.py
sync_whoop.py
sync_speediance.py
sync_nutrition.py
sync_eightsleep.py
gate_same_day_recovery.py
build_adaptive_plan.py
build_report.py
reports/
morning/
latest.html
nightly/
latest.html
frontend/
data/
A estrutura de arquivos faz parte da interface. Mantenha-a simples o suficiente para que um agente futuro consiga inspecionar o sistema, localizar cada conector, executar novamente uma única sincronização e comparar os payloads brutos com as saídas normalizadas.
13. Exemplo de padrão de construtor de relatório
Quando cada conector grava JSON normalizado, o código real do relatório se torna simples.
import json
from pathlib import Path
base = Path("data")
garmin = json.loads((base / "garmin/summary/latest.json").read_text())
whoop = json.loads((base / "whoop/normalized/latest.json").read_text())
speediance = json.loads((base / "speediance/normalized/history.json").read_text())
nutrition = json.loads((base / "nutrition/latest.json").read_text())
eightsleep_path = base / "eightsleep/normalized/latest.json"
eightsleep = json.loads(eightsleep_path.read_text()) if eightsleep_path.exists() else {}
summary = {
"recovery": whoop.get("recovery_score"),
"hrv": whoop.get("hrv_rmssd_milli"),
"rhr": whoop.get("resting_heart_rate"),
"steps": garmin.get("totalSteps"),
"body_battery": garmin.get("bodyBattery"),
"lifting_volume": speediance.get("today", {}).get("total_volume"),
"calories_in": nutrition.get("calories_consumed"),
"sleep_score": eightsleep.get("sleep_score"),
}
html = f"""
<html>
<body>
<h1>Relatório Diário de Fitness</h1>
<ul>
<li>Recuperação: {summary['recovery']}</li>
<li>HRV: {summary['hrv']}</li>
<li>RHR: {summary['rhr']}</li>
<li>Passos: {summary['steps']}</li>
<li>Body Battery: {summary['body_battery']}</li>
<li>Volume de Musculação: {summary['lifting_volume']}</li>
<li>Calorias Consumidas: {summary['calories_in']}</li>
<li>8Sleep Pontuação: {summary['sleep_score']}</li>
</ul>
</body>
</html>
"""
out = Path("reports/morning")
out.mkdir(parents=True, exist_ok=True)
(out / "latest.html").write_text(html)
É aqui que todo o design compensa: uma vez que a camada de sincronização está consistente, a camada de relatório fica monótona da melhor maneira possível.
14. Para que cada conector realmente serve
Este é o modelo mental mais simples:
WHOOP
Usar para:
- recuperação
- HRV
- RHR
- desempenho do sono
- strain
- enquadramento de prontidão
Garmin
Usar para:
- detalhes de corrida e cardio
- pace, potência, cadência
- zonas de FC
- efeito de treino
- histórico detalhado de atividades
Speediance
Usar para:
- histórico de treinos de força
- volume total
- detalhe de exercícios
- execução planejada vs. real da sessão
- progressão em nível de movimento se você construir indexação por exercício
Aplicativo de nutrição
Usar para:
- ingestão calórica
- contexto de macronutrientes
- detecção de subalimentação
8Sleep
Usar para:
- detalhes do sono que chegam atrasados
- duração e pontuação do sono específicas da cama
- verificações cruzadas do contexto do sono contra WHOOP e Garmin
OpenClaw então combina todos eles em uma única superfície de relatório e recomendação.
15. Entregáveis de conexão por sistema
Este é o checklist que o agente de implementação deve satisfazer antes de polir a interface do relatório.
Pontos de conexão Garmin
- Biblioteca:
garminconnectdecyberjunky/python-garminconnect - Autenticação: e-mail/senha do Garmin Connect com o tratamento de token/sessão da biblioteca
- Cadência de pull: sincronização diária pela manhã mais sincronização opcional pós-treino
- Pulls mínimos:
- estatísticas diárias de passos, FC em repouso, segundos de sono, body battery, calorias
- atividades por data para sessões de corrida/ciclismo/cardio
- detalhes da atividade quando disponível para zonas de FC, pace, cadência, potência, efeito de treino
- Saída normalizada:
data/garmin/summary/latest.json
Pontos de conexão WHOOP
- Documentação da API:
https://developer.whoop.com/api - Autenticação: fluxo de token de acesso OAuth2 + refresh token
- URL base:
https://api.prod.whoop.com/developer/v2 - Grupos mínimos de endpoints:
/cyclepara contexto de strain/ciclo/recoverypara score de recuperação, HRV, FC em repouso/activity/sleeppara desempenho e tempo de sono/activity/workoutpara treinos e dados de strain WHOOP/user/profile/basice/user/measurement/bodypara contexto de perfil/corpo quando necessário
- Saída normalizada:
data/whoop/normalized/latest.json
Pontos de conexão Speediance
- Extração pública para esta build:
https://github.com/clawdassistant85-netizen/speediance-smartgym-workout-manager - Referência upstream:
https://github.com/hbui3/UnofficialSpeedianceWorkoutManager - Autenticação: fluxo não oficial baseado em token/user-id exposto pela camada cliente SmartGym
- Coletas mínimas:
- histórico de treinos
- detalhes de exercício/sessão
- metadados de treino/modelo personalizado se você quiser relatórios planejado vs real
- captura de resposta bruta de API/debug sem segredos
- Saídas normalizadas:
data/speediance/normalized/history.jsondata/speediance/normalized/by_exercise.json
Pontos de conexão Cronometer
- Fonte pública: exports/integrations
https://cronometer.com/ - Abordagem de implementação recomendada: export CSV ou drop de arquivo agendado, não uma dependência de API em tempo de renderização ao vivo
- Campos mínimos: data, calorias, proteína, carboidratos, gordura, fibra e quaisquer micronutrientes que você queira na análise de recuperação
- Saída normalizada:
data/nutrition/latest.json
Pontos de conexão 8Sleep
- Autenticação: fluxo de login/sessão apoiado por variáveis de ambiente, sem credenciais no código-fonte
- Cadência de coleta: sincronização matinal mais suporte a rerun/refresh para hoje e ontem
- Coletas mínimas:
- score de sono
- tempo de sono
- tempo dormindo e tempo na cama
- HRV e FC em repouso quando disponíveis
- contexto de temperatura e away-mode quando disponíveis
- Saída normalizada:
data/eightsleep/normalized/latest.json
Ponto de conexão para geração de relatório
O gerador de relatórios deve ler apenas arquivos normalizados estáveis e snapshots de planos. Um formato prático é:
data/garmin/summary/latest.json
data/whoop/normalized/latest.json
data/speediance/normalized/history.json
data/speediance/normalized/by_exercise.json
data/nutrition/latest.json
data/eightsleep/normalized/latest.json
data/training_plans/YYYY-MM-DD_morning.json
data/training_plans/YYYY-MM-DD_post_bjj.json
Essa é a superfície de conexão real. Tudo upstream pode quebrar e ser corrigido de forma independente.
16. As regras reais de implementação
Se um agente vai construir isso com sucesso, essas regras importam mais do que qualquer trecho de código isolado:
Normalize cada fornecedor em seu próprio schema
Nunca deixe um relatório depender do formato de payload do fornecedor.Mantenha snapshots brutos
Quando uma sincronização quebra, payloads brutos salvam você.
Never render from live APIs if the report is time-sensitive
Sync first, render second.
Treat unofficial integrations as disposable adapters
Especially Speediance.Make Garmin and WHOOP complement each other, not compete
WHOOP = readiness. Garmin = execution detail.Model strength data at both session and exercise level
Otherwise progression reporting stays shallow.Gate coaching on today's readiness, not yesterday's
Missing same-day recovery should degrade the system to web-only reporting.Save the plan before judging the day
A nightly adherence score only works if the morning or post-BJJ plan was stored as data.Pilot new backends in shadow mode
Open Wearables or any other abstraction layer should prove it can match current production files before it becomes the source of truth.
Lista de referência final de implementação
Estas são as referências públicas que um agente de codificação de IA deve receber primeiro ao implementar este sistema:
- OpenClaw como a camada de orquestração
- Conector Garmin:
https://github.com/cyberjunky/python-garminconnect - Contexto histórico de autenticação Garmin:
https://github.com/matin/garth(descontinuado; use como contexto, não como centro de uma nova construção) - API oficial de desenvolvedor WHOOP:
https://developer.whoop.com/api - Extração pública de Speediance para esta build:
https://github.com/clawdassistant85-netizen/speediance-smartgym-workout-manager - Referência upstream/original de Speediance:
https://github.com/hbui3/UnofficialSpeedianceWorkoutManager - Referência de gerador/modelo de relatório:
https://github.com/tobyglenn/scriptsJinja - Exportações de nutrição do Cronometer:
https://cronometer.com/ - Contrato do conector 8Sleep: sincronização apoiada por ambiente que grava
data/eightsleep/normalized/latest.json
Se você está entregando este artigo para Claude Code, Codex, OpenClaw, ou outro agente de implementação, a instrução correta é: construa os conectores primeiro, escreva os snapshots JSON normalizados em segundo lugar, imponha o gate de recuperação do mesmo dia em terceiro, e então construa o renderizador de relatório por último. Não comece projetando o relatório HTML final.