WebSocket
Monitoreo y filtrado de eventos de WebSocket
Suscríbete a eventos de WebSocket en tiempo real de Rhombus — filtra y procesa alertas de políticas, cambios de estado de dispositivos, detección de movimiento y eventos de control de acceso.
En esta página
- Tópico de eventos
- Estructura de la carga útil del evento
- Campos principales
- Tipos de cambio
- Tipos de entidad
- Inspección de alertas de política
- Filtrado de eventos
- Por tipo de entidad
- Por tipo de cambio
- Por dispositivo
- Enriquecimiento de eventos con datos de la API REST
- Obtener el nombre de la cámara a partir del UUID del dispositivo
- Obtener detalles de la alerta
- Formatos de salida
- Visualización de alerta con formato
- Salida JSON sin procesar
- Patrones de integración
- Relé de webhook
- Notificaciones de Slack
- Registro en base de datos
Esta página se tradujo automáticamente. Si encuentras errores o tienes sugerencias, escríbenos.
El flujo de eventos de WebSocket de Rhombus entrega notificaciones en tiempo real sobre la actividad de tu organización que puede ver el rol de tu credencial. Esta guía cubre la estructura de los eventos, los tipos de entidad disponibles y los patrones para filtrar y procesar eventos.
Tópico de eventos
Todos los eventos de la organización se publican en un único tópico:
/topic/change/{orgUuid}Los cambios en muchos tipos de objetos de tu organización emiten un evento en este tópico, desde nuevas alertas de políticas hasta el estado de las cámaras y los componentes de puertas; la referencia de eventos los enumera. Una conexión recibe los eventos que cubre el rol de su credencial, incluidas las alertas de políticas; los eventos de otros dispositivos y ubicaciones se descartan sin error (consulta Qué recibe una conexión).
Estructura de la carga útil del evento
Cada trama MESSAGE lleva un cuerpo JSON. Una nueva alerta de política se ve así (abreviada):
{
"entity": "POLICY_ALERT",
"type": "CREATE",
"update": {
"uuid": "Xq3vT1bKQ2m8c9Zr0aLwYg",
"type": "POLICY_ALERT_V2",
"deviceUuid": "ItkwWv1qT7Wy8-pY8KDesw",
"locationUuid": "Rk2pQ7yLT0qX4b1nVt8sJw",
"timestampMs": 1791367200000,
"policyAlertTriggers": ["MOTION_HUMAN"],
"textDescription": "Human detected at Front Lobby"
}
}Campos principales
| Campo | Tipo | Descripción |
|---|---|---|
entity | string | El tipo de objeto que cambió |
type | string | CREATE, UPDATE, DELETE o REFRESH |
entityUuid | string | El objeto que cambió. No aparece en una nueva alerta de política: usa update.uuid |
update | object | El nuevo estado del objeto o los campos que cambiaron; falta en muchos mensajes. Su forma depende de entity |
deviceUuid | string | El dispositivo involucrado, en los pocos mensajes que lo incluyen |
subLocationsHierarchyKey | string | La ruta de sububicaciones, en algunos mensajes de monitoreo de alarmas |
La organización no está en el cuerpo: está en el destino y en el encabezado ORG_UUID de la trama. La referencia de eventos documenta cada campo, incluida la alerta de política completa.
Tipos de cambio
| Tipo | Significado | Ejemplo |
|---|---|---|
CREATE | Algo nuevo, enviado con el objeto completo | Una nueva alerta de política |
UPDATE | Un objeto existente cambió | Cambió el estado de una cámara |
REFRESH | El objeto cambió; vuelve a leerlo si necesitas su estado | Un sensor de puerta informó un cambio |
DELETE | El objeto se eliminó, sin update | Una alerta se eliminó o se archivó |
Tipos de entidad
El campo entity indica qué tipo de objeto cambió. Los que más usan las integraciones:
| Entidad | Se envía cuando |
|---|---|
POLICY_ALERT | Se crea una alerta (CREATE, con la alerta), se vincula a un caso de amenaza (UPDATE) o se elimina (DELETE) |
CAMERA_STATE, AUDIO_STATE | Cambia el estado de una cámara o de un gateway de audio (UPDATE, con el nuevo estado) |
DOOR_STATE, CLIMATE_STATE, OCCUPANCY_STATE, PROXIMITY_STATE | Un sensor informa un cambio (REFRESH, con los campos que cambiaron) |
CAMERA, DOOR_SENSOR, CLIMATE_SENSOR, PROXIMITY_SENSOR | Se agrega un dispositivo (REFRESH) |
ACCESS_CONTROLLED_DOOR, COMPONENT_*_SHADOW | Cambia una puerta con control de acceso o uno de sus componentes |
POLICY, SCHEDULE | Se modifica una política o un horario |
SAVED_CLIPS | Cambia un clip guardado (REFRESH) |
La referencia de eventos enumera todos los tipos de entidad. Todos llegan al mismo destino y no hay filtro del lado del servidor, así que filtra por entity en tu controlador.
Inspección de alertas de política
Una alerta nueva llega como CREATE con la alerta completa en update: su uuid, la cámara (deviceUuid), timestampMs, los policyAlertTriggers que se activaron y más. Se envía una sola vez, cuando la alerta se guarda por primera vez, así que los campos que Rhombus completa después (como las ubicaciones de clips y finalized) pueden tener todavía sus valores iniciales; obtén la alerta con la API REST cuando necesites su estado final.
def inspect_alert(payload):
if payload.get("entity") != "POLICY_ALERT" or payload.get("type") != "CREATE":
return
alert = payload["update"]
print(alert["uuid"], alert.get("deviceUuid"), alert["timestampMs"], alert.get("policyAlertTriggers"))Filtrado de eventos
Por tipo de entidad
def handle_message(payload):
entity = payload.get("entity")
if entity == "POLICY_ALERT":
handle_alert(payload)
elif entity == "CAMERA_STATE":
handle_camera_state(payload)
else:
pass # ignora los tipos que no usasPor tipo de cambio
def handle_alert(payload):
change_type = payload.get("type")
if change_type == "CREATE":
send_notification(payload["update"]) # una alerta nueva
elif change_type == "UPDATE":
refresh_alert(payload["entityUuid"]) # vinculada a un caso de amenaza
elif change_type == "DELETE":
remove_alert(payload["entityUuid"]) # eliminada o archivadaNo dependas de los mensajes DELETE para seguir cada alerta eliminada: están limitados a uno por organización cada 10 minutos.
Por dispositivo
Dónde está el dispositivo depende de la entidad: una alerta de política lo indica en update.deviceUuid, y un mensaje de estado de dispositivo trata del dispositivo de entityUuid.
WATCHED_DEVICES = {"ItkwWv1qT7Wy8-pY8KDesw"}
def device_of(payload):
if payload.get("entity") == "POLICY_ALERT":
return (payload.get("update") or {}).get("deviceUuid")
return payload.get("deviceUuid") or payload.get("entityUuid")
def handle_message(payload):
if device_of(payload) in WATCHED_DEVICES:
process_event(payload)Enriquecimiento de eventos con datos de la API REST
Los eventos de WebSocket contienen datos mínimos por eficiencia. Usa la API REST para obtener detalles adicionales cuando sea necesario:
Obtener el nombre de la cámara a partir del UUID del dispositivo
import requests
def get_camera_name(api_token, device_uuid):
"""Fetch camera name for display purposes."""
response = requests.post(
"https://api2.rhombussystems.com/api/camera/getMinimalCameraStateList",
headers={
"x-auth-scheme": "api-token",
"x-auth-apikey": api_token,
"Content-Type": "application/json"
},
json={}
)
cameras = response.json().get("cameraStates", [])
for camera in cameras:
if camera.get("uuid") == device_uuid:
return camera.get("name", "Unknown Camera")
return "Unknown Camera"Obtener detalles de la alerta
def get_alert_details(api_token, alert_uuid):
"""Fetch full policy-alert details from the REST API."""
response = requests.post(
"https://api2.rhombussystems.com/api/event/getPolicyAlertDetails",
headers={
"x-auth-scheme": "api-token",
"x-auth-apikey": api_token,
"Content-Type": "application/json"
},
json={"policyAlertUuid": alert_uuid}
)
return response.json().get("policyAlert")Almacena en caché los nombres de las cámaras localmente para evitar llamadas excesivas a la API REST. Los nombres de las cámaras cambian con poca frecuencia, así que una caché con un TTL de 5 minutos funciona bien.
Formatos de salida
Visualización de alerta con formato
def display_alert(payload, camera_name=""):
entity = payload.get("entity", "UNKNOWN")
change = payload.get("type", "UNKNOWN")
update = payload.get("update", {})
print(f"{change} {entity} camera={camera_name}")
print(f" device={payload.get('deviceUuid', 'N/A')}")
print(f" uuid={payload.get('entityUuid', 'N/A')}")
# `update` is entity-specific; print its keys to discover available detail.
if update:
print(f" update keys={list(update.keys())}")
print()Salida JSON sin procesar
Para canalizar a otras herramientas o sistemas de registro:
import json
def output_json(payload):
print(json.dumps(payload, indent=2))Patrones de integración
Relé de webhook
Reenvía los eventos de Rhombus a tu propio endpoint de webhook:
import requests
WEBHOOK_URL = "https://your-server.com/webhooks/rhombus"
def relay_to_webhook(payload):
try:
requests.post(WEBHOOK_URL, json=payload, timeout=5)
except requests.RequestException as e:
print(f"Webhook relay failed: {e}")Notificaciones de Slack
Envía alertas de alta prioridad a un canal de Slack:
def send_slack_alert(payload, webhook_url):
entity = payload.get("entity", "UNKNOWN")
change = payload.get("type", "UNKNOWN")
message = {
"text": f":rotating_light: *Security Alert*\n"
f"{change} {entity}\n"
f"Entity: {payload.get('entityUuid', 'N/A')} "
f"Device: {payload.get('deviceUuid', 'N/A')}"
}
try:
requests.post(webhook_url, json=message, timeout=5)
except requests.RequestException as e:
print(f"Slack notification failed: {e}")Registro en base de datos
Persiste los eventos para análisis histórico:
import sqlite3
import json
def log_event(db_path, payload):
conn = sqlite3.connect(db_path)
conn.execute("""
INSERT INTO events (entity, entity_uuid, change_type, device_uuid, payload)
VALUES (?, ?, ?, ?, ?)
""", (
payload.get("entity"),
payload.get("entityUuid"),
payload.get("type"),
payload.get("deviceUuid"),
json.dumps(payload)
))
conn.commit()
conn.close()