A rotulagem de séries temporais de sensores costuma ser a parte mais difícil do machine learning supervisionado em IoT, não porque as ferramentas sejam complicadas, mas porque o ground truth está espalhado entre a memória dos operadores, registros em papel e sistemas de manutenção. Este guia mostra como capturar eventos e rótulos de operadores via MQTT no momento em que acontecem, como projetar um esquema de rótulos que resista ao uso real e como transformar esses eventos em janelas rotuladas unidas à sua telemetria.
Por que os rótulos são o gargalo
Dados de sensores são baratos de coletar. Um gateway publicando a cada poucos segundos gera milhões de pontos em poucas semanas. Mas um modelo que deve reconhecer um filtro entupido, uma quebra de ferramenta ou um defeito de qualidade precisa de exemplos em que alguém disse "isso aconteceu, aqui, neste horário". Esses exemplos são raros, e as fontes habituais não são confiáveis:
- Ordens de serviço de manutenção registram quando o reparo foi feito, não quando a falha começou, e muitas vezes contêm texto livre como "bomba consertada".
- Livros de turno são preenchidos no fim do turno, com horários aproximados.
- Históricos de alarmes registram cruzamentos de limites, o que não é o mesmo que falhas reais.
- A rotulagem retrospectiva feita por engenheiros olhando gráficos é lenta e inconsistente entre pessoas.
A solução mais eficaz é capturar os rótulos como eventos estruturados, no momento em que acontecem, na mesma camada de mensageria da telemetria. Se o operador toca em "travamento resolvido" em um tablet e isso vira uma mensagem MQTT com timestamp e caminho do ativo, o rótulo já está alinhado com os dados dos sensores.
Tipos de rótulos para dados de sensores
| Tipo de rótulo | Formato | Exemplo | Uso típico |
|---|---|---|---|
| Evento pontual | Um único timestamp | "Ferramenta trocada", "Amostra coletada" | Segmentar vidas úteis, marcar intervenções |
| Intervalo | Início e fim | "Setup das 08:10 às 08:45" | Excluir períodos sem produção, classificação de estados |
| Classe de janela | Janela fixa com uma classe | "Esta janela de 10 minutos: cavitação" | Treinamento de classificadores |
| Resultado | Resultado vinculado a um período | "Lote 4411 reprovado na inspeção de qualidade" | Previsão de qualidade |
| Falha | Timestamp mais modo de falha | "Falha de rolamento, pista externa" | Modelos de falha e de RUL |
A maioria dos projetos precisa de vários tipos ao mesmo tempo. Intervalos de estado da máquina (operando, setup, limpeza, falha) são especialmente valiosos, porque permitem excluir períodos que, de outra forma, confundiriam o modelo.
Projetando um esquema de rótulos
Antes de construir qualquer interface, chegue a um acordo sobre o esquema. Um esquema prático inclui:
- Um vocabulário fixo de códigos de rótulo, por exemplo
STATE_SETUP,STATE_CLEANING,FAULT_JAM,FAULT_LEAK,MAINT_BEARING_REPLACED. Texto livre vai para um campo de comentário separado. - Um tipo de evento:
start,endoupoint. Os intervalos são montados a partir de pares de início e fim. - O caminho do ativo, usando a mesma hierarquia da telemetria, para que a junção seja trivial.
- Timestamp de origem e timestamp de registro. O operador pode registrar "o travamento começou há 5 minutos"; guarde tanto quando aconteceu quanto quando foi registrado.
- Quem rotulou (função ou crachá, não necessariamente um nome) e a confiança, quando relevante.
- Um ID de evento único, para que correções possam referenciar e substituir um rótulo anterior.
- Uma versão do esquema, para lidar com mudanças sem quebrar dados antigos.
Mantenha o vocabulário curto. Dez códigos bem definidos e usados de forma consistente valem mais do que cem códigos que cada operador interpreta de um jeito. O guia de modelagem de dados IIoT cobre o lado do caminho do ativo nesse projeto.
Capturando rótulos via MQTT
Publique os rótulos em um subtopic dedicado de cada ativo, ao lado da sua telemetria:
connectmq/plant1/line2/filler1/telemetry/vibration
connectmq/plant1/line2/filler1/labels
Os rótulos devem usar QoS 1 para não serem perdidos silenciosamente e não devem ser retidos, porque cada rótulo é um evento, e não um estado atual. Se você também quiser que o estado atual da máquina fique visível nos dashboards, publique-o separadamente como um topic state retido.
Aqui está um pequeno cliente de rotulagem em Python que uma estação de operador ou um script de teste pode usar. Ele publica eventos de rótulo estruturados no servidor MQTT público, feito para testes; em operações reais, use as credenciais do seu próprio broker.
# label_client.py
import json
import sys
import time
import uuid
import paho.mqtt.client as mqtt
BROKER = "broker.connectmq.com"
ASSET = "connectmq/demo/lbl-4c2e/line2/filler1"
CODES = {"STATE_SETUP", "STATE_CLEANING", "FAULT_JAM", "FAULT_LEAK", "MAINT_BEARING_REPLACED"}
def publish_label(client, code, event, minutes_ago=0, comment="", operator="op-station-2"):
if code not in CODES:
raise ValueError(f"unknown label code {code}")
now = int(time.time() * 1000)
label = {
"schema": 1,
"id": str(uuid.uuid4()),
"code": code,
"event": event, # start | end | point
"ts": now - int(minutes_ago * 60000),
"entered": now,
"by": operator,
"comment": comment,
}
info = client.publish(f"{ASSET}/labels", json.dumps(label), qos=1)
info.wait_for_publish()
print("sent", label["code"], label["event"])
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="labeler-" + uuid.uuid4().hex[:8])
client.connect(BROKER, 1883, keepalive=60)
client.loop_start()
# Usage: python label_client.py FAULT_JAM start 3 "bottle stuck at infeed"
code, event = sys.argv[1], sys.argv[2]
minutes = float(sys.argv[3]) if len(sys.argv) > 3 else 0
comment = sys.argv[4] if len(sys.argv) > 4 else ""
publish_label(client, code, event, minutes, comment)
client.loop_stop()
client.disconnect()
Na prática, a mesma mensagem pode vir de um botão em um dashboard Node-RED, de um app de tablet usando MQTT sobre WebSocket, de um leitor de código de barras em uma estação de qualidade ou de um CLP que publica as próprias mudanças de estado. Rótulos gerados por máquinas, como códigos de estado do CLP, costumam ser a fonte mais confiável para intervalos de estado; os operadores então acrescentam o que a máquina não tem como saber, como as causas raiz.
Transformando eventos em dados de treinamento
Depois que rótulos e telemetria são armazenados por um assinante historiador, o próximo passo é converter os eventos de início e fim em intervalos e atribuí-los a janelas de telemetria. O script a seguir faz isso com pandas.
# build_dataset.py
import pandas as pd
# labels.csv: id,code,event,ts telemetry.csv: ts,vib_rms,current
labels = pd.read_csv("labels.csv", parse_dates=["ts"]).sort_values("ts")
tele = pd.read_csv("telemetry.csv", parse_dates=["ts"]).sort_values("ts")
# 1. Pair start/end events per code into intervals
intervals = []
open_events = {}
for row in labels.itertuples():
if row.event == "start":
open_events[row.code] = row.ts
elif row.event == "end" and row.code in open_events:
intervals.append((row.code, open_events.pop(row.code), row.ts))
intervals = pd.DataFrame(intervals, columns=["code", "start", "end"])
# 2. Build fixed windows of telemetry features
win = (tele.set_index("ts").resample("1min")
.agg({"vib_rms": ["mean", "std", "max"], "current": ["mean"]}))
win.columns = ["_".join(c) for c in win.columns]
win = win.dropna().reset_index()
win["window_end"] = win["ts"] + pd.Timedelta(minutes=1)
# 3. Assign a label when a window overlaps an interval by more than half
def label_for(w):
for iv in intervals.itertuples():
overlap = (min(w.window_end, iv.end) - max(w.ts, iv.start)).total_seconds()
if overlap > 30:
return iv.code
return "NORMAL"
win["label"] = [label_for(w) for w in win.itertuples()]
# 4. Drop ambiguous windows near interval boundaries
for iv in intervals.itertuples():
near = ((win["ts"] - iv.start).abs() < pd.Timedelta(minutes=2)) | \
((win["ts"] - iv.end).abs() < pd.Timedelta(minutes=2))
win.loc[near, "label"] = "EXCLUDE"
dataset = win[win["label"] != "EXCLUDE"]
print(dataset["label"].value_counts())
dataset.to_csv("training_windows.csv", index=False)
Dois detalhes importam aqui. As janelas de fronteira são excluídas porque o início exato de um travamento ou vazamento é incerto, e treinar com essas janelas ensina ruído ao modelo. E eventos de início sem par não são fechados silenciosamente; revise-os, porque um "fim" esquecido pode transformar horas de operação normal em um rótulo de falha.
Verificações de qualidade dos rótulos
Use esta checklist antes de treinar:
- Conte os rótulos por código e por ativo; contagens muito desiguais costumam revelar um turno ou uma unidade que simplesmente não está rotulando.
- Encontre inícios e fins sem par e intervalos sobrepostos de códigos incompatíveis.
- Compare o horário de registro com o horário do evento; grandes diferenças indicam palpites retrospectivos.
- Plote a telemetria em torno de uma amostra aleatória de rótulos e confira se o sinal realmente muda.
- Peça a uma segunda pessoa que revise uma amostra e meça a concordância.
- Versione o dataset com a versão do esquema de rótulos e a consulta que o gerou.
Mantendo os rótulos fluindo
A rotulagem não é um projeto pontual. Faça dela parte do trabalho normal: o botão que reconhece um alarme de travamento também pode publicar o rótulo, e o formulário de encerramento da manutenção pode publicar o modo de falha. Devolva os alertas do modelo como candidatos a rótulo que os operadores confirmam ou rejeitam; essa confirmação é, por si só, um rótulo valioso. O artigo sobre MLOps para IoT descreve como esses ciclos de feedback impulsionam o retreinamento, e machine learning para manutenção preditiva mostra como os rótulos de falha se tornam alvos de treinamento. Para modelos de degradação, eventos completos de ciclo de vida são essenciais, como explicado em previsão de vida útil remanescente.
Rótulos e telemetria no ConnectMQ
Usar um único broker para telemetria e rótulos mantém tudo alinhado por caminho de ativo e por tempo. O ConnectMQ oferece um broker MQTT gerenciado com MQTT sobre WebSocket seguro na porta 8084, para que uma página de rotulagem no navegador publique diretamente, e o explorador de topics ao vivo permite verificar as mensagens de rótulo à medida que os operadores as enviam. O armazenamento e a montagem do dataset rodam nos seus próprios assinantes, como um gravador de historiador e o script acima. Para o panorama completo de IA com dispositivos conectados, veja o guia de IA e IoT.
Comece a usar o ConnectMQ
Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito. Use YOUR_USERNAME, YOUR_PASSWORD e YOUR_CLIENT_ID gerados no seu gateway e nos clientes de rotulagem e comece hoje mesmo a coletar rótulos ao lado da sua telemetria; cada semana de rótulos consistentes torna o seu próximo modelo melhor.
Perguntas frequentes
Qual é a melhor forma de fazer a rotulagem de séries temporais de sensores?
Capture os rótulos como eventos estruturados no momento em que acontecem, com vocabulário fixo, caminho do ativo e timestamps, na mesma camada de mensageria da telemetria. A rotulagem retrospectiva a partir de gráficos é mais lenta e menos consistente.
As mensagens de rótulo devem ser retidas no MQTT?
Não. Rótulos são eventos, então publique-os com QoS 1 e sem a flag retain, e armazene-os com um assinante. Publique o estado atual da máquina separadamente como um topic retido, se os dashboards precisarem dele.
Como lidar com horários de início de rótulo incertos?
Registre tanto o horário estimado do evento quanto o horário de registro e exclua do treinamento as janelas próximas das fronteiras dos intervalos. Isso remove os exemplos mais ambíguos sem descartar o rótulo.
As máquinas podem gerar rótulos automaticamente?
Sim. Códigos de estado do CLP, eventos de alarme e resultados de estações de qualidade são bons rótulos automáticos. Os operadores então acrescentam informações que a máquina não tem como saber, como a causa raiz ou a confirmação de um alerta do modelo.



