14

Como construí um dashboard de energia solar embutido na parede da minha casa

Moro numa casa off-grid no alto de uma montanha e trabalho remoto. Nesse cenário, monitorar o consumo de energia é necessidade constante: no verão os painéis solares recebem sol a partir das 6-7h da manhã, mas no inverno isso só acontece por volta das 9-10h. A decisão de "assistir mais um episódio antes de dormir" ou "guardar energia" é literalmente a diferença entre ter ou não energia elétrica para trabalhar nos próximos dias nublados.

Para tomar essa decisão eu precisava consultar o aplicativo da bateria e a previsão do tempo — dois aplicativos, várias telas e atenção dividida. Então construí um dashboard que consulta os dados da bateria e uma API de previsão do tempo e exibe tudo em um display embutido na parede:

Display embutido na parede mostrando a carga da bateria e a previsão do tempo

Neste write-up, conto o processo por trás do projeto: as limitações que guiaram cada decisão de arquitetura, as semanas de engenharia reversa para conseguir os dados da bateria e a solução para responder o "e amanhã, vai ter sol?".

Se quiser o contexto completo (o problema que motivou tudo isso), leia o post anterior no meu blog.

As limitações do cenário off-grid

A maior restrição do projeto pode ser resumida em uma frase: não tenho internet disponível 24 horas por dia. Essa é uma limitação derivada de não ter geração de energia constante — e é justamente o problema que este projeto busca quantificar e deixar visível.

Consequência direta: todo o sistema precisava funcionar com ou sem acesso à internet.

Onde comecei

