Monitoramento MQTT - Khomp IED302
Escrito por Hitfy
Preparação do Proxy e Serviço de coleta MQTT
Foi desenvolvido em python um serviço que executa na maquina pxHitfy-OCI para escuta e criação de threads para receber tópicos MQTT e enviar para o host correto. Lembrando que esse processo só é necessário caso necessite reconstruir o serviço MQTT.
Código do serviço em python (/etc/zabbix/mqtt_zabbix_service.py)
#!/usr/bin/env python3
import threading
import subprocess
from flask import Flask, request, jsonify
from paho.mqtt.client import Client as MQTTClient
app = Flask(__name__)
# Chave: (broker, topic, zabbix_host), Valor: Thread
active_listeners = {}
lock = threading.Lock()
ZABBIX_SERVER = "localhost" # IP ou hostname fixo do servidor Zabbix
def send_to_zabbix(zabbix_host, key, value):
try:
subprocess.run([
"zabbix_sender", "-z", ZABBIX_SERVER,
"-s", zabbix_host, "-k", key, "-o", value
], check=True)
print(f"[ZABBIX] {zabbix_host}: {key} = {value}")
except subprocess.CalledProcessError as e:
print(f"[ERRO] Falha ao enviar para Zabbix ({zabbix_host}): {e}")
def mqtt_listener(broker, topic, zabbix_host):
client = MQTTClient()
client.on_connect = lambda c, u, f, rc: c.subscribe(topic)
client.on_message = lambda c, u, msg: send_to_zabbix(
zabbix_host,
f"mqtt.{topic.replace('/', '_')}",
msg.payload.decode()
)
try:
client.connect(broker, 1883, 60)
client.loop_forever()
except Exception as e:
print(f"[ERRO] Conexão com {broker} falhou: {e}")
@app.route("/listen", methods=["POST"])
def listen():
data = request.get_json()
broker = data.get("broker")
topic = data.get("topic")
zabbix_host = data.get("zabbix_host")
if not broker or not topic or not zabbix_host:
return jsonify({"error": "Parâmetros 'broker', 'topic' e 'zabbix_host' são obrigatórios."}), 400
key = (broker, topic, zabbix_host)
with lock:
if key in active_listeners:
return jsonify({"status": "Escutando", "broker": broker, "topic": topic, "zabbix_host": zabbix_host})
thread = threading.Thread(target=mqtt_listener, args=(broker, topic, zabbix_host), daemon=True)
active_listeners[key] = thread
thread.start()
return jsonify({"status": "Iniciado", "broker": broker, "topic": topic, "zabbix_host": zabbix_host})
@app.route("/status", methods=["GET"])
def status():
with lock:
return jsonify({
"ativos": [f"{b}::{t} -> {h}" for (b, t, h) in active_listeners.keys()]
})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Preparar libs para ativar o serviço do linux
Instalar as libs Flask, paho-mqtt com o comando abaixo
pip3 install flask paho-mqtt
Criando serviço no linux
Crie o arquivo vim /etc/systemd/system/mqtt_zabbix.service e coloque o código abaixo
[Unit] Description=Serviço MQTT para envio ao Zabbix After=network.target [Service] Type=simple ExecStart=/usr/bin/python3 /etc/zabbix/mqtt_zabbix_service.py WorkingDirectory=/etc/zabbix Restart=always RestartSec=5 User=nobody Environment=PYTHONUNBUFFERED=1 [Install] WantedBy=multi-user.target
Depois execute os comandos abaixo para criar o serviço, ativar e verificar o status
systemctl daemon-reexec systemctl daemon-reload systemctl enable --now mqtt_zabbix.service systemctl status mqtt_zabbix.service
Verificar logs em tempo real do serviço
journalctl -u mqtt_zabbix.service -f
Comandos para verificar e ativar novos processo de escuta MQTT por tópico
Executar o comando abaixo para verificar o status e listar todos os tópicos que estão sendo ouvidos.
curl <http://localhost:5000/status>
Executar na maquina que esta instalado o serviço e exibira o resultado abaixo:
{"ativos":["146.235.57.205::remota/211500/measures -> Broker_MQTT_DevIOT","{$BROKER}::{$TOPIC} -> Broker_MQTT_DevIOT"]}
Comando para ativar uma nova escuta de tópico
curl -X POST <http://localhost:5000/listen> -H "Content-Type: application/json" -d '{"broker": "<IP do Broker MQTT>", "topic": "<Tópico do MQTT>", "zabbix_host": "<Nome do Host>"}'
Executar na maquina que esta instalado o serviço e exibira o resultado abaixo:
{"broker":"146.235.57.205","status":"Escutando","topic":"remota/211500/measures","zabbix_host":"Broker_MQTT_DevIOT"}
OBS.: O serviço MQTT já bloqueia a ativação do mesmo tópico.
Ativação do monitoramento IED302 para coleta de Corrente e Tensão
É necessário criar um host no zabbix, depois adicionar a template (Template_Khomp_IED302_Padrao) e ter as informações do Broker e Tópico:
- Broker, é o IP que esta instalado o serviço que coleta e envia para o Zabbix. Hoje é o IP 146.235.57.205
- Tópico, é o caminho que vamos pegar as informações e coletar no zabbix, o tópico é composto por remota/<Numero de serie>/measures. Exemplo: remota/211500/measures
Depois de adicionar o host, é necessário ajustar a macro desse host com as informações acima.