Pular para conteúdo

Conformidade LGPD

Este documento resume como o EnergIA trata dados pessoais à luz da Lei Geral de Proteção de Dados Pessoais (LGPD, Lei nº 13.709/2018), conforme exigido pelo briefing do Desafio 6. Dados de consumo energético residencial com granularidade de segundos/minutos permitem inferir hábitos domésticos (horários de presença, rotina de sono, uso de equipamentos) — por isso são tratados como dados pessoais sensíveis à privacidade, não apenas como métricas técnicas.


1. Minimização

O sistema coleta apenas o necessário para a gestão energética: tensão, corrente, potência ativa, fator de potência e energia acumulada (TelemetryReading), a cada 5 segundos. Não há coleta de localização geográfica precisa, dados biométricos, ou qualquer dado pessoal além do estritamente necessário ao cadastro (nome, e-mail, WhatsApp) e à operação do serviço.

A retenção também é limitada no tempo (seção 5) — dados não são guardados indefinidamente "só por precaução".

2. Finalidade

Os dados de consumo são usados exclusivamente para: - Exibir consumo, custo estimado e histórico ao próprio usuário (dashboard, app, WhatsApp). - Prever a fatura do ciclo corrente (analytics.BillForecast). - Identificar aparelhos de alto consumo (NILM) e recomendar horários de uso mais baratos (tarifa branca). - Alertar sobre anomalias de consumo e desconexões do medidor.

Não há venda, cessão ou compartilhamento de dados de consumo com terceiros. A API de clima (Open-Meteo) recebe apenas coordenadas geográficas aproximadas configuradas pelo operador do sistema (não por usuário) — nenhum dado pessoal do usuário trafega para esse serviço externo.

3. Transparência

  • A página de Perfil (/perfil/) exibe e permite editar todos os dados pessoais cadastrados (nome, e-mail, números de WhatsApp).
  • O consentimento para uso de dados no treinamento do classificador NILM (seção 4) é explícito, opt-in, e pode ser revogado a qualquer momento pelo próprio usuário, na mesma tela.
  • A seção "Meus Dados" da página de Perfil permite exportar (portabilidade) e excluir (esquecimento) os próprios dados a qualquer momento — ver seção 5.
  • Este documento, o Termos de Uso e o docs/nilm.md descrevem publicamente, no repositório do projeto, como os dados são processados e quais algoritmos são aplicados sobre eles.

4. Consentimento para treinamento de modelos (NILM)

O classificador de aparelhos (analytics/services.py::_classify_event) opera em três camadas (ver docs/nilm.md, seção 2). Apenas a Camada A (árvore de decisão treinada por medidor) constitui, em sentido estrito, "treinamento de modelo com dados do usuário" — as Camadas B e C são consulta direta ao próprio histórico do usuário e regras fixas, não aprendizado de máquina.

Por isso, a Camada A exige consentimento explícito, registrado em accounts.User.consented_nilm_training_at:

  • Opt-in via checkbox na página de Perfil ("Autorizo o uso dos meus aparelhos confirmados para treinar o classificador de identificação (NILM)").
  • Ausência de consentimento (None, o padrão de qualquer conta nova) faz a classificação pular direto para a Camada B — o sistema continua funcionando, só não treina o modelo de aprendizado de máquina com os dados daquele usuário.
  • O usuário pode revogar o consentimento a qualquer momento desmarcando a mesma opção; a revogação some com o timestamp de consentimento, e a próxima classificação já respeita o novo estado (não há re-treinamento retroativo a desfazer, pois o modelo é treinado sob demanda a cada classificação, não persistido).

Anonimização: os dados usados na Camada A (delta_w, duration_s, hour_of_day) já são, por natureza, agregados/derivados (degraus de potência), não a série bruta de leituras — não incluem nome, e-mail ou qualquer identificador direto do usuário além do vínculo interno ao medidor. Ainda assim, o treinamento ocorre isoladamente por medidor (nunca combinando dados de usuários diferentes no mesmo modelo), o que já limita a superfície de exposição sem exigir uma etapa adicional de anonimização.