Meu ponto de partida foi ver o que eu já tinha em mãos:

  • dados da bateria via aplicativo mobile do fabricante
  • APIs públicas de previsão do tempo
  • hardware barato e de baixo consumo de energia (um CYD — placa ESP32 com tela TFT de 2.8" soldada)

O primeiro problema: eu sempre usei o próprio roteador da Starlink. Com ela desligada, eu ficava não só sem internet, mas também sem rede nenhuma — os dispositivos não conseguiam nem se falar entre si.

A solução foi adicionar um roteador wifi simples (Intelbras), que funciona 24h por dia independente da Starlink. Ele disponibiliza uma rede exclusiva para a bateria e o display, e se conecta via cabo ethernet à Starlink para dar acesso à internet quando ela está online.

Os dados: o capítulo da engenharia reversa

Conseguir os dados da bateria foi um longo processo de exploração que levou algumas semanas. Eu sabia que deveria haver algum modo de acessá-los, afinal a bateria enviava os dados para o aplicativo do fabricante.

Na primeira exploração, identifiquei a bateria na rede, mas não encontrei nenhum serviço aberto no IP dela. Descompilei o aplicativo, fiz engenharia reversa, monitorando o tráfego da minha rede — dias de frustração e nenhum caminho à frente.

Esgotadas minhas ideias, decidi fazer o caminho inverso: pegar os dados do aplicativo em vez da bateria. Não era o que eu queria, pois eu só teria acesso aos dados com internet, mas não ia deixar o projeto travar antes de sair do papel. Com isso, implementei a v0: a tela mostrava o estado de carga da bateria e uma estimativa de carga/descarga.

Satisfeito com a vitória e usando o dashboard há algumas semanas, decidi fazer um segundo round de exploração. Afinal, não faz sentido acessar um servidor na China para ler os dados de um dispositivo que está a 20 metros de mim, na mesma rede local.

Depois de muita pesquisa e leitura de várias versões de manuais, encontrei uma funcionalidade escondida no aplicativo: ele consegue acessar os dados da bateria sem internet, conectando-se diretamente a ela na rede local. Descoberta promissora.

A partir daí, instalei aplicativos de monitoramento de rede no celular e gravei o tráfego enquanto usava o aplicativo da bateria. Rede não é meu forte, e analisar aqueles logs manualmente levaria muito tempo, com risco de deixar algo passar. Então usei o Claude Code para analisar os logs, informando quais ações eu tinha feito durante a gravação — e ele identificou exatamente quais requests traziam os dados que eu via no app. Com alguns scripts Python, passei a replicar essas requests sem depender do aplicativo.

Para quem tem uma bateria da Felicity ou quer entender o protocolo por baixo dos panos, documentei tudo no repositório do projeto.

Com isso, a v1 estava de pé: dados da bateria sem nenhuma dependência de internet.

Temos o hoje, mas e amanhã?

Com a situação atual resolvida, faltava responder: vai ter sol amanhã? Posso esbanjar ou preciso economizar?

Depois de comparar APIs, escolhi a Open-Meteo. Melhor que previsão do tempo, ela disponibiliza a previsão de radiação solar — uma métrica muito mais precisa para o meu problema do que "nublado", "sol" ou "chuva".

Aqui esbarrei de novo na limitação de internet, e também na do hardware do display. A solução mais simples seria o próprio display consultar a API, mas isso significaria implementar em C uma série de redundâncias e caches para falhas de internet ou da API. Optei por uma solução um pouco mais complexa, porém mais simples de manter:

  • um serviço em Go rodando na VPS busca os dados na Open-Meteo de hora em hora, aplica cache e cálculos, e sobrescreve um arquivo JSON estático
  • o serviço nunca fica exposto na internet: se a API retornar erro, ele simplesmente não faz nada — o próprio arquivo vira a camada de cache
  • o display faz uma requisição para esse arquivo: se der erro, continua mostrando os últimos dados que tinha; se voltar, compara a data e atualiza o que está na tela
  • para falhas de conexão não passarem despercebidas, a tela mostra há quantas horas foi a última atualização bem-sucedida

Detalhe da tela: carga, tensão, corrente, previsão de geração e histórico das últimas 24h

Instalação

Para simplificar, aproveitei uma tomada com adaptador USB: liguei os fios 220v na tomada e o CYD na saída USB, tudo em uma única peça. Removi as outras entradas da tomada, aumentei o buraco do espelho e embuti o CYD dentro da caixa — instalar ficou simples como instalar qualquer outra tomada.

Parte de trás do display: placa ESP32 com tela TFT integrada, encaixada na caixa

Interior da caixa embutida na parede, com a fonte e a fiação

O sistema completo

               wifi                      ethernet
Bateria Felicity <-----> Roteador Intelbras <-----> Starlink (internet)
       ^                      ^
       |                      |
       +---- wifi ------------+
                     |
                     v
            +--------------+
            |  CYD (tela)  |
            +--------------+
                     ^
                     | http (arquivo JSON)
                     |
Open-Meteo --https--> Serviço Go (VPS) --sobrescreve--> JSON estático

Componentes: bateria Felicity, roteador Intelbras, CYD (ESP32 + tela), serviço Go na VPS, API Open-Meteo, tomada USB.

Código do firmware e do serviço: github.com/marcosvpj/felicity-cyd

Conclusão

Não é porque moro off-grid, no alto de uma montanha, que não posso usar tecnologia para melhorar minha vida. A principal questão é entender as limitações vigentes e trabalhar com elas — e ao redor delas.

E isso serve para tudo: muitas vezes queremos fazer as coisas do melhor modo possível, com a melhor arquitetura possível, quando simplesmente disponibilizar um arquivo JSON estático já resolve.

Carregando publicação patrocinada...
2
2

Cara, que top. Primeira vez que vejo um conteudo desse em português.
Trabalho com solar, principalmente na area de monitoramento, e tambem sei, é um saco pegar esses dados, no seu caso, você pega da bateria, off-grid, nunca fiz isso, pois pego do inversor.
Consegui identificar da boa parte das marcas, mas ainda bem que algumas tem APIs bem documentadas.

1

Ja comecei a mapear os dados do inversor pra pegar de la também, ai assim terei os dados da carga e do consumo. Mas meu inversor só disponibiliza isso via RS485, e pra isso preciso fazer um hardware específico. Mas ta nos planos ampliar pra pegar eles também.

1

Meus 2 cents,

Parabens pela iniciativa !

Apesar de nao precisar com urgencia (energia da concessionaria), estou namorando por um projeto off-grid aqui em casa faz tempo (fazendo um bocado de contas e tentando convencer a esposa) e por conta disso achei teu projeto bem legal.

Repositorio devidamente starreado e forkeado - obrigado por compartilhar !

Saude e Sucesso !


Este post foi favoritado via extensão TABNEWS FAVORITOS

Tem curiosidade sobre IA ? Da uma olhada no meu LIVRO: IA PARA ENGENHEIROS

1

A decisão mais subestimada do teu write-up tá numa frase só: a tela mostra há quantas horas foi a última atualização bem-sucedida.

Dashboard que segue exibindo o último dado sem avisar que ele é velho é pior que tela apagada. Com a tela apagada você desconfia. Com o número de ontem em fonte grande, você assiste mais um episódio achando que tá olhando dado fresco.

Passei dois dias esses tempos com quatro agentes meus caídos por causa de uma aspas mal escapada dentro de um prompt. Nada apitou. O painel tava verde. O "sucesso" no log era só o processo tendo terminado sem reclamar.

Fiquei curioso: a tela separa "não consegui falar com a bateria" de "a previsão tá velha"? São dois defeitos com decisões opostas, porque previsão velha você compensa economizando, e bateria muda te deixa sem saber onde tá pisando.

-1

Que projeto sensacional! Esse é o verdadeiro espírito da engenharia: entender as restrições reais do ambiente e desenhar uma arquitetura simples, barata e à prova de falhas.
Quatro decisões que achei geniais no seu relato:
Desacoplar a rede local da Starlink: colocar um roteador dedicado para a bateria e o display conversarem 24/7 mesmo com a internet desligada é a definição prática de arquitetura Local-First.
A engenharia reversa do protocolo local: não aceitar depender de um servidor na China para ler os dados de uma bateria que está a 20 metros de você na mesma casa. Descobrir a chamada local e replicar direto no ESP32 eliminou o ponto único de falha.
Previsão de radiação solar em vez de "tempo": usar radiação solar da Open-Meteo é infinitamente mais assertivo para planejar carga de bateria do que previsão genérica de sol/chuva.
A simplicidade do JSON estático: em vez de criar um pipeline complexo com banco de dados e WebSockets, um serviço leve em Go sobrescrevendo um arquivo estático serviu como cache, fallback e persistência sem dor de cabeça no ESP32.
O acabamento embutindo o display CYD direto no espelho da tomada 220V deu um toque profissional de automação residencial. Parabéns pelo projeto, pelo write-up e por abrir o código no GitHub!