Skip to main content

Arvist MQTT Integration Guide

This document explains how third-party integrators can subscribe to Arvist incident notifications over MQTT and then connect those events to an IoT device of their choosing (e.g., a siren, light, or actuator).


1. Overview

  • Broker: Arvist provides an MQTT broker (Eclipse Mosquitto) running in Docker.

  • Publishing Pattern: Whenever an incident is created, Arvist publishes a message to arvist/incident/{module_name}.

    Example: "arvist/incident/Person Detection After Hours"

Your Role as Integrator:

  • Deploy a service (container) that subscribes to the relevant arvist/incident/* topics.
  • Translate those incident messages into commands for your IoT device (MQTT, HTTP, Modbus, GPIO, etc.).
  • Ensure your service can communicate with both the broker and your IoT device.

2. Connecting to the MQTT Broker

Docker Compose Example

In your docker-compose.yml:

version: '3.9'
services:
mqtt:
container_name: arvist-mqtt
image: eclipse-mosquitto:latest
ports:
- '8883:8883' # TLS-secured MQTT for LAN devices
volumes:
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf:ro
- ./data:/mosquitto/data
- ./log:/mosquitto/log
networks:
- iot

your-subscriber-service:
build: ./subscriber
environment:
- MQTT_HOST=mqtt
- MQTT_USER=youruser
- MQTT_PASS=yourpass
depends_on:
- mosquitto
networks:
- iot

networks:
iot:
driver: bridge

3. Subscribing to Incident Topics

Python Example Subscriber

import os
import json
import paho.mqtt.client as mqtt

BROKER_HOST = MQTT_HOST
BROKER_PORT = 8883 # use 1883 if plaintext
MQTT_USER = os.getenv("MQTT_USER", "youruser")
MQTT_PASS = os.getenv("MQTT_PASS", "yourpass")

# Callback when the client connects to the broker
def on_connect(client, userdata, flags, rc, properties=None):
if rc == 0:
print("✅ Connected to MQTT broker")
client.subscribe("arvist/incident/#", qos=1)
else:
print(f"❌ Failed to connect, return code {rc}")

# Callback when a message is received
def on_message(client, userdata, msg):
try:
payload = json.loads(msg.payload.decode("utf-8"))
print(f"📥 Received incident on {msg.topic}: {payload}")

# TODO: Send command to your IoT device
# Example: If the device is also MQTT-based, publish a command:
# cmd = {"action": "on", "durationSec": 10}
# client.publish("devices/siren-01/cmd", json.dumps(cmd), qos=1, retain=False)

except Exception as e:
print(f"⚠️ Error parsing message: {e}")

def main():
client = mqtt.Client(client_id="incident-subscriber", protocol=mqtt.MQTTv5)
client.username_pw_set(MQTT_USER, MQTT_PASS)

# Enable TLS if using mqtts://
client.tls_set() # You can provide cert paths if not using system CAs

client.on_connect = on_connect
client.on_message = on_message

print(f"Connecting to {BROKER_HOST}:{BROKER_PORT} ...")
client.connect(BROKER_HOST, BROKER_PORT, keepalive=60)

client.loop_forever()

if __name__ == "__main__":
main()

4. Payload Format

Incident Message will be JSON-encoded. A typical payload might look like:

{
"data": {
"box": "<box_value>",
"label": "<formattedLabel>",
"confidence": "<rounded_confidence_or_null>",
"camera": "<camera_value>",
"zone": {
"name": "<zone_name>",
"full_coordinates": "<zone_full_coordinates>"
},
"name": "<module_name>",
"report_type": "<module_report_type>",
"severity": "<module_severity>",
"notifications": "<notifications_array_or_object>",
"explanatory_elements": {}
}
}

Notes on mapping:

  • confidence: Should be a number rounded to two decimals (e.g., 83.42), or null.
  • zone: If no zone is present, set this key to null.
  • explanatory_elements: Usually contains some post-processing metadata. Defaults to {} if nothing is provided.

5. Connecting to Your IoT Device

You are responsible for adapting the incident payload into your device's expected command format. Examples:

  • If the IoT device is also an MQTT client
    • Configure it to connect to the same broker (mqtt://<host>:8883).
    • Make it subscribe to a control topic such as devices/siren-01/cmd.
    • Have your subscriber service publish commands to that topic.
  • If the IoT device uss another protocol (HTTP, serial, GPIO, etc.)
    • Extend your subscriber service to make the appropriate API call or hardware control

6. Example Flow

  1. Arvist publishes:
topic: arvist/incident/forklift_safety
payload: { "data": { "id": "incident_12345", "severity": "high", ...} }
  1. Your subscriber receives the message.
  2. Your subscriber translates it into the IoT device protocol:
topic: devices/siren-01/cmd
payload: { "action": "on", "durationSec": 10 }
  1. The siren device acts accordingly.