5. Portabilidade, retenção e exclusão

5.1 Exportação e exclusão pelo próprio usuário (autoatendimento)

Na página de Perfil (/perfil/), seção "Meus Dados":

  • Exportar meus dados (accounts:data_export) — baixa um .json com os dados pessoais do próprio usuário logado: perfil, medidores, tarifas (com postos horários, quando branca), faturas enviadas (metadados — não inclui o arquivo PDF/imagem em si), aparelhos identificados, preferências de uso e de notificação, histórico de mensagens do assistente, e um resumo agregado de telemetria por medidor (quantidade de leituras e período coberto — não o dump bruto das leituras, que pode chegar a milhões de linhas a 1 leitura/5s). accounts/services.py::export_user_data.
  • Excluir minha conta (accounts:account_delete) — pede a senha atual como confirmação e, se correta, apaga a conta permanentemente. A exclusão cascateia via on_delete=CASCADE nas FKs de Meter, Tariff, AssistantMessage etc. para o User — apagar o usuário já remove todos os dados vinculados. Contas visualizadoras também podem excluir a própria conta (não afeta os dados do owner que elas visualizavam).

5.2 Retenção automática de dados históricos

Comando: python manage.py purge_old_data [--months 24] [--pending-days 90] [--dry-run]

Dado Janela padrão O que acontece após a janela
TelemetryReading (leituras brutas) 24 meses Removidas — o histórico de altíssima granularidade não precisa ser mantido indefinidamente
PowerStepEvent com status='pending' (nunca identificados pelo usuário) 90 dias Removidos — são ruído que o usuário optou por não classificar
PowerStepEvent com status='confirmed' ou 'auto' Nunca removidos por este comando — são a base de identificação de aparelhos e alimentam a Camada A/B do classificador

Recomenda-se agendar este comando periodicamente (ex.: cron mensal no servidor de produção) com --dry-run primeiro para conferir o volume antes de aplicar em definitivo.

6. Segurança

  • Em trânsito: MQTT via TLS (MQTTS, porta 8883, CERT_REQUIRED); tráfego web via HTTPS (nginx + Let's Encrypt em produção). Reforço de defesa em profundidade na própria aplicação Django (core/settings.py): SECURE_SSL_REDIRECT, SESSION_COOKIE_SECURE e CSRF_COOKIE_SECURE, habilitados via .env em produção (não dependem só do proxy reverso).
  • Em repouso: credenciais (banco, MQTT, APIs) nunca hardcoded — sempre via variáveis de ambiente (python-decouple) e .env fora do controle de versão.
  • Isolamento entre usuários: todo endpoint (web e REST API) filtra por owner efetivo (request.user.effective_owner) — nenhum usuário acessa dados de outro, incluindo contas visualizadoras somente-leitura (User.viewing). Ver seção 6.11 do PRD.md.
  • Autenticação: login por e-mail/senha (Django nativo) na web; token (DRF TokenAuthentication) na API REST.

7. Limitações declaradas (honestidade sobre a PoC)

Conforme o briefing do Desafio 6 recomenda declarar com clareza:

  • O comando de retenção (purge_old_data) precisa ser agendado manualmente (cron); não há agendamento automático embutido na aplicação nesta fase.
  • A anonimização dos dados de treino do NILM é estrutural (dados já agregados, isolados por medidor), não uma etapa de pseudonimização formal adicional — documentado como suficiente para o volume e escopo atual da PoC, não como conformidade plena para operação em escala com múltiplos usuários. A política de retenção (seção 5.2) atua por remoção, não por anonimização em si — suficiente para o critério "removidos ou anonimizados", mas registrado aqui por transparência.
  • A exportação de dados (seção 5.1) não inclui o dump bruto de TelemetryReading/PowerStepEvent (só um resumo agregado) nem o arquivo binário das faturas enviadas (BillUpload.bill_file) — decisão deliberada de escopo para evitar exports impraticavelmente grandes; esses dados continuam acessíveis pela própria interface do sistema enquanto a conta existir.