Monitorar tomadas inteligentes via MQTT é a forma mais barata de descobrir quanto cada aparelho da sua casa realmente custa para funcionar. Neste tutorial você vai conectar tomadas Tasmota e Shelly a um broker, normalizar seus payloads diferentes, armazenar as leituras em SQLite com um subscriber Python e gerar um gráfico de kWh diário por aparelho. A abordagem lida com reinicializações e zeramentos de contador, que é exatamente onde a maioria dos registradores de energia caseiros falha sem ninguém perceber.
Quais Tomadas Inteligentes Falam MQTT
Você precisa de uma tomada capaz de publicar em um broker escolhido por você, e não apenas na nuvem do fabricante. Três famílias cobrem a maior parte do mercado para esse fim:
| Família de tomada | Como o MQTT é ativado | Campos de energia | Observações |
|---|---|---|---|
| Tomadas com Tasmota (muitos modelos baseados em ESP) | Embutido no firmware Tasmota | ENERGY.Power (W), ENERGY.Total (kWh), Today, Yesterday |
Alguns modelos já vêm com Tasmota; outros precisam ser regravados |
| Shelly Plug S Gen3 / Plus Plug | Interface web local, Settings > MQTT | apower (W), aenergy.total (Wh) |
API JSON-RPC Gen2/Gen3 |
| Tomadas baseadas em ESPHome | Bloco mqtt: no YAML do ESPHome |
Um topic por sensor | Flexível, mas com topics por entidade |
Confira se a tomada tem medição de energia antes de comprar; muitas tomadas baratas apenas ligam e desligam. Verifique também a corrente nominal em relação ao aparelho, já que chaleiras, aquecedores e secadoras ficam perto do limite da maioria das tomadas.
Conectando uma Tomada Tasmota
Abra a interface web do Tasmota e vá em Configuration > Configure MQTT, ou use o console para uma configuração mais rápida. O comando Backlog aplica várias configurações de uma vez e reinicia a tomada:
Backlog MqttHost broker.connectmq.com; MqttPort 1883; MqttClient plug-kitchen-kettle-9f2; Topic kettle; FullTopic connectmq/demo/p4w8/%prefix%/%topic%/; TelePeriod 60
Com isso, a tomada publica sua telemetria a cada 60 segundos em connectmq/demo/p4w8/tele/kettle/SENSOR, com um payload como este:
{
"Time": "2026-10-16T07:31:12",
"ENERGY": {
"TotalStartTime": "2025-11-02T18:04:51",
"Total": 48.215,
"Yesterday": 0.412,
"Today": 0.197,
"Period": 3,
"Power": 0,
"ApparentPower": 0,
"ReactivePower": 0,
"Factor": 0.00,
"Voltage": 231,
"Current": 0.000
}
}
Total é a energia acumulada em kWh e Power é a potência ativa instantânea em watts. Use um segmento de caminho aleatório como p4w8, porque o servidor MQTT público é compartilhado e pode ser lido por todos; use-o só para testes, nunca para dados de produção. Os detalhes específicos do Tasmota, incluindo builds com TLS, estão no guia de Tasmota MQTT.
Conectando uma Tomada Shelly
Em uma Shelly Plus Plug ou Plug S Gen3, abra a interface web local, vá em Settings > MQTT, ative-o, defina o servidor como broker.connectmq.com:1883, o prefixo como connectmq/demo/p4w8/shelly/fridge e ative Generic status update over MQTT. A tomada passa então a publicar retratos completos em connectmq/demo/p4w8/shelly/fridge/status/switch:0, onde apower está em watts e aenergy.total é a energia acumulada em watt-hora, não em kWh. Confundir essas unidades é o bug mais comum ao combinar marcas. O guia de configuração do Shelly MQTT explica toda a estrutura de topics e RPC.
Projetando o Pipeline de Dados da Tomada Inteligente MQTT
Todas as tomadas já publicam no broker; o que falta é algo que escute e guarde o histórico. Brokers entregam mensagens ao vivo e valores retidos, mas não são bancos de dados, então o registrador é um cliente MQTT separado. O plano:
- Assinar os dois formatos de tomada com wildcards.
- Normalizar cada mensagem em
(time, plug, power_w, total_kwh). - Armazenar cada amostra no SQLite.
- Calcular a energia diária a partir da diferença entre totais acumulados consecutivos, ignorando saltos negativos causados por zeramento de contador.
- Plotar uma série de barras por tomada por dia.
Por que calcular a partir dos totais acumulados em vez de integrar a potência? Porque a potência é amostrada uma vez por minuto, e uma chaleira que funciona por 90 segundos entre duas amostras pode aparecer como zero. O contador de energia da própria tomada mede continuamente, então as diferenças do total são precisas mesmo com amostragem esparsa. Se uma mensagem se perder, a diferença seguinte simplesmente cobre um período maior.
O Registrador em Python
pip install "paho-mqtt>=2.0" matplotlib
import json
import sqlite3
import sys
from datetime import datetime
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/p4w8"
DB = sqlite3.connect("plugs.db", check_same_thread=False)
DB.execute("""CREATE TABLE IF NOT EXISTS samples (
ts TEXT, plug TEXT, power_w REAL, total_kwh REAL)""")
DB.commit()
def normalize(topic, payload):
parts = topic.split("/")
data = json.loads(payload)
if "/tele/" in topic and topic.endswith("/SENSOR"):
e = data.get("ENERGY")
if not e:
return None
return parts[-2], float(e["Power"]), float(e["Total"])
if "/shelly/" in topic and topic.endswith("/status/switch:0"):
if "aenergy" not in data:
return None
plug = parts[parts.index("shelly") + 1]
return plug, float(data.get("apower", 0)), float(data["aenergy"]["total"]) / 1000.0
return None
def on_connect(client, userdata, flags, reason_code, properties):
print("Connected:", reason_code)
client.subscribe(f"{PREFIX}/tele/+/SENSOR", qos=1)
client.subscribe(f"{PREFIX}/shelly/+/status/switch:0", qos=1)
def on_message(client, userdata, msg):
try:
row = normalize(msg.topic, msg.payload)
except (ValueError, KeyError) as exc:
print("Skipping", msg.topic, exc)
return
if row is None:
return
plug, power, total = row
DB.execute("INSERT INTO samples VALUES (?, ?, ?, ?)",
(datetime.now().isoformat(timespec="seconds"), plug, power, total))
DB.commit()
print(f"{plug:12s} {power:8.1f} W {total:10.3f} kWh")
def daily_kwh():
rows = DB.execute("SELECT ts, plug, total_kwh FROM samples ORDER BY plug, ts").fetchall()
result, last = {}, {}
for ts, plug, total in rows:
day = ts[:10]
prev = last.get(plug)
last[plug] = total
if prev is None:
continue
delta = total - prev
if delta < 0: # contador zerado ou tomada substituída: ignora este intervalo
continue
result.setdefault(plug, {}).setdefault(day, 0.0)
result[plug][day] += delta
return result
def plot():
import matplotlib.pyplot as plt
data = daily_kwh()
days = sorted({d for per in data.values() for d in per})
width = 0.8 / max(len(data), 1)
fig, ax = plt.subplots(figsize=(10, 5))
for i, (plug, per_day) in enumerate(sorted(data.items())):
xs = [n + i * width for n in range(len(days))]
ax.bar(xs, [per_day.get(d, 0) for d in days], width, label=plug)
ax.set_xticks([n + 0.4 - width / 2 for n in range(len(days))])
ax.set_xticklabels(days, rotation=45, ha="right")
ax.set_ylabel("kWh per day")
ax.legend()
fig.tight_layout()
fig.savefig("daily_kwh.png", dpi=120)
for plug, per_day in sorted(data.items()):
print(plug, {d: round(v, 3) for d, v in sorted(per_day.items())})
if __name__ == "__main__":
if sys.argv[1:] == ["plot"]:
plot()
else:
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="plug-logger-3391")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_forever()
Deixe python plug_logger.py rodando e, depois de um ou dois dias, execute python plug_logger.py plot para gerar daily_kwh.png e imprimir os números. Os dias são agrupados pelo horário local do registrador, que normalmente é o que você quer em relatórios domésticos.
Interpretando os Números
Depois de uma semana de dados, alguns padrões costumam se destacar:
- Consumo em standby. Televisores, consoles e equipamentos de rede que nunca caem abaixo de alguns watts somam bastante ao longo de um ano. Observe o
power_wmínimo por tomada, e não apenas o total diário. - Geladeiras e freezers mostram um ciclo de trabalho regular. Um total diário crescente com a mesma temperatura ambiente pode indicar uma borracha de vedação com defeito ou um condensador sujo.
- Cargas altas e curtas, como chaleiras e cafeteiras, quase não aparecem nas amostras de potência, mas o contador de energia as registra, o que valida o método das diferenças.
- Custo anual é o kWh diário multiplicado por 365 e pela sua tarifa. Calcule-o por tomada para saber qual mudança vale a pena.
Para uma visão da casa inteira para comparar, veja o tutorial de monitor de energia residencial com MQTT.
Transformando Dados da Tomada Inteligente MQTT em Alertas
O histórico mostra o que aconteceu; os alertas avisam enquanto ainda está acontecendo. Como todas as leituras já passam pelo broker, você pode adicionar alertas sem mexer nas tomadas:
- Freezer parado. Uma tomada de freezer informando menos de alguns watts por mais de uma hora geralmente indica um termostato desarmado ou uma porta aberta. As regras de alerta por limite do portal ConnectMQ podem monitorar um campo numérico em um topic, e um subscriber em Python ou Node-RED pode acrescentar a condição "por mais de uma hora".
- Aparelho esquecido. Um ferro, aquecedor ou chapinha consumindo energia por mais tempo que o normal é uma automação clássica de tomada inteligente MQTT: publique
offno topic de comando da tomada após um tempo limite. - Máquina de lavar terminou. A potência caindo de centenas de watts para perto de zero e ficando assim por alguns minutos é um sinal confiável de "ciclo concluído" para uma notificação no celular.
Mantenha a lógica em um único subscriber, em vez de espalhá-la pelos dispositivos, para poder mudar os limites sem regravar nada.
Checklist de Solução de Problemas
| Problema | Causa | Solução |
|---|---|---|
| Totais diários 1000 vezes maiores | Wh do Shelly tratado como kWh | Divida aenergy.total por 1000 |
| Sem dados do Tasmota por minutos | TelePeriod longo demais |
Defina TelePeriod 60 ou menos (mínimo 10) |
| Tomadas derrubam umas às outras | Client IDs MQTT duplicados | MqttClient único por tomada |
| Valores diários negativos | Zeramento de contador não tratado | Ignore diferenças negativas, como acima |
| Leituras de potência estranhas | Tomada não calibrada | Calibre com PowerSet, VoltageSet, CurrentSet no Tasmota |
Migrando para um Broker Privado
O servidor MQTT público é perfeito para este experimento, mas dados de energia revelam quando você está em casa, e qualquer pessoa que adivinhe seu prefixo também pode acionar suas tomadas. Antes de deixar a instalação rodando, migre para um broker MQTT na nuvem com credenciais e TLS. Com o ConnectMQ, crie um broker no portal e dê a cada tomada seu próprio usuário, senha e client ID. No Tasmota isso significa um build com TLS e MqttPort 8883; no Shelly, ative o SSL com o pacote de CAs embutido. No registrador, acrescente:
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set()
client.connect("broker.connectmq.com", 8883, keepalive=60)
As 25 conexões do plano Serverless gratuito bastam para uma dúzia de tomadas, o registrador e um dashboard. Um broker MQTT gerenciado também significa que o broker fica acessível pelo celular sem abrir portas no roteador. O guia de automação com IoT mostra como os dados das tomadas também podem disparar automações.
Comece a Monitorar suas Tomadas com o ConnectMQ
O ConnectMQ oferece às suas tomadas inteligentes, registradores e dashboards um broker privado protegido por TLS, com explorador de topics ao vivo e regras de alerta por limite, por exemplo para avisar quando a tomada do freezer informar zero watt por tempo demais. Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito.
Perguntas frequentes
Qualquer tomada inteligente pode enviar dados via MQTT?
Não. Somente tomadas com MQTT no firmware, como dispositivos Tasmota, Shelly Gen2/Gen3 ou ESPHome, podem publicar em um broker escolhido por você. Tomadas que funcionam só pela nuvem precisam de uma integração do fabricante.
Qual é a precisão das leituras de energia de uma tomada inteligente?
Normalmente é boa o suficiente para comparar aparelhos e identificar desperdícios, mas elas não são medidores com precisão de faturamento. Calibrar com uma carga resistiva conhecida melhora bastante a precisão em tomadas Tasmota.
Por que usar o total de energia em vez do valor de potência?
A tomada integra a energia continuamente, enquanto a potência só é amostrada quando uma mensagem é enviada. As diferenças entre os totais acumulados capturam cargas curtas que as amostras de potência deixam passar.
Com que frequência uma tomada inteligente deve publicar?
A cada 30 a 60 segundos é um bom equilíbrio para histórico e dashboards. Intervalos menores aumentam o tráfego sem melhorar os totais diários, porque estes vêm do contador de energia.